쿠버네티스 알아보기 3편: 쿠버네티스를 이루고 있는 여러 가지 구성 요소

1, 2편에서 컨테이너 개념과 쿠버네티스를 설치하는 방법 등 전반적인 사항을 알아보았습니다. 이번 글부터 쿠버네티스에 대해서 좀 더 본격적으로 알아보려고 하는데요. 먼저 쿠버네티스를 이루는 구성 요소 쿠버네티스 컴포넌트에 대해 살펴보겠습니다.

쿠버네티스 컴포넌트를 크게 분류를 하자면, 쿠버네티스 기능 제어를 전체적으로 담당하는 컨트롤 플레인(Control Plane) 컴포넌트와 컨트롤 플레인 컴포넌트의 요청을 받아 각 노드에서 동작을 담당하는 노드(Node) 컴포넌트로 나누어볼 수 있습니다. 컨트롤 플레인 컴포넌트와 노드 컴포넌트는 세부적으로 많은 개별 구성 요소를 가지고 있는데요. 먼저 이 구조를 전체적으로 살펴보겠습니다. 아래 그림은 쿠버네티스 공식 홈페이지에서 소개하고 있는 쿠버네티스의 컴포넌트들입니다.

Kubernetes cluster Control Plane c-m c-c-m -> Cloud provider API api etcd sched Node Kublet k-proxy Node Kublet k-proxy Node Kublet k-proxy API server api Cloud controller manager (optional) c-c-m Controller manager c-m etcd(persistence store) etcd kublet kublet kube-proxy k-proxy Scheduler (sched) Control plane Node
쿠버네티스 컴포넌트(https://kubernetes.io/ko/docs/concepts/overview/components/)

뭔가 컴포넌트가 굉장히 많고 알아야 할 것도 많아 보이죠? 그렇지만 너무 걱정 마세요. 위 그림의 컴포넌트들이 가장 핵심적인 구성 요소이고, 각 부분에 대해 지금부터 차근차근 따라오시면 쿠버네스가 어떻게 동작하는지는 확실히 감을 잡으실 수 있을 것입니다!

앞에서 쿠버네티스의 컴포넌트는 컨트롤 플레인(Control Plane) 컴포넌트와 노드(Node) 컴포넌트로 나누어진다고 말씀드렸죠? 오늘은 이 부분을 회사 조직과 업무에 비유해 보려 합니다. 먼저 컨트롤 플레인 컴포넌트는 회사 전반에 해당하는 ‘본사의 업무’라고 할 수 있습니다. 노드 컴포넌트는 각 지역별 ‘지사의 업무’라고 볼 수 있습니다.

컨트롤 플레인(Control Plane) 컴포넌트

컨트롤 플레인에 속해 있는 컴포넌트를 살펴보면 아래와 같습니다.

kube-apiserver : 공식 문서에서는 kube-apiserver를 ‘쿠버네티스 컨트롤 플레인의 프론트 엔드’ 라고 소개하고 있는데요. 쉽게 감이 오지 않는 분들을 위해 비유를 들어볼게요. 우리가 어떤 회사에 방문하면 가장 먼저 안내데스크를 찾아갑니다. 여기서 방문 목적을 설명하고 안내를 받는데요. 안내 데스크에서는 이 방문자가 적절한 방문자인지 시스템에서 검색하거나 관련된 직원에게 문의하여 방문증을 발급하고, 가야 할 곳을 안내해줍니다. 이런 역할을 하는 컴포넌트가 kube-apiserver입니다. kube-apiserver는 쿠버네티스 클러스터로 들어오는 요청을 가장 앞에서 접수하는 역할을 해요. 예를 들어 쿠버네티스 커맨드 라인 도구인 kubectl을 사용해 각종 명령을 수행할 경우 이 명령은 kube-apiserver로 전송됩니다. 이렇게 전달된 요청에 대하여 kube-apiserver는 이 요청의 처리 흐름에 따라 적절한 컴포넌트로 요청을 전달하는 역할까지 맡고 있습니다.

etcd : 겉으로는 쉽게 드러나지 않아 놓치기 쉽지만 매우 중요한 역할을 담당하고 있는 컴포넌트가 엣시디(이하 etcd)입니다. 쿠버네티스 클러스터가 동작하기 위해서는 클러스터 및 리소스의 구성 정보, 상태 정보 및 명세 정보 등이 필요합니다. etcd는 이를 키-값(key-value) 형태로 저장하는 저장소입니다. 만약 etcd가 정상적으로 동작하지 않는다면 쿠버네티스 클러스터에 존재하는 리소스들은 그저 바다에 떠다니는 난파선과 다를 바 없게 됩니다. etcd는 이처럼 매우 중요한 역할을 수행하고 있는데요. 안정적인 동작을 위해 자료를 분산해서 저장하는 구조를 채택하고 있습니다. 비유해서 설명드리자면, etcd는 회사 각종 중요 정보가 모두 모여 있는 금고와 같은 곳이고, 매우 중요한 정보를 보관하는 금고이기 때문에 동일한 자료를 여러 금고에 나눠서 보관하고 있다고 생각하시면 될 것 같습니다.

kube-scheduler : 쿠버네티스 클러스터는 여러 노드로 구성되어 있어요. 그리고, 기본적인 작업 단위라고 할 수 있는 파드는 여러 노드 중 특정 노드에 배치되어 동작하게 됩니다. 이때 새로 생성된 파드를 감지하여 어떤 노드로 배치할지 결정하는 작업을 스케줄링이라고 해요. 이런 스케줄링을 담당하는 컴포넌트가 kube-scheduler입니다. 스케줄링을 위해 노드 및 파드의 각종 요구사항과 제약사항을 종합적으로 판단할 필요가 있는데, 이러한 판단 또한 kube-scheduler의 역할입니다. 회사로 비유하자면, 각 부서 인력 소요 계획과 신입사원 역량을 고려해 적절한 부서로 배치하는 인사 담당 부서에 비유할 수 있습니다.

kube-controller-manager : 회사에서는 목표 수준을 달성하기 위해 끊임없이 확인하고, 목표치에 미달하는 부분에 대해서는 대책을 수립합니다. 목표 달성한 후에도 이를 유지하려면 책임감 있는 관리자가 필요하죠. 쿠버네티스에서 이 역할을 하는 컴포넌트가 kube-controller-manager입니다. kube-controller-manager는 다운된 노드가 없는지, 파드가 의도한 복제(Replicas) 숫자를 유지하고 있는지, 서비스와 파드는 적절하게 연결되어 있는지, 네임스페이스에 대한 기본 계정과 토큰이 생성되어 있는지를 확인하고 적절하지 않다면 적절한 수준을 유지하기 위해 조치하는 역할을 하고 있습니다.

노드(Node) 컴포넌트

그럼 이제 노드(Node) 컴포넌트에 대해서 살펴보겠습니다.

kubelet : 쿠블릿(kubelet)은 노드에서 컨테이너가 동작하도록 관리해 주는 핵심 요소입니다. 각 노드에서 파드를 생성하고 정상적으로 동작하는지 관리하는 역할을 담당하고 있으며, 실제로 우리가 쿠버네티스의 워크로드를 관리하기 위해 내려지는 명령은 kubelet을 통해 수행된다고 볼 수 있습니다. 우리가 쿠버네티스 파드를 관리하기 위해 작성하는 YAML을 쿠버네티스 클러스터에 적용하기 위해 kubectl 명령어를 사용할 때, 이 YAML이 kube-apiserver로 전송된 후 kubelet으로 전달됩니다. kubelet은 이 YAML을 통해 전달된 파드를 생성 혹은 변경하고, 이후 이 YAML에 명시된 컨테이너가 정상적으로 실행되고 있는지 확인합니다. 지사에서 본사의 업무 요청을 받아 확인하는 막중한 역할을 수행하고 있다고 볼 수 있습니다.

container runtime : 컨테이너 런타임은 파드에 포함된 컨테이너 실행을 실질적으로 담당하는 애플리케이션을 의미합니다. 단, 컨테이너 런타임은 쿠버네티스 구성 요소에 기본적으로 포함되어 있거나, 특정 소프트웨어를 지칭하는 것은 아닙니다. 쿠버네티스가 컨테이너를 제어하기 위해 제공하는 표준 규약인 컨테이너 런타임 인터페이스(CRI)를 준수하여 쿠버네티스와 함께 사용할 수 있는 외부 애플리케이션들을 의미합니다. 쿠버네티스는 컨테이너 관리를 위해 특정 애플리케이션을 사용할 것을 강제하지는 않고 단지 쿠버네티스가 제공하는 규약에 따라 쿠버네티스와 연계할 것을 요구하고 있습니다. 이러한 규약을 따르는 대표적인 컨테이너 런타임은 컨테이너디(containerd), 크라이오(CRI-O) 등이 있습니다. 컨테이너 런타임에 대한 좀 더 자세한 설명은 ‘흔들리는 도커(Docker)의 위상 - OCI와 CRI 중심으로 재편되는 컨테이너 생태계’를 참고하시기 바랍니다.

kube-proxy : kube-proxy는 쿠버네티스 클러스터 내부에서 네트워크 요청을 전달하는 역할을 합니다. 이 부분에 대해 제대로 이해하기 위해서는 쿠버네티스의 네트워크 동작 방식에 대한 이해가 필요하지만, 이번 글에서는 최대한 간단하게 비유하여 설명드리겠습니다.

먼저 이 글을 읽으시는 분이 저에게 선물을 보내고 싶다고 가정해 볼게요. 그렇지만 여러분은 제가 삼성SDS 어떤 사업장에 근무하는지 알 수 없습니다. 그러므로 독자 여러분은 단지 삼성SDS 심근우에게 선물을 보낼 수 있을 뿐입니다. 이 선물이 전달되는 과정을 살펴볼게요. 우선 삼성SDS는 잠실 WEST 캠퍼스, 잠실 EAST 캠퍼스, 판교 IT캠퍼스 그리고 상암데이터센터에 사업장이 있으며, 저는 상암데이터센터에서 근무하고 있습니다. 독자 여러분이 삼성SDS로 선물을 발송했다면, 일단 이 선물은 아마도 본사 소재지인 잠실 WEST 캠퍼스로 전달될 것입니다. 그렇지만 저는 상암데이터센터에 근무하고 있으므로 잠실 WEST 캠퍼스에서 선물을 받을 수는 없겠죠? 삼성SDS에서 이 선물을 상암데이터센터에 있는 저에게 다시 보낼 것입니다. 이제 저는 여러분이 보내주신 선물을 전달받을 수 있게 되었어요!

이 예시에서 제가 어느 사업장에 있는지 관리하고, 저에게 오는 선물이 타 사업장으로 도착했더라도 다시 제가 위치한 사업장으로 전달해 주는 역할을 kube-proxy가 수행합니다. 제가 쿠버네티스 내부에 위치한 파드와 같은 역할을 한다고 가정했을 때, kube-proxy가 없었다면 쿠버네티스 내부에 위치한 특정 파드로 요청을 보내기 위해서 해당 파드의 IP를 정확히 알아야 하며, 이 IP가 외부에서 접근 가능하도록 구성되어야 할 것입니다. 그렇지만 쿠버네티스 파드 IP는 파드가 배포될 때마다 매번 바뀌기 때문에, IP를 통해 파드에 요청을 전달하기란 쉽지 않습니다.

쿠버네티스는 파드 IP가 매번 바뀌는데서 오는 어려움을 해결하기 위해 오브젝트를 통해 고정적으로 파드에 접근할 수 있도록 하는 방법을 제공합니다. 그리고 서비스로 들어온 요청이 파드에 실제로 접근할 수 있는 방법을 관리합니다. 이때 이 관리를 담당하는 컴포넌트가 kube-proxy입니다. 즉, 파드의 IP는 매번 변하지만 kube-proxy가 이 파드에 접근할 수 있는 방법을 그때마다 관리하고 갱신하며, 서비스 오브젝트는 이 정보를 사용하여 파드가 외부에서 접근할 수 있는 경로를 제공합니다. 쿠버네티스의 네트워크 원리는 매우 복잡하기 때문에 이 부분에 대해서는 추후 좀 더 자세히 다뤄볼게요.

자금까지 쿠버네티스의 컴포넌트에 대해 살펴봤습니다. 사실 쿠버네티스의 컴포넌트를 잘 아는 것은 쿠버네티스 전문가가 되기 위한 핵심 요소라고 할 만큼 까다로운 부분이라 말해도 과언이 아닙니다. 비유를 통해 최대한 쉽게 설명해 봤는데 이해하시는 데 도움이 되었을까요? 다음 편에서는 쿠버네티스의 실제 활용과 관계되는 각종 오브젝트에 대해 알아보겠습니다.

출처: 컨테이너 인프라 환경 구축을 위한 쿠버네티스/도커 (조훈, 심근우, 문성주 저)

+ '컨테이너 인프라 환경 구축을 위한 쿠버네티스/도커' 도서를 공저한 심근우 프로 인터뷰
+ 쿠버네티스 알아보기 1편: 쿠버네티스와 컨테이너, 도커에 대한 기본 개념
+ 쿠버네티스 알아보기 2편: 쿠버네티스를 만나는 여러 가지 방법



삼성SDS 소셜크리에이터 심근우 프로

이 글이 좋으셨다면 구독&좋아요

여러분의 “구독”과 “좋아요”는
저자에게 큰 힘이 됩니다.

subscribe