Skip to main content

컨테이너와 쿠버네티스 리마인드

컨테이너 역사

  • 1979 chroot - 애플리케이션이 지정된 디렉토리만 접근하도록 제한
  • 2006 cgroups - 프로세스들의 리소스 사용을 제한 및 격리
  • 2008 LXC
  • 2013 Docker
  • 2014 Kubernetes

컨테이너란

  • 컨테이너 기술에서는 가능한 한 데이터를 컨테이너에 포함하지 않는 것이 기본이다.
  • 컨테이너 가상화에서 호스트 가상화(OS가상화) 또는 하이퍼바이저 가상화에서 가지고 있는 게스트 OS가 없다는 것은 컨테이너 내 애플리케이션에서도 호스트 OS의 기능(커널)을 이용해 동작한다는 것이다. 커널을 공유해도 컨테이너가 가지는 파일시스템이 독립적이기 때문에 호스트 OS 내에 설치된 다른 어플리케이션이나 파일들에는 영향을 끼치지 않는다.
  • 컨테이너 런타임은 컨테이너를 실행하거나 관리하는 소프트웨어이다.
  • 컨테이너가 일반 프로세스와 다른 점은 네임스페이스를 통해 다른 프로세스와 격리되도록 설정한다.
  • 컨테이너는 다른 컨테이너나 프로세스와 운영체제(정확하게는 커널이라고 하는 운영체제의 핵심부분)를 공유하는 반면, 가상서버는 다른 가상 서버나 물리서버와 운영체제를 공유하지 않는다.
  • 컨테이너는 프로세스, 그 자체이다.
  • 리눅스 배포판은 리눅스 커널과 그 외의 소프트웨어(셸이나 에디터들을 하나로 모아놓은 것)이며 컨테이너 이미지에 OS 이미지(리눅스)를 사용할 때 이 리눅스 배포판을 사용하게 된다.
  • 컨테이너는 호스트 머신의 운영체제(커널)을 이용하고 있지만, 어떤 컨테이너가 우분투에 포함되는 소프트웨어를 갖추고 있다면 그 컨테이너 내에서 실행하는 프로세스를 마치 우분투에서 실행되는 것처럼 보이게 할 수 있다. 호스트 OS가 윈도 또는 맥OS인 경우 도커 데스크톱을 설치하면 컨테이너형 가상화 소프트웨어에 리눅스 가상 시스템이 구축된다. 컨테이너는 리눅스 가상 서버에서 동작하도록 구성된다.
  • 컨테이너 이미지의 대부분은 컨테이너를 실행하는 데 필요한 파일시스템이며 파일시스템은 레이어라는 층이 겹쳐서 구성된다.
  • 컨테이너는 프로세스이고 컨테이너 이미지는 데이터이다.
  • 운영체제 설치 디스크는 소프트웨어를 하드 디스크 드라이브 등으로 복사하는 반면 컨테이너 이미지는 컨테이너 프로세스에서 컨테이너 이미지의 소프트웨어에 접근할 수 있으므로 복사하지 않는다. 또한 운영체제 설치 디스크에는 리눅스 커널이 포함되어 있지만 컨테이너 이미지에는 리눅스 커널이 포함되어 있지 않다.
  • 컨테이너 생성 시에 도커 클라이언트는 도커 데몬 API에 요청을 전달하고 도커 데몬은 컨테이너를 생성하기 전에 먼저 네임스페이스 프로세스를 생성한 뒤 네임스페이스의 멤버로 컨테이너 프로세스를 실행합니다.
  • 컨테이너를 실행하면 이미지 레이어 위에 프로세스에 따른 파일추가나 변경사항을 기록하는 레이어가 생성되며 이 레이어를 컨테이너 레이어라고 한다. 기록할 수 있다는 점이 읽기 전용인 컨테이너 이미지 레이어와는 차이점을 가진다.
  • 컨테이너 프로세스가 이미지 레이어에 포함된 파일을 수정하려고 하면 대상 파일을 이미지 레이어에서 컨테이너 레이어로 복사한 다음, 복사된 파일을 변경한다. 이러한 변경 방법을 카피 온 라이트 전략이라고 한다.

쿠버네티스

  • 쿠버네티스는 패킷을 전달하기 위해 iptables의 네트워크 주소 변환 기능을 사용한다. 또한, 패킷을 전송하는 방법을 결정하는 규칙은 kube-proxy라는 에이전트 프로그램에 의해 필요에 따라 변경한다. iptables 대신 IPVS를 사용할 수도 있으며 서비스 수가 10,000개를 초과하는 대규모 클러스터에서는 IPVS를 사용하는 것이 좋다. 워커 노드의 kube-proxy는 마스터 노드의 kube-api-server로부터 패킷전송 규칙을 취득하고 kube-proxy는 취득한 정보로 iptables의 주소를 변경함으로써 파드 간 상호통신이 이루어지게 한다.
  • iptables는 리눅스의 네트워크 관리 도구이며 iptables를 사용하면 netfilter(패킷 필터링 및 네트워크 주소 변환을 수행하는 리눅스의 기능)설정을 변경할 수 있다. 반면 IPVS는 리눅스 커널에 내장된 로드 밸런싱 기능이며 iptables와 마찬가지로 netfilter를 사용한다. iptables와 IPVS를 비교하면, IPVS는 설정 내용을 해시테이블에 보존하거나 커널 모드에서 동작하는 등 효율화가 진행되어 iptables보다 빠른 속도로 동작한다.
  • kubelet은 파드의 상태를 정기적으로 확인해 헬스체크를 구현한다.
  • 쿠버네티스에서는 HPA(Horizontal Pod Autoscaler)를 사용해 파드를 수평 스케일링할 수 있다. HPA 컨트롤러는 주기적으로(기본적으로 15초 간격으로) 파드의 매트릭스를 취득해 이를 기반으로 필요한 파드 수를 계산하고 레플리카셋 및 디플로이먼트의 파드 수를 변경한다.
  • VPA(Vertical Pod Autoscaler)를 사용해 파드를 수직 스케일링할 수 있다. 파드에 할당하는 리소스(CPU나 메모리)등의 수량은 request와 limit이라는 두 파라미터에 따라 정해지며 각각 request는 하한선을 limit은 상한선을 지정한다.
  • 디플로이먼트 컨트롤러란 디플로이먼트를 특정한 상태로 유지하는 컨트롤러다.
  • 쿠버네티스 클러스터가 아마존 웹서비스 및 애저와 같은 퍼블릭 클라우드에 구축된 경우 CA(Cluster Autoscaler)를 사용해 클러스터 자체를 수평 스케일링할 수 있다. CA는 클러스터를 구성하는 시스템의 수를 늘리거나 줄여서 수평 스케일링한다. CA가 서버 수를 늘리는 타이밍은 HPA와 다르며 CA는 리소스 부족으로 파드를 시작하지 못한 경우에 서버 수를 늘린다.

마스터 노드

  • 마스터 노드는 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는 디플로이먼트 컨트롤러와 같은 여러 컨트롤러의 실행 및 정지를 관리하고 쿠버네티스 클러스터를 정상적인 상태로 유지한다.

워커 노드

  • 워커는 컨테이너를 시작하는 데 필요한 컨테이너 런타임(도커, 크라이오 등)을 실행하고 kubelet과 kube-proxy라는 두 에이전트 프로그램을 실행한다.
  • kubelet은 마스터 노드에서 PodSpec(파드의 상태를 나타내는 데이터)을 가져온 다음, 컨테이너 런타임 인터페이스에 접근해 컨테이너를 실행/정지 및 감시한다.
  • kube-proxy는 마스터 노드에서 네트워크 구성을 가져온 다음, 파드와 파드가 통신할 때 접근 중계 및 주소 변환 규칙을 변경한다.