서론
쿠버네티스 클러스터에는 마스터 노드와 워커 노드가 있다. 이들이 어떻게 다른지 알아보자.
쿠버네티스 클러스터 환경에서 노드들이 어떻게 스스로 복구(self-healing)하고 관리(self-managed)되는지 알아보자.
1. 워커 프로세스(Worker processes)
쿠버네티스 클러스터에는 실질적인 일을 하는 워커 노드가 있다. 워커 노드는 쿠버네티스의 기본 구성요소인 파드 여러 개를 가질 수 있다. 위 그림의 Node1은 컨테이너로 이루어진 2개의 파드를 가지고 있다.
쿠버네티스는 하나의 노드에 3개의 프로세스를 필요로 한다. 프로세스는 모든 노드에 반드시 설치되어야 하며 그들을 스케줄링, 관리 하는데 반드시 필요하다.
첫 번째 프로세스는 노드의 컨테이너 런타임을 위해 수행되는 프로그램이다. 왜냐하면 애플리케이션 파드들은 내부적으로 컨테이너가 구동되기 때문이다.일반적으로 Docker를 사용하게 된다.
쿠버네티스 버전 1.24 부터 Docker 런타임에 대한 지원을 전면 중단했습니다.
쿠버네티스는 CRI(Container Runtime Interface) 를 사용해서 컨테이너를 관리하고 있습니다.
하지만 도커는 쿠버네티스보다 먼저 만들어졌고 서로 통합되도록 설계되지 않았으며 CRI 를 지원하지 않습니다.
지금까지 쿠버네티스에서 도커 런타임을 지원할 수 있었던 이유는 dockershim 이라는 도커 전용 브리지 서비스를 통해서 docker api와 CRI 의 변환을 수행했기 때문입니다.
이러한 dockershim 기능이 유지보수 문제와 쿠버네티스에 필요없는 기능이 많다는 이유로 중단되면서 docker 런타임은 앞으로 쿠버네티스에서 사용이 불가능하게 되었습니다.
사실 docker 이미지를 빌드하고 사용할 때 대부분 OCI 표준을 준수하여 이미지를 만들기 때문에 도커 런타임 중단과는 별개로 도커 이미지를 문제없이 사용할 수 있습니다.
그 대체제로 containerd, CRI-O 가 있습니다.
(https://www.openmaru.io/쿠버네티스-와-도커/)
두 번째 프로세스는 파드와 노드를 스케줄링하는 kubelet 이다. kubelet은 컨테이너 런타임과 노드간의 인터페이스 역할을 수행한다. 파드 내부의 컨테이너 구동에 관한 관리 역할을 하고, 노드가 컨테이너를 위해 할당할 자원(CPU, RAM)등을 결정해 준다.
세 번째 프로세스는 외부의 요청을 알맞은 서비스에서 파드로 전달(forwarding)해주는 Kube proxy가 있다.
Kube proxy는 서비스 및 파드간의 통신을 적은 오버헤드로 수행할 수 있도록 지원해 준다.
예를 들어 my-app 파드에서 DB-service로 데이터를 요청한 경우를 보자.
DB는 2개의 Replica를 가지고 서로 다른 노드에 분산되어 있다. 하나는 요청을 보낸 my-app과 동일한 노드에 있고 하나는 다른 노드에 존재한다. 만약 요청이 DB-service로 들어온다면 service는 일반적으로 임의의 파드로 요청을 전달해 줄 것이다. 하지만 Kube proxy는 같은 노드에 요청을 처리할 수 있는 파드가 있다면, 서비스가 좀 더 오버헤드가 적은 파드에게 요청을 전달할 수 있도록 도와주는 역할을 한다.
그렇다면 개발자는 어떻게 클러스터와 소통을 할까?
파드를 어떤 노드에 배포할 것인지(Schedule Pod), 모니터링은 어떻게 할 것인지, 파드가 파괴될 경우 re-schedule/re-start 는 어떤 방식으로 할 것인지, 새로운 노드가 생길 경우 클러스터에 어떻게 입장시킬 것인지 등을 정해야 할 것이다.
이 모든 일은 마스터 노드라고 불리는 노드가 수행하게 된다.
2. 마스터 프로세스(Master processes)
마스터 노드는 클러스터 및 워커 노드의 상태를 관리하는데 총 4개의 프로세스가 필요하다.
첫 번째 프로세스는 API server 이다. 쿠버네티스 클러스터에서 새로운 애플리케이션을 배포하고 싶을 때, 개발자는 쿠버네티스의 api server 를 사용해 kubelet같은 command line tool을 사용할 수 있다. 즉, api server는 클러스터 gateway의 역할을 수행한다. 모든 요청 및 쿼리를 처음으로 받아들이기 때문에 gateway가 될 수 있는 것이다. 그리고 인증 및 인가받은 사용자만 클러스터에 출입할 수 있게 해주는 문지기 역할을 할 수 있다.
이는 파드의 스케줄링, 애플리케이션의 배포, 새로운 서비스 생성 같은 쿠버네티스 구성요소에 관한 작업을 할 때는 항상 마스터 노드의 api server를 거쳐서 유효성을 검사 한다는 것이다.
요청을 받는 entrypoint가 하나이므로 보안에 좋은 구조를 가지게 된다.
두 번째 프로세스는 Scheduler 이다. 개발자가 api server에게 파드의 스케줄링에 관한 요청을 보내면, 요청을 scheduler 프로세스로 전달 되고, scheduler는 파드를 워커 노드 중 하나로 보내 애플리케이션을 실행시킨다. 파드를 노드로 보내는 과정은 랜덤으로 보내지 않고, 특정 알고리즘(특정 노드의 CPU 사용량이 많으면 다른 노드로 파드를 보낸다)에 의해 결정된 노드에게 보낸다.
중요한 점은 scheduler는 새로 만들어진 파드의 스케줄링만을 결정한다는 점이다. 새로운 파드가 워커 노드에게 전달 되면, 워커 노드의 kubelet이 컨테이너를 만들고 구동시키게 된다.
세 번째 프로세스는 Controller Manager 이다. 파드가 고장나거나 제대로 동작을 하지 못한다면 빠르게 파드를 교체하거나 재시작을 해야할 것이다. Controller manager(이하 CM)는 파드가 파괴되는 등의 클러스터 상태 변화를 감지하는 역할을 한다. CM이 상태 변화를 감지하면 최대한 빠르게 회복하기 위해서 scheduler에게 파드를 재조정하라는 요청을 보낸다. 그리고 scheduler는 파드를 노드에 배정하는 위와 동일한 사이클을 수행하게 된다.
네 번째 프로세스는 etcd 라고 불리는 클러스터의 상태를 저장하는 key-value 저장소이다. etcd는 클러스터의 두뇌라고 비유할 수 있다. 새로운 파드가 스케줄링 되고, 파드가 파괴되는 등의 모든 상태 변화를 etcd에 저장하고 업데이트 하기 때문이다. 그리고 etcd가 두뇌라고 불리는 가장 중요한 이유는 scheduler, controller manager가 수행되는 매커니즘이 모두 etcd의 데이터를 바탕으로 한 것이기 때문이다.
scheduler가 파드를 노드에 배정할 때 어떻게 노드의 가용 자원을 알 수 있었을까?
controller manager는 클러스터의 상태 변화(파드 파괴, kubelet의 파드 restart)를 어떻게 감지했을까?
개발자가 api server로 클러스터의 상태를 알고 싶은 쿼리를 날렸을 때, api server를 정보를 어디서 가져오는 걸까?
모두 etcd에 있는 정보를 바탕으로 할 수 있었던 작업이다.
당연히 개별 애플리케이션 데이터는 저장되지 않는다. 오직 클러스터에 관한 정보만이 저장된다.
마스터 노드도 워커 노드와 동일하게 Multiple Node로 구성될 수 있다.
개발자의 요청은 api server에서 로드밸런싱 될 것이고, 클러스터 정보들은 두 개의 etcd에 분산되어 저장될 것이다.
클러스터 Set-Up 예제
마스터 노드는 일반적으로 적은 자원을 사용한다. 반면에 워커노드는 실제로 애플리케이션이 구동되는 서버이므로 더 많은 자원이 사용된다. 그리고 애플리케이션의 복잡도가 높아지고 더 많은 자원을 요구하면 서버를 증설해야 한다.
이미 존재하는 쿠버네티스 클러스터에 새로운 마스터/워커 노드를 추가하는 과정
bare server(하드웨어 상에 어떤 소프트웨어도 설치되어 있지 않은 상태)가 존재해야 한다.
마스터/워커 노드에 맞는 프로세스들을 설치한다.
새로운 노드를 클러스터에 추가한다.
워커 노드를 추가하기 위해서는 bare server에 kebelet, kube proxy, container runtime을 설치한다. 그리고 쿠버네티스 클러스터에 추가하면 된다. 동일한 과정으로 쿠버네티스 클러스터의 크기를 무한하게 늘릴 수 있게 된다.
출처 : https://www.youtube.com/watch?v=X48VuDVv0do
번역 : 나
Chapter : K8s Architecture
'DevOps > Kubernetes' 카테고리의 다른 글
[kubernetes] #5 핵심 kubectl 명령어 (0) | 2022.03.01 |
---|---|
[kubernetes] #4 Minikube와 kubectl - 클러스터 구축 (0) | 2022.02.28 |
[Kubernetes] #2 핵심 쿠버네티스 컴포넌트 (0) | 2022.02.27 |
[Kubernetes] #1 쿠버네티스란? (0) | 2022.02.26 |
[K8S] 쿠버네티스 파드의 생명주기 (0) | 2022.01.18 |