Kubernetes 인 액션 1장 쿠버네티스 소개
Devops/Kubernetes

Kubernetes 인 액션 1장 쿠버네티스 소개

뉴비뉴 2023. 3. 21.

1장, 쿠버네티스 소개

  • 애플리케이션을 격리하고 컨테이너를 사용해 실행 환경 차이 줄이기
  • 쿠버네티스에서 사용되는 컨테이너와 도커의 이해
  • 쿠버네티스로 개발자와 시스템 관리자의 작업 간소화하기

몇 년 전만 하더라도 대부분의 소프트웨어 애플리케이션은 하나의 프로세스 또는 몇 개의 서버에 분산된 프로세스로 실행되는 거대한 모놀리스 였다.

  • 릴리스 주기가 느리고 비교적 업데이트가 자주 되지 않는다.
  • 시스템을 원활하게 구성, 관리, 유지하는 일이 점점 어려워졌다.
  • 각 구성 요소를 배치할 위치를 파악하는 것은 훨씬 어렵다.

위와 같은 이유로 인하여 쿠버네티스가 등장하게 되었다.

쿠버네티스는 하드웨어 인프라를 추상화하고 데이터 센터 전체를 하나의 거대한 컴퓨팅 리소스로 제공한다.

1.1.1 모놀리스 애플리케이션에서 마이크로서비스로 전환

  • 모놀리스란 모놀리스 애플리케이션은 모든 것이 서로 강하게 결합돼 있고, 전체가 하나의 운영체제 프로세스로 실행되기 때문에 하나의 개체로 개발, 배포, 관리 돼야 한다.
    • 거대한 모놀리식 애플리케이션에서는 한 줄만 수정하더라도 해당 변경을 릴리스하기 위해 전체 애플리케이션을 배포해야 한다.
    • 경계가 불분명해지고 상호의존성의 제약이 커지면서 전체 시스템의 복잡성이 증가하고 품질이 저하된다.
  • 모놀리스 특징
    • 시스템의 증가하는 부하를 처리하려고 서버 구성 요소를 추가해 서버를 수직 확장 하거나 서버를 추가하고 애플리케이션의 복사본을 실행해 전체 시스템을 수평 확장 해야 한다.
    • LET ME) 간단한 예시로 AWS EC2를 Auto Scaling 사용하여 EC2 를 수평 확장하는 경우, AWS EC2의 사양을 올려 g4dn → g16dn 사양을 증설하는 수직 확장
    • 위의 예시처럼 수직 확장의 경우 비용이 많이 들고 확장에 한계가 있다. 반면 수평 확장의 경우 저렴하지만 애플리케이션의 코드의 큰 변경이 필요할 수 있으며 항상 가능한 것도 아니다.

마이크로서비스로 애플리케이션 분할

  1. 마이크로서비스는 일반적으로 RESTful API를 제공하는 HTTP 와 같은 동기 프로토콜과 AMQP 와 같은 비동기 프로토콜로 통신한다.
  2. 각 마이크로서비스는 대체로 정적인 외부 API를 제공하는 독립형 프로세스이기 때문에 개별적으로 개발, 배포 할 수 있다.
  3. LET ME) 마이크로서비스는 외부와 통신하는 서버에서 보안을 강화한다. 그 서버는 베스천서버로 알고 있다.

마이크로서비스 확장

  1. 마이크로서비스는 확장은 서비스별로 수행된다.
  2. LET ME) 즉, 5개의 마이크로서비스가 존재한다. 마이크로서비스 3번만 통신이 모이고 있다. 그럼 3번만 확장하면 된다.

마이크로서비스 배포

언제나 그렇듯이 마이크로서비스도 단점이 있다.

  1. 구성 요소가 많아지면 배포 조합의 수뿐만 아니라 구성 요소 간의 상호 종속성 수가 훨씬 많아지므로 배포 관련 결정이 점점 어려워진다.
  2. 마이크로서비스는 여러 프로세스와 시스템에 분산돼 있기 때문에 실행 호출을 디버그하고 추적하기 어렵다. 다행히 이런 문제는 현재 Zipkin과 같은 분산 추적 시스템으로 해결한다. LET ME) Zipkin은 분산환경에서 로그 트레이싱을 제공해주는 오픈 소스입니다

1.1.2 애플리케이션에 일관된 환경 제공

  • 개발자와 운영 팀이 항상 해결해야 하는 큰 문제 중 하나는 애플리케이션을 실행하는 환경이 다르다는 것이다.
  • 개발과 프로덕션 환경 사이에 큰 차이가 있을 뿐만 아니라 각 프로덕션 머신 간에도 차이가 있다.
  • 또 하나의 피할 수 없는 사실은 프로덕션 머신의 환경이 시간이 지남에 따라 변한다는 것이다.
  • LET ME) 보통 개발환경은 개인 환경에 따라 결정된다. Window or Mac or Linux If you choose a Window but Production is Linux
  • 이런 차이는 하드웨어에서 운영체제, 각 시스템에서 사용 가능한 라이브러리에 이르기까지 다양하다.
  • 프로덕션 환경에서만 나타나는 문제를 줄이려면 애플리케이션 개발과 프로덕션이 정확히 동일한 환경에서 실행돼 운영체제, 라이브러리, 시스템 구성, 네트워킹 환경, 기타 모든 것이 동일한 환경을 만들 수 있다면 이상적일 것이다.

1.2.1 컨테이너 이해

애플리케이션이 더 작은 수의 커다란 구성 요소로만 이뤄진 경우 각 구성 요소에 전용 가상머신(VMware)을 제공하고 고유한 운영체제 인스턴스를 제공해 환경을 격리할 수 있다. 그러나 이런 구성 요소가 점점 작아지고 숫자가 많아지기 시작하면 하드웨어 리소스를 낭비하지 않으면서 비용을 줄이려면 각 구성 요소마다 가상머신을 제공할 수 없다. LET ME) 도커는 기존의 가상화 기술을 기반으로 만들어졌다. 가상화 이전의 시대에서는 하나의 서버에 하나의 애플리케이션만 구동시켰다고 한다. 이렇다 보니 하나의 서버에 남는 자원이 많았다. 이런 비효율성을 극복하기 위해 등장한 기술이 가상화 기술이다.

컨테이너와 가상머신 비교

컨테이너를 가상머신과 비교하면 컨테이너는 훨씬 더 가벼워서 동일한 하드웨어에서 더 많은 수의 소프트웨어 구성 요소를 실행할 수 있다. 가상머신은 구성 요소 프로세스 뿐만 아니라 시스템 프로세스를 실행해야 하기 때문에 추가 컴퓨팅 리소스가 필요하다. LET ME) 즉 도커 컨테이너 승리 가상머신은 구성 요소 프로세스뿐만 아니라 시스템 프로세스를 실행해야 하기 때문에 추가 컴퓨팅 리소스가 필요하다.

  • 컨테이너는 호스트 OS에서 실행되는 하나의 격리된 프로세스에 지나지 않으며, 애플리케이션이 소비하는 리소스만 소비하고 추가 프로세스의 오버헤드는 없다.
  • 가상머신의 오버헤드로 인해 각 애플리케이션 별로 하나의 VM을 전용으로 사용하기에는 리소스가 충분하지 않기 때문에 각 가상머신에 여러 애플리케이션을 그룹으로 배포하는 경우가 종종 있다.

  • 호스트에 가상머신 세 개를 실행하면 세 개의 완전히 분리된 운영체제가 실행되고 동일한 베어메탈 하드웨어 LET ME) ‘베어메탈(Bare Metal)’이란 용어는 원래 하드웨어 상에 어떤 소프트웨어도 설치되어 있지 않은 상태를 뜻합니다. 즉, 베어메탈 서버는 가상화를 위한 하이퍼바이저 OS 없이 물리 서버를 그대로 제공하는 것을 말합니다. 따라서 하드웨어에 대한 직접 제어 및 OS 설정까지 가능합니다. 를 공유하게 된다. LET ME) 아 그래서, 도커를 실행 할 때 기본적인 것들은 다 apt-get install and update 로 설치하고, WORKDIR 등등을 설정하는 구나!
  • 물리적 하드웨어 리소스를 각 가상머신 내부의 운영체제에서 사용할 수 있는 더 작은 리소스로 나누는 호스트 OS와 하이퍼바이저가 있다. LET ME) 하이퍼바이저 는 가상 머신(Virtual Machine, VM)을 생성하고 구동하는 소프트웨어입니다.
  • 해당 가상머신 내에서 실행되는 애플리케이션이 가상머신의 게스트 OS 커널 LET ME) “운영체제의 핵심부로 컴퓨터 자원들을 관리하는 역할”, 즉, 커널은 항상 컴퓨터 자원만 바라보고 있다. 을 수행합니다.에 대한 시스템 콜 LET ME) 운영 체제의 커널이 제공하는 서비스에 대해, 응용 프로그램의 요청에 따라 커널에 접근하기 위한 인터페이스이다. 을 수행하면, 커널은 하이퍼바이저로 호스트의 물리적 CPU에서 x86 명령을 수행한다.
  • 반면 컨테이너는 호스트 OS에서 실행되는 동일한 커널에서 시스템 콜을 수행한다.
  • CPU는 가상머신과 같은 방식으로 어떠한 종류의 가상화도 필요가 없다.
  • 가상머신의 주요 이점은 각 가상머신이 자체 리눅스 커널을 실행해 완전한 격리를 제공하는 데 반해 컨테이너는 모두 동일한 커널을 호출함으로 보안 위험이 발생할 수 있다는 것이다.
  • 하드웨어 리소스가 제한된 경우 격리하려는 프로세스가 적은 경우에만 가상머신을 사용할 수 있다.
  • 동일한 시스템에서 더 많은 수의 격리된 프로세스를 실행하려면 컨테이너의 오버헤드가 낮기 때문에 컨테이너를 선택하는 것이 좋다.
  • 각 가상머신은 자체 시스템 서비스를 실행하지만 컨테이너는 모두 동일한 OS에서 실행되므로 컨테이너는 시스템 서비스를 실행하지 않는다는 점을 기억하자.
  • 즉, 컨테이너를 실행하려면 가상머신처럼 부팅할 필요가 없다. 컨테이너에서 실행되는 프로세스는 즉시 시작된다.

리눅스 네임스페이스로 프로세스 격리

기본적으로 각 리눅스 시스템은 초기 구동 시 하나의 네임스페이스가 있다. 파일시스템, 프로세스 ID, 사용자 ID, 네트워크 인터페이스 등과 같은 모든 시스템 리소스는 하나의 네임스페이스에 속한다.

네임스페이스의 종류

  • 마운트(mnt)
  • 프로세스 ID(PID)
  • 네트워크(net)
  • 프로세스 간 통신(ipc)
  • 호스트와 도메인 이름(uts)
  • 사용자 ID(user)

각 네임스페이스는 특정 리소스 그룹을 격리하는 데 사용된다.

LET ME) 네임스페이스란 동일한 시스템에서 별개의 독립된 공간을 격리된 환경에서 운영하는 가상화 기술

1.2.2 도커 컨테이너 플랫폼 소개

도커 개념 이해

  • 도커는 애플리케이션을 패키징, 배포, 실행하기 위한 플랫폼 이다.
  • 이미지: 파일시스템과 이미지가 실행될 때 실행돼야 하는 실행파일 경로와 같은 메타데이터가 포함
  • 레지스트리: 도커 이미지를 저장하고 다른 사람이나 컴퓨터 간에 해당 이미지를 쉽게 공유할 수 있는 저장소 이다. LET ME) 이미지를 리지스트리로 docker pull and docker push
  • 컨테이너: 도커 기반 컨테이너 이미지에서 생성된 일반적인 리눅스 컨테이너다. 실행 중인 컨테이너는 도커를 실행하는 호스트에서 실행되는 프로세스이지만 호스트와 호스트에서 실행 중인 다른 프로세스와 완전히 격리돼 있다.

이미지 레이어의 이해

레이어란 기존 이미지에 추가적인 파일이 필요할 때 다시 다운로드받는 방법이 아닌 해당 파일을 추가하기 위한 개념

Docker container Layer ID

LET ME) 위의 shell 코드에서 cd90f92aa93f, b0a4a1a77178등과 같은 건 모두 레이어이다. 레이어는 차례차례 쌓이며, mysql같은 경우 마지막 레이어는 cd90f92aa93f인 것이다. 이미지 내 레이어는 나중에 이미지를 빌드할 때 중요한 개념이기 때문에 한 번 짚고 넘어가는 게 좋다고 생각한다.

Docker Container layer

  • 위 이미지에서 Images A를 살펴보면, 총 3개의 레이어로 구성 돼 있다. 이렇게 3개의 이미지 레이어로 구성된 도커 이미지를 $Docker run 명령어를 사용해 컨테이너로 만드는 순간!! 마지막에 container layer가 추가되면서 컨테이너로 동작하기 시작하는 것이다.
  • 컨테이너로 동작하기 시작하면, 사용자가 입력하고 하는 모든 행동은 container layer에서 이루어지며, 환경을 구성하는 이미지 레이어를 변경하는 것은 불가능하다.
  • 이미지 레이어는 컨테이너가 종료되도 사라지지 않지만, 컨테이너를 exit 하면 container layer만 사라지게 된다. 만약 내가 작업하던 container layer을 이미지 레이어로 저장하고 싶다면 $docker commit 명령어를 사용해준다. (이 부분은 나중에 새로 포스팅 해야겠다) 출처: https://anweh.tistory.com/66
  • 컨테이너가 실행될 때 이미지 레이어 위에 새로운 쓰기 가능한 레이어가 만들어진다. 컨테이너의 프로세스가 기본 레이어 중 하나에 있는 파일에 쓰면 전체 파일의 복사본의 최상위 레이어에 만들어지고 프로세스는 복사본에 쓴다.

1.2.3 도커의 대안으로 rkt 소개

지금 rkt을 언급하는 이유는 쿠버네티스가 도커 기반 컨테이너만을 위해 특별히 만들어진 컨테이너 오케스트레이션 시스템이라고 생각하는 실수를 하지 않게 하기 위해서다.

1.3 쿠버네티스 소개

전세계적으로 수십만 대의 서버를 운영하는 몇 안되는 기업(Google) 중 하나로, 엄청난 규모의 배포 관리를 처리해야 했다. 이로 인해 수천 개의 소프트웨어 구성 요소를 관리하고 비용 효율적으로 개발, 배포할 수 있는 솔루션을 개발해야만 했다.

쿠버네티스 핵심 이해

시스템은 마스터 노드와 여러 워커 노드로 구성된다.

1.3.3 쿠버네티스 클러스터 아키텍처 이해

하드웨어 수준에서 쿠버네티스 클러스터는 여러 노드로 구성되며, 두 가지 유형으로 나눌 수 있다.

  • 마스터 노드는 전체 쿠버네티스 시스템을 제어하고 관리하는 쿠버네티스 컨트롤 플레인을 실행한다.
  • 워커 노드는 실제 배포되는 컨테이너 애플리케이션을 실행한다.

컨트롤 플레인

컨트롤 플레인은 클러스터를 제어하고 작동시킨다. 하나의 마스터 노드에서 실행하거나 여러 노드로 분할되고 복제돼 고가용성을 보장할 수 있는 여러 구성 요소로 구성된다.

  • 쿠버네티스 API 서버는 사용자, 컨트롤 플레인 구성 요소와 통신한다.
  • 스케줄러는 애플리케이션의 배포를 담당한다.(애플리케이션의 배포 가능한 각 구성 요소를 워크 노드에 할당)
  • 컨트롤러 매니저는 구성 요소 복제본, 워커 노드 추적, 노드 장애 처리 등과 같은 클러스터단의 기능을 수행한다.
  • Etcd는 클러스터 구성을 지속적으로 저장하는 신뢰할 수 있는 분산 데이터 저장소다.

노드

워커 노드는 컨테이너화된 애플리케이션을 실행하는 시스템이다.

  • 컨테이너를 실행하는 도커, rkt 또는 다른 컨테이너 런타임
  • API 서버와 통신하고, 노드의 컨테이너를 관리하는 Kubelet
  • 애플리케이션 구성 요소 간에 네트워크 트래픽을 로드밸런싱하는 쿠버네티스 서비스 프록시 kube-proxy

쿠버네티스에서 애플리케이션 실행

쿠버네티스에서 애플리케이션을 실행하려면 먼저 애플리케이션을 하나 이상의 컨테이너 이미지로 패키징하고 해당 이미지를 이미지 레지스트리로 푸시한 다음 쿠버네티스 API 서버에 애플리케이션 디스크립션을 게시해야 한다.

디스크립션으로 컨테이너를 실행하는 방법 이해

API 서버가 애플리케이션 디스크립션을 처리할 때 스케줄러는 각 컨테이너에 필요한 리소스를 계산하고 해당 시점에 각 노드에 할당되지 않은 리소스를 기반으로 사용 가능한 워커노드에 지정된 컨테이너를 할당한다.

그런 다음 해당 노드의 Kubelet은 컨테이너 런타임 (예: Docker)에 필요한 컨테이너 이미지를 가져와 컨테이너를 실행하도록 지시한다.

실행된 컨테이너 유지

애플리케이션이 실행되면 쿠버네티스는 애플리케이션의 배포 상태가 사용자가 제공한 디스크립션과 일치하는지 지속적으로 확인한다.

프로세스가 중단되거나 응답이 중지될 때와 같이 인스턴스가 제대로 작동하지 않으면 쿠버네티스가 자동으로 다시 시작한다.

마찬가지로 워커 노드 전체가 종료되거나 액세스 할 수 없게 되면 쿠버네티스는 이 노드에서 실행 중인 모든 컨테이너의 노드를 새로 스케쥴링하고, 새로 선택한 노드에서 실행한다.

복제본 수 스케일링

LET ME) deployment.yaml 의 replicas 의 값을 변경하여 본제본(Pod) 수를 조정할 수 있다.

1.3.5 쿠버네티스 사용의 장점

애플리케이션이 실행할 가장 적합한 노드를 선택할 수 있다.

쿠버네티스는 모든 워커 노드를 하나의 배포 플랫폼으로 제공하기 때문에 애플리케이션 개발자는 자체적으로 애플리케이션 배포를 시작할 수 있으며 클러스터를 구성하는 서버에 관해 알 필요가 없다.

쿠버네티스는 애플리케이션 구성 요소와 이 애플리케이션이 구동 중인 노드를 모니터링하다가 노드 장애 발생 시 자동으로 애플리케이션을 다른 노드로 스케줄링한다.

LET ME) Pod 장애가 발생하면 0/3 으로 파드가 생성되지 않는다. 생각해보니 장애가 발생하여 0/3 으로 가만히 냅두는 게 아니라 3/3 이 될 때 까지 재시도를 했던 것으로 기억한다. 하지만 관리자는 무조건 있어야 한다. 이유 모를 문제가 발생했다면 그 문제를 찾고 고쳐야 되기 때문이다.

각 애플리케이션에서 사용하는 리소스를 모니터링하고 각 애플리케이션의 실행 중인 인스턴스 수를 계속 조정하도록 지시할 수 있다.

애플리케이션이 개발과 프로덕션 환경이 모두 동일한 환경에서 실행된다는 사실로 돌아가보면 버그가 발견됐을 때 큰 효과가 있다.

1.4 요약

  • 모놀리스 애플리케이션은 구촉하기 쉽지만 시간이 지남에 따라 유지 관리하기가 더 어려워지고 때로는 확장이 불가능할 수 있다.
  • 마이크로서비스 기반 애플리케이션 아키텍처는 각 구성 요소의 개발을 용이하게 하지만하나의 시스템으로 작동하도록 배포하고 구성하기가 어렵다.
  • 리눅스 컨테이너는 가상머신과 동일한 이점을 제공하지만 훨씬 더 가볍고 하드웨어 활용도를 높일 수 있다.
  • 도커는 OS 환경와 함께 컨테이너화된 애플리케이션을 좀 더 쉽고 빠르게 프로비저닝할 수 있도록 지원해 주는 리눅스 컨테이너 기술을 개선했다.
  • 쿠버네티스는 전체 데이터 센터를 애플리케이션 실행을 위한 컴퓨팅 리소스로 제공한다.
  • 개발자는 시스템 관리자의 도움 없이도 쿠버네티스로 애플리케이션을 배포할 수 있다.
  • 시스템 관리자는 쿠버네티스가 고장 난 노드를 자동으로 처리하도록 함으로써 더 편하게 잠을 잘 수 있다.

https://newbiecs.tistory.com/378

 

Kubernetes 인 액션 2장 도커와 쿠버네티스 첫 걸음

다루는 내용 도커를 사용한 컨테이너 이미지 생성, 실행, 공유 로컬에 단일 노드 쿠버네티스 클러스터 생성 구글 쿠버네티스 엔진에서 쿠버네티스 클러스터 설치 kubectl CLI 클라이언트 설정과 사

newbiecs.tistory.com

 

댓글

💲 추천 글