Kubernetes의 정의와 도입 취지
마이크로 서비스 아키텍쳐가 성행하면서 하나의 시스템을 구성하는 독립적인 애플리케이션의 수는 많아지고, 컨테이너들의 상호 관계는 좀 더 복잡해졌습니다. 이로 인해 높아진 서비스 운영 난이도를 해소하고자 ‘자동화 프로세스’를 도입하여 체계적인 컨테이너 관리 및 조율을 돕는 기술들이 개발되어 왔는데요. 이런 기술을 설명하기 위해 컨테이너 오케스트레이션(Container Orchestration)이라는 용어가 등장하였습니다.
Kubernetes(줄여서 k8s
)는 대표적인 컨테이너 오케스트레이션 툴입니다. 자동화된 배포, 스케일링, 장애 복구 등 필수적인 오케스트레이션 기능을 비롯하여 단일 서버 급을 뛰어넘는 클러스터 전반에 탄력적인 운영을 수행해는 프레임워크로 많은 인기를 누리고 있습니다.
Kubernetes 안에서는 어떤 일이 벌어지나?
그렇다면 Kubernetes는 어떻게 컨테이너를 관리하는 걸까요? Kubernetes의 동작을 개략적으로 기술하면 다음과 같습니다.
- 상태 체크: 현재 상태 = 원하는 상태(Desired State) 인지 체크 (ex. 컨테이너 개수가 맞는지 등)
- 차이점 발견: 현재 상태 ≠ 원하는 상태
- 조치: 현재 상태 → 원하는 상태
위 1~3 과정은 Kubenetes 내부에서 무한 루프를 돌게 됩니다. 핵심은 컨테이너가 어떤 내부/외부 상황에도 끊임없이 동작하게 하는 것입니다. 애플리케이션과 서비스는 원래 수시로 다운되기 일쑤입니다. 시스템 에러나 일시적인 네트워크 오류는 흔한 사유에 속하죠.
이따금씩 이런 오류가 발생하더라도 애플리케이션이 상시로 정상 작동하는 것처럼 보이려면 시스템에서 변화를 빠르게 추적해야 합니다. 컨테이너 상태가 양호한지, 그리고 문제가 생긴 컨테이너들이 새 컨테이너로 대체하는 이러한 중요한 작업을 Kubenetes에서는 Health check라는 용어로 표현합니다.
Kubernetes가 제공하는 것
구체적으로 Kubernetes의 기능적 측면을 파헤쳐보면 아래와 같습니다.
서비스 디스커버리와 로드 밸런싱
Kubernetes 컨테이너를 노출시킬 때, 자체 IP 주소를 사용하거나 DNS 체계를 도입하는 선택지를 제공합니다. 컨테이너로 향하는 트래픽이 증가하면 Kubernetes는 네트워크 트래픽을 로드 밸런싱하여 안정적인 운영을 도모합니다.
자동화된 롤아웃(Roll-out)과 롤백(Roll-back)
애플리케이션의 cofiguration이 변경되거나 새로운 업데이트가 발생하더라도, 실행 중인 애플리케이션의 성능에 영향을 주지 않고 배포가 이뤄집니다. 또한, 업데이트 중에 에러가 발견되면 자동으로 이전 애플리케이션 버전으로 롤백이 이뤄집니다.
자동화된 복구(self-healing)
초기화 과정 또는 동작 중에 문제가 발생한 컨테이너를 즉시 재시작하여, 오작동으로 인한 서비스 지연을 최소화시킵니다.
자동화된 빈 패킹(*bin packing)
Kubernetes 클러스터는 하나 이상의 노드(서버 자원)으로 구성되는데, 각 노드의 CPU, 메모리 등의 자원을 고려하여 컨테이너를 적재적소에 배치합니다.
*bin packing: n
개의 물건을 m
개의 가방에 모두 담을 수 있도록 용량을 고려하여 배분하는 문제를 의미합니다.
Secreat과 configuration 관리
클러스터 전체 또는 일부 서비스 그룹에 활용되는 암호, 인증 키, 애플리케이션 속성 등을 관리합니다.
스토리지 오케스트레이션
일반적인 시스템에서는 데이터를 각 서버/노드 내에 저장하여 관리했으나, Kubernetes는 공용 스토리지를 구성하여 접근 권한만 주어진다면 컨테이너끼리 파일 시스템을 자유롭게 활용할 수 있습니다.
Kubernetes vs Docker
Kubernetes를 설명하는 Diagram이나 실습 자료를 보면Docker가 심심치 않게 등장하는 것을 느낀 분들도 있을 겁니다. 실제로도 많은 곳에서 Kubernetes 클러스터를 구축할 때 Docker시스템과 연동을 이루곤 합니다.
Docker도 컨테이너를 다루는 도구인데, 그렇다면 Kubernetes와 Docker 두 가지를 왜 동시에 함께 쓰는 걸까요? 그 둘은 어떤 부분에서 차별점이 있을까요?
Docker = 컨테이너 런타임 ≠ 컨테이너 오케스트레이터
컨테이너 런타임(Container runtime)은 컨테이너를 쉽게 배포하고 구동할 수 있도록 하는 도구를 의미합니다. 잘 알려진 것이 바로 Docker이죠. 컨테이너 기반으로 실행되는 애플리케이션의 기능적인 측면에 초점이 맞춰져 있습니다.
반면, Kubernetes와 같은 컨테이너 오케스트레이터는 운영적인 측면을 소화하기 위해 개발되었습니다. 이들은 컨테이너 런타임을 이용하여 원하는 서비스를 지속적으로 운영/관리하기 위한 정책과 컨테이너를 띄울 호스트(노드)에 관한 구체적인 명세를 갖춰야 합니다.
컨테이너를 어떤 노드에 배치할지, 문제가 생긴 컨테이너를 어떻게 처리할지, 컨테이너에 적용할 보안 정책과 환경 설정은 무엇인지 등이야말로 컨테이너 오케스트레이터가 다뤄야 하는 부분입니다.
Docker는 Kubernetes를 비롯한 컨테이너 오케스트레이터가 채택할 수 있는 컨테이너 런타임 후보 중 하나일 뿐이며, Docker 이외에도 CRI-O
, rkt
, containerd
등의 다양한 컨테이너 런타임을 활용 가능합니다.
그리고 Docker는 단일 호스트에서 동작하는 데몬 형태로 제공되는 엔진인데 반해, Kubernetes는 여러 호스트(노드)를 통틀어 관리하여 컨테이너 실행과 운영에 대한 지시를 내릴 수 있습니다. Kubernetes 클러스터에 속하는 각 노드는 저마다 컨테이너 런타임을 갖추고 있습니다.