Skip to main content

그림으로 이해했던 가상화와 컨테이너

ghdwlsgur
Blog Owner

Vagrant, EC2, ECS, Docker 등은 줄곧 사용해오면서 쿠버네티스는 접할 기회가 없었는데 이번에 맘을 먹고 쿠버네티스 자격증 취득을 새해 목표로 쿠버네티스 자격증을 취득하려고 한다. (aws ans도 따야하는데...) 취득 전에 가상화 개념과 도커 기본 내용들을 복습 및 정리하고자 그림으로 이해하는 가상화와 컨테이너 도서를 퇴근 후 스벅에서 일주일 동안 피곤한 몸을 이끌며 주경야독을 실천했다 ㅎㅎ. 결론은 책 내용이 너무도 좋아서 블로그에 글을 남기기로 결심했다!

도커 컨테이너 라이프사이클

docker-kube-1

  • 생성: 컨테이너 레이어가 생성된 상태
  • 실행: 컨테이너 내 프로세스가 실행된 상태
  • 정지: 컨테이너 내 프로세스가 종료된 상태
  • 일시정지: 컨테이너 내 프로세스가 일시 정지된 상태
  • 삭제: 컨테이너 레이어가 삭제된 상태

요약

  • 라이프 사이클은 컨테이너가 생성된 후 삭제될 때까지의 상태 흐름이다.
  • 컨테이너는 생성, 실행, 정지, 일시 정지, 삭제 상태를 취할 수 있다.
  • 컨테이너 상태는 도커 명령어의 실행으로 변경된다.

도커 엔진과 도커 데몬

docker-kube-2 docker-kube-3

  • 도커 데몬은 도커 클라이언트의 요청에 따라 도커 객체를 관리한다.
  • 도커 객체는 도커 데몬의 관리 대상이며 컨테이너 및 컨테이너 이미지를 포함한다.
  • 도커 데몬은 도커 클라이언트의 요청을 수락하기 위한 API가 있다.

바인드 마운트와 네임 스페이스

볼륨과 비슷한 기능으로 바인드 마운트라는 기능이 있는데 바인드 마운트는 호스트 운영 체제의 파일 시스템을 컨테이너에 마운트한다는 점이 볼륨과 다르다. 바인드 마운트 역시 파일 시스템을 공유할 수 있지만 제약이 많기 때문에 파일 시스템을 공유할 때는 볼륨을 사용하는 편이 낫다. 바인드 마운트는 주로 호스트와 컨테이너 간에 파일 시스템을 공유하기 위해 사용된다.

"보이지 않는다면 없는 것과 같다"

도커는 네임스페이스를 이용해 다른 컨테이너와 격리하는데 네임 스페이스의 실제 역할은 내부에서 외부를 볼 수 없게 하는 것 뿐이다.

  • 도커는 프로세스별로 컨테이너를 분리하는 것을 추천한다.
  • 볼륨은 컨테이너가 읽고 쓰는 데이터를 지속화하기 위한 방법이다.
  • 볼륨을 사용하면 여러 컨테이너에서 파일 시스템을 공유할 수 있다.
  • 네임 스페이스는 내부 프로세스가 외부 프로세스와 격리된 것처럼 보이는 방식이다.
  • 도커는 네임스페이스의 작동 방식을 사용해 컨테이너를 다른 컨테이너와 격리한다.
  • 컨트롤 그룹은 컨테이너가 하드웨어 리소스 사용량을 제한하는 방법이다.
  • 컨트롤 그룹으로 하드웨어 리소스 사용량에 상한선을 설정함으로써 특정 컨테이너가 시스템 리소스를 소모해 다른 컨테이너에 영향을 미치는 상황을 방지한다.

도커 컨테이너 이미지

  • 차분 관리는 기준과의 차이점을 기록하고 변경을 관리하는 방법이다.
  • 컨테이너 이미지에 포함된 파일 시스템은 직전과의 차이를 기록하는 여러 레이어로 구성된다.
  • 차분 관리 덕분에 시작할 때 복사할 필요가 없으므로 빠르게 배포할 수 있다.
  • 컨테이너를 실행하면 이미지 레이어 위에 프로세스에 따른 파일 추가나 변경 사항을 기록하는 레이어가 생성된다. 이 레이어를 컨테이너 레이어라고 하며 기록할 수 있다는 점이 읽기 전용인 이미지 레이어와 다르다.
  • 컨테이너의 프로세스가 이미지 레이어에 포함된 파일을 수정하려고 하면 대상 파일을 이미지 레이어에서 컨테이너 레이어로 복사한 다음, 복사된 파일을 변경한다. 이러한 변경 방법은 카피 온 라이트 전략이라고 하며 도커의 파일 읽기 및 쓰기의 속도가 빨라지도록 지원한다.

쿠버네티스

  • 컨테이너 오케스트레이션은 컨테이너 관리 및 운영을 자동화한다.
  • 컨테이너의 관리 및 운영에는 로드 밸런싱, 헬스 체크, 스케일링 등이 필요하다.
  • 컨테이너를 활용한 애플리케이션이 보급되고 그 규모가 커질수록 컨테이너 오케스트레이션은 점점 더 중요해질 것이다.

쿠버네티스에서 가능한 것

  • 헬스 체크와 정지한 컨테이너 재시작
  • 엔드포인트 제공과 로드밸런싱
  • 소비 리소스를 고려한 컨테이너의 배포
  • 롤링 업데이트와 롤백
  • 스토리지 관리
  • 기밀 정보 및 구성 정보 저장

쿠버네티스에서 불가능한 것

  • 자동빌드
  • 로그의 기록 및 감시
  • 미들웨어 기능
  • 서버 자체의 관리

쿠버네티스는 대량의 컨테이너 및 서버로 구축된 서비스의 관리 및 운영에 대한 부하를 줄일 수 있다. 이러한 시스템의 집합을 클러스터라고 하며, 쿠버네티스에서 관리하는 클러스터를 쿠버네티스 클러스터라고 한다. 또한, 클러스터를 구성하는 각 서버를 노드라고 한다.

마스터와 워커

docker-kube-4

  • 노드에는 실제로 파드를 구동하는 워커 노드(워커)와 워커를 제어하는 마스터 노드(마스터)가 있다.
  • 쿠버네티스는 오케스트레이션(컨테이너 관리 및 운영을 자동화)하는 도구다.
  • 쿠버네티스 클러스터는 쿠버네티스에서 관리하는 시스템의 집합이다.
  • 노드에는 실제로 파드를 구동하는 워커와 워커를 제어하는 마스터라는 두 가지 유형이 있다.

파드 (Pod)

  • 파드는 쿠버네티스가 컨테이너를 관리하는 최소 단위이며 하나 이상의 컨테이너로 구성된다. 같은 파드에 포함된 컨테이너는 라이프 사이클이 같아 파드 내 한 컨테이너가 시작되면 다른 모든 컨테이너도 시작되고 한 컨테이너가 중지되면 다른 모든 컨테이너도 중지된다.
  • 컨테이너에서 여러 프로세스를 시작하면 직접 프로세스를 관리해야 하지만 파드 내에서 여러 컨테이너를 시작하면 쿠버네티스가 컨테이너를 관리할 수 있다.
  • 파드는 쿠버네티스가 컨테이너를 관리하는 최소 단위다.
  • 같은 파드 내에서 시작할 필요가 없는 컨테이너는 가능한 한 별도의 파드에 포함되는 것이 좋다.
  • 파드는 컨테이너 관리를 쿠버네티스에 맡길 수 있다.
  • 사이드카 컨테이너는 자주 사용하는 디자인 패턴(설계 패턴)이다.

레플리카셋과 디플로이먼트

  • 레플리카셋은 같은 유형의 파드만 포함하는 그룹이다.
  • 디플로이먼트는 같은 레플리카셋의 다른 버전이 포함된 그룹이다.
  • 디플로이먼트 컨트롤러는 디플로이먼트를 특정 상태로 유지하는 컨트롤러이다.

서비스

  • 쿠버네티스의 서비스란 컨테이너에 접속하기 위한 창구인 엔드포인트를 제공하는 방식을 말한다. 외부에서 컨테이너에 접속하려면 컨테이너에 직접 접속하는 것이 아니고 엔드포인트를 통해 간접적으로 접속하는 것이다.
  • 서비스는 컨테이너에 접속하기 위한 엔드포인트를 제공한다.
  • 서비스에 의해 컨테이너의 실행과 정지가 반복되는 상황에서도 컨테이너에 접속할 수 있다.

서비스 유형과 특징

  • ClusterIP: 클러스터 내부에만 접속할 수 있는 가상 IP 주소 생성
  • NodePort: 클러스터의 모든 노드의 지정된 포트에 대한 접속이 컨테이너로 전달된다. 클러스터 외부에서도 접속할 수 있다.
  • LoadBalancer: 클라우드 서비스의 로드 밸런서에 대한 접속이 컨테이너로 전송된다. 클러스터 외부에서도 접속할 수 있다.
  • ExternalName: 서비스에 대한 접속이 지정된 호스트로 전달된다.

파드 내 통신

flanneld는 플라넬이 IPv4 네트워크를 구축하기 위해 쿠버네티스 클러스터를 구성하는 모든 컴퓨터에서 구동되는 에이전트 프로그램이다. 만약 플라넬로 구축한 IPv4 네트워크가 없는 경우, 서비스는 엔드포인트에 접속을 같은 컴퓨터의 파드로만 연결할 수 있으며 다른 파드로는 연결할 수 없게 된다.

  • 같은 파드에 포함된 컨테이너는 로컬호스트에 접속하면 통신할 수 있다.
  • 파드에는 고유의 IP 주소가 할당되어 있다.
  • 플라넬은 컴퓨터의 파드끼리 통신하는 방식이다.

iptables는 리눅스의 네트워크 관리 도구이며 iptables를 사용하면 netfilter(패킷 필터링 및 네트워크 주소 변환을 수행하는 리눅스의 기능) 설정을 변경할 수 있고 IPVS는 리눅스 커널에 내장된 로드 밸런싱 기능이며 iptables와 마찬가지로 netfilter를 사용하지만 IPVS는 설정 내용을 해시 테이블에 보존하거나 커널 모드에서 동작하는 등 효율화가 진행되어 iptables보다 빠른 속도로 동작한다.

docker-kube-5

  • 로드 밸런싱과 헬스체크를 조합하면 시스템 가용성을 높일 수 있다.
  • kube-proxy는 iptables 규칙을 변경해 로드 밸런싱을 실현한다.
  • kubelet은 파드의 상태를 정기적으로 확인해 헬스 체크를 구현한다.

쿠버네티스의 오토스케일링

쿠버네티스에서 파드의 스케일링에는 수평 스케일링과 수직 스케일링으로 나뉘며 수평 스케일링에는 HPA(Horizontal Pod Autoscaler)를 사용해 파드를 수평 스케일링하고 수직 스케일링은 VPA(Vertical Pod Autoscaler)를 사용하며 limi(상한선)과 request(하한선)을 설정하여 상한선과 하한선 사이에서 리소스 소비량을 유지한다.

  • 스케일링이란 요청 규모에 따라 컨테이너를 늘리거나 줄이는 것을 말한다.
  • 매트릭스는 스케일링을 수행할지 여부를 결정하는 데 사용하는 데이터다.
  • HPA는 파드의 수평 스케일링을 수행하고, CA는 클러스터의 수평 스케일링을 수행한다.

레이블과 레이블 셀렉터

docker-kube-6

쿠버네티스는 메니페스트로 클러스터를 조작하며 레이블 및 레이블 셀렉터를 사용해 개체를 선택할 수 있다.

마스터와 워커의 구조

docker-kube-7

마스터는 kube-api-server, etcd, kube-scheduler, kube-controller-manager와 같은 다양한 구성 요소를 실행한다.

  • kube-api-server: 사용자 및 워커가 쿠버네티스 클러스터와 상호 작용할 수 있는 엔드포인트(REST API)를 제공한다.
  • etcd: (쿠버네티스 클러스터와 관련된 설정 등)를 저장하는 장소다. 여러 노드로 구성된 키-값 저장소이며, 일부 노드가 고장 나도 데이터가 손실되거나 불일치가 발생하지 않는 구조를 갖추고 있다. kube-api-server와 etcd는 프런트엔드와 백엔드간 관계이며 kube-api-server는 데이터를 갖지 않고 etcd를 통해 데이터를 관리한다.
  • kube-scheduler: 파드를 시작할 노드를 계획하는 스케쥴러다. 필요한 리소스 등 다양한 조건을 고려해 최적의 노드를 결정한다.
  • kube-controller-manager: 디플로이먼트 컨트롤러와 같은 여러 컨트롤의 실행 및 정지를 관리하고 쿠버네티스 클러스터를 정상적인 상태로 유지한다.

워커는 컨테이너를 시작하는 데 필요한 컨테이너 런타임을 실행하고 kubeletkube-proxy라는 두 에이전트 프로그램을 실행한다.

  • kubelet: 마스터에서 PodSpec(파드의 상태를 나타내는 데이터)을 가져온 다음, 컨테이너 런타임 인터페이스에 접근해 컨테이너를 실행/정지 및 감시한다.
  • kube-proxy: 마스터에서 네트워크 구성을 가져온 다음, 파드와 파드가 통신할 때 접근 중계 및 주소 변환 규칙을 변경한다.