Kubernates 추가 정리본

김도비·2022년 10월 23일
0

Kubernates

목록 보기
3/4

Kubernetes의 Input은 Action이 아닌 Desired State
Kuberenetes 공식 홈페이지의 다큐멘테이션을 읽으면 유독 Desired state라는 단어가 많이 등장한다.

이는 Kubernetes를 이해하는 데에 있어서 핵심적인 부분이다.

Docker에서 컨테이너를 띄우는 명령어는

docker run <image>

이다. 이 커맨드는 docker engine에게 “이 이미지를 베이스로 컨테이너를 하나 띄워주세요”라는 한 가지 action을 지시하는 것이다.

반면, Kubernetes는 그렇지 않다. 우리는 Kubernetes에게 “어플리케이션 배포 상황을 다음과 같이 유지해주세요”라는 Desired state를 넘겨준다. 그러면 Kubernetes는 current state를 지속적으로 모니터링하고, current state와 desired state 사이에 다른 부분이 있을 경우 이를 일치하도록 만든다. 이 미묘한 차이를 이해하는 것이 Kubernetes를 쉽게 이해할 수 있는 핵심이다.

이제 Kubernetes가 Desired state를 유지하기 위해 내부적으로 어떻게 동작하는지를 알아보고, 이를 Kubernetes의 각 컴포넌트와 workload와 연결보려한다.

설명에 앞서, Kubernetes는 꽤나 많은 컴포넌트로 이루어져있다. 각 컴포넌트는 최소한의 책임을 가지고 각자 자기가 할 일만 수행하며, 컴포넌트들이 조합되었을 때 비로소 Kubernetes가 하나의 시스템으로 작동한다.

우리가 Kubernetes를 통해서 한 어플리케이션을 배포하는 상황을 가정해보자. 이 어플리케이션을 구운 이미지는 이미지 A이다. 그리고 우리는 이 어플리케이션을 총 4대 띄우고 싶다.

우선, 위에서 Kubernetes는 Desired state를 input으로 받는다고 했다. 일반적으로 유저가 정의하는 Desired state는 Deployment Object이다.

예를 들어, 유저는 kubectl을 통해 Kubernetes Master node에 노출된 api server 컴포넌트에 “이미지 A의 컨테이너가 하나 있는 Pod을 4개 띄운 상태로 유지해주세요”라는 Deployment Object를 만들라고 명령한다. 그러면 Api server는 http 요청을 받고 etcd라는 저장소에 해당 Deployment object의 정보를 저장하기만 한다.

Deployment Object를 저장하면, Controller Manager라는 컴포넌트가 이를 감지하고 이에 대응하는 ReplicaSet object를 생성한다. 위 상황에서는 “이미지 A에 대해 4개의 컨테이너 복사본을 유지한다”는 ReplicaSet object를 하나 만들라고 api server에게 명령할 것이다. 그러면 api server는 이를 etcd에 저장(생성)한다.

ReplicaSet Object 역시 Controller의 일종이기 때문에, Controller Manager가 ReplicaSet Object의 생성을 감지한다. 그러면 Controller Manager는 ReplicaSet Object에 적힌 대로 이미지 A를 기반으로 Pod을 4개 생성한다. 여기서 중요한 것은 Controller Manager가 Pod을 실제 Node에 띄우지는 않고 단지 생성만 한다는 것이다.

이렇게 아무데도 띄워져 있지 않은 Pod을 어떤 Node에 띄울지 결정하는 것은 Scheduler의 책임이다. Scheduler는 실제 물리적인 서버에 띄워져 있지 않은 Pod을 감지하여 적절한 서버에 연결시켜주는 역할’만’ 한다. 심지어 띄워주지도 않고 어떤 Node에 띄워져야 하는지만 결정해서 etcd에 저장한다.

Scheduler가 Pod과 Node를 연결한 정보를 etcd에 적으면, 이 정보를 기반으로 실제 Pod을 Node에 띄우는 것은 각 Node에서 실행되고 있는 kubelet이라는 프로그램의 역할이다. kubelet은 자신의 Node에 Pod이 새로 할당되면 docker 같은 Container Runtime Interface(CRI)에 실제로 컨테이너를 띄우는 명령을 날린다.

모든 정보는 etcd에 저장되고 api server를 통해 각 컴포넌트에 노출된다.
Kubernetes의 컴포넌트들은 전부 api server를 바라보며 변화를 감지하고 있다.
그러다가 자신의 책임인 변화가 감지되면 자신이 해야 할 일만 처리한다.
그리고 각 컴포넌트의 책임은 다음과 같다.

api server: 유저나 다른 컴포넌트의 명령을 받아 object를 관리(CRUD)
Controller Manager: 새로운 Controller를 감지하고 이를 처리
Deployment Controller → ReplicaSet Controller
ReplicaSet Controller → new unbound Pods
Scheduler: unbound Pods를 감지하고 이를 처리
unbound Pods → bound Pods
kubelet: bound Pods를 감지하고 실제로 Pod을 띄움
이러한 상태 감지와 이에 대응되는 action은 끊임없이 이루어진다. Kubernetes는 지속적으로 각종 current state를 측정하여 저장한다. 그리고 각 컴포넌트는 자신이 바라보는 Current state와 Desired state가 일치하도록 최선을 다한다.

References
https://suhwan.dev/

profile
모든 걸 기록하자

0개의 댓글