Computing

Kubernetes 고가용성(HA) (1): 고가용성과 Kube Master의 고가용성 본문

Cloud/Kubernetes

Kubernetes 고가용성(HA) (1): 고가용성과 Kube Master의 고가용성

jhson989 2023. 1. 4. 22:21

고가용성 High Availability

고가용성(HA, High Availability)라는 말이 생소할 수 있는데 가용성이 높다, 즉 높은 확률로 사용할 수 있다는 말이다. 애플리케이션 서비스를 생각해보자. 이 서비스의 DB가 고장난다면 더 이상 애플리케이션을 사용할 수 없다. 이런 저런 방법으로 DB가 절대 고장나지 않도록 한다면 더이상 DB에 의해 서비스 이용이 불가능해지는 상황이 사라질 것이다. 즉 이 서비스는 높은 확률로 사용가능한(고장나지 않는), 고가용성을 가지는 것이다.

 

좀 더 정확한 정의로 가용성이란 서버, 네트워크 등의 시스템이 정상적으로 사용 가능한 정도를 말하는 것으로 가동률과 비슷한 의미[1]이다. 가용성은 시스템이 설치된 이후의 전체 시간 중에 정상 작동한 시간의 비율이다. 시스템이 설치된 전체 시간 중에는 정상 작동하는 시간도 있을 것이고, 혹은 고장나서 수리하는 시간도 있을 것이다. 고가용성, 즉 가용성이 높다는 것은 이 시스템이 정상 작동한 시간이 많다는 것이고, 다른 말로 고장나서 작동하지 않는 시간이 적다는 의미이다.

 

고가용성은 애플리케이션 서비스에 매우 중요한 요소이고, 애플리케이션을 안정적으로 실행시켜준다고 자랑하는 클라우드 시스템에는 특히 중요한 성능 평가 척도일 것이다. 애플리케이션 서비스를 운영하는데 DB가 고장나, 컴퓨터가 고장나, 네트워크가 고장나 등 다양한 이유에 의해서 애플리케이션 서비스가 작동하지 않는다고 한다면 매우 짜증날 것이다. 클라우드 시스템은 애플리케이션에 고가용성을 보장할 수 있다. 이를 위해 클라우드 시스템은 다양한 기법이 적용된다.

 

 

 

Kubernetes의 HA

쿠버네티스 경우, deployment와 같은 워크로드 리소스를 이용하여 쿠버네티스 내에 선언적으로 워크로드를 정의해둔다. 다양한 이유에 의해 애플리케이션(워크로드)가 고장날 경우, 해당 애플리케이션을 종료하고 자동으로 애플리케이션을 재실행한다. 애플리케이션이 실행되고 있던 컴퓨터의 문제라면, 쿠버네티스 클러스터에 포함된 다른 컴퓨터에서 애플리케이션을 자동으로 재실행시킨다. 컴퓨터의 고장에 의해 서비스가 중단되는 시간이 최소화되는 것이다. (원래라면 해당 컴퓨터를 고치는 시간동안 서비스가 중단될 것인데, 아예 다른 컴퓨터에서 서비스를 실행시키므로 약간의 중단만이 발생한다.)

 

쿠버네티스 클러스터가 잘 운영된다고 가정한다면, 쿠버네티스 내에서 실행되고 있는 애플리케이션은 문제가 발생하더라도 자동으로 재실행되어 높은 고가용성을 보장받을 수 있다. 쿠버네티스를 사용하는 사용자 입장에서는 자신의 서비스의 고가용성이 보장된 것이다. 다만, 쿠버네티스 클러스터 자체가 잘 운영되어야 한다는 가정이 필요하다. 애플리케이션이 작동하는 쿠버네티스 시스템 자체가 고장나 버린다면 애플리케이션 또한 고장날 수 밖에 없다.

 

Fig 1. Kubernetes Cluster [2]

 

Fig 1.은 쿠버네티스 클러스터 시스템의 간략한 모습을 나타낸 것이다. Master(Control Plane)은 쿠버네티스 시스템 전체를 관리하는 서버이고, 2개의 Node(Worker)는 애플리케이션(Pod)가 실제 실행되는 서버이다. Node 하나가 갑자기 고장난다면 쿠버네티스는 해당 Node에서 실행되고 있던 Pod들을 다른 Node에서 재실행시킨다. Worker Node가 무한하다면 Pod는 무한히 재실행될 수 있을 것이다. 이러한 전체 과정, 노드의 상태를 계속 체크하고 문제가 발생한다면 정상 노드에서 Pod를 재실행시키는 과정을 담당하는 것이 Master이다.

 

문제는 위 시스템에서는 Master가 고장난다면 쿠버네티스 클러스터는 더이상 작동할 수 없다는 것이다. 쿠버네티스 시스템 자체의 고가용성을 생각해야 할 때가 온 것이다. 이를 위해 쿠버네티스는 여러 Master들을 동시에 실행시키는 것으로 쿠버네티스 시스템 자체의 고가용성을 보장하였다.

 

 

 

Multiple Masters가 참여하는 Kubernetes Cluster System

Fig 2.는 쿠버네티스 시스템의 고가용성을 위해 3개의 Master(Contro Plane Node)들이 참여하는 쿠버네티스 클러스터의 모습을 보여준다.

 

Fig 2. Multiple Masters가 참여하는 Kernetes Cluster System [3]

 

Fig 1. 시스템과 Fig 2. 시스템의 차이는 클러스터에 참여하는 Master의 개수가 1개에서 3개로 늘어났다는 것과, Worker들과 Master들 사이에 load balancer가 추가되었다는 것이다. Master 3개는 앞으로 일을 나누어 처리할 것이다. 만약 하나의 Master가 고장나더라도 다른 2개의 Master가 살아있기에 쿠버네티스 클러스터는 정상 작동할 수 있다.

 

사용자와 Worker는 Master와 통신을 한다. 이때 Master의 IP 주소를 알아야 하는데, 3개의 Master 모두를 기억하고 있는 것은 매우 귀찮은 일이다. Master가 3개가 아니라, 5개 혹은 7개이면 외워야 하는 IP가 더욱 늘어난다. 또한 Master 하나가 고장난다면 다른 Master에게 다시 한번 더 통신을 요청해야 한다. 100명의 사용자가 Master 1과만 통신하고 Master 2, 3은 노는 경우도 발생할 수 있다. Master 2, 3이 놀고 있는 매우 비효율적인 상황인 것이다. 이를 해결하기 위해 load balancer가 존재한다.

 

Load balancer는 하나의 IP를 가지고 있는 물리적 혹은 가상의 장치이다. Load balancer는 자기에게 들어온 네트워크 트래픽을 등록된 서버들에게 룰에 따라(공평하게 등) 나눠준다. 이를 통해 사용자는 load balancer의 IP만을 이용해 모든 Master에 접근할 수 있다. 또한 Master들 중 하나가 고장나 통신이 되지 않는다면 자동으로 그 master를 제외해준다. Load balancer를 통해 사용자는 여러 Master들을 하나의 Master라고 생각하고 사용할 수 있게 된 것이다.

 

 

 

Multiple Masters 분산 처리 분석

Multiple Master가 어떻게 일을 분산하여 처리하는 지에 대해서 좀 더 깊이 있게 알아보자. 일단 Master가 어떤 역할을 수행하는 지 정리하였다. Fig 2.에서 보듯 Master는 api-server, controller-manager, scheduler, etcd로 구성된다.

 

api-server는 master에 명령을 내리는 API server로 사용자 혹은 Worker가 Master와 통신한다. 앞서 말했듯 Master가 쿠버네티스 클러스터 운영을 담당한다. 사용자가 Master에게 명령을 내리거나 혹은 Worker가 Master와 통신해야 할 경우가 있는데, 이때 api-server를 통해 공개된 API를 사용해 사용자 혹은 Worker는 Master와 통신을 한다. api-server를 통해 들어온 명령에 따라 Master는 작동한다. 다만 이것 자체로는 쿠버네티스 클러스터의 상태를 변화시키지 않는다. (api-server가 controller-manager에게 명령을 내려 상태를 변화시킨다.)

 

controller-manager는 쿠버네티스 클러스터 내에 등록된 다양한 리소스들을 관리하는 다앙햔 controller를 관리하는 오브젝트이다. Controller란 쿠버네티스 시스템의 상태를 지속적으로 확인하는 오브젝트로 문제가 발생할 경우 (ex, 원하는 상태가 아닐 경우, A pod가 3개 운영되어야 하는데 2개만 운영되는 경우 등) 이를 해결한다. 다양한 Controller들(Node controller-Worker들의 상태를 체크, Deployment controller-deployment로 정의된 상태가 제대로 지켜지는 지 확인, Job controller, Namespace controller, Endpoint controller, etc.)이 있는데 이들을 관리하는 것(정확히는 controller를 반복적으로 실행시키는 하나의 프로세스)이 controller-manager이다. controller-manager는 쿠버네티스 클러스터의 상태를 변화시킨다.

 

scheduler는 Pod를 실행시킬 Worker를 선택하는 프로세스이다. 현재 Workers의 상태를 파악하고, 어떤 Worker에 스케쥴해야할 Pod를 실행시킬 지를 결정한다. scheduler는 쿠버네티스 클러스터의 상태를 변화시킨다.

 

etcd는 쿠버네티스의 상태가 저장되는 분산 스토리지 시스템이다. Key-value를 이용해 저장되는 object storage로, 다양한 노드에서 분산되어 데이터를 저장할 수 있는 분산 시스템으로 설계되었다. 위 그림에서 etcd만이 stacked etcd cluster라는 큰 박스로 묶어져 있는 것을 볼 수 있는데, 그림처럼 여러 개의 etcd가 모여 하나의 etcd 역할을 수행하기(즉, 분산 시스템) 때문이다. 쿠버네티스의 모든 상태는 etcd에 저장되고, api-server 등이 쿠버네티스에서 정보를 얻고 싶으면 etcd로부터 정보를 얻는다. controller에 의해 상태가 업데이트될 때에도 그 업데이트는 etcd에 쓰여진다.

 

앞서 말했듯, 쿠버네티스는 여러 Master들을 동시에 실행시키는 것으로 쿠버네티스 시스템 자체의 고가용성을 보장하였다. 하지만 단순히 여러 Master들을 동시에 실행시키는 것은 문제를 발생시킨다. 철수가 Master 1에게 Deployment-A를 제거하라고 명령했다고 하자. 동시에 영희가 Master 2에게 Deployment-A를 업데이트 시켜라라고 명령하는 경우가 발생할 수 있다. 쿠버네티스 클러스터는 Deployment-A를 어떻게 처리해야 할까? 이처럼 쿠버네티스 클러스터의 상태를 변화시키는 명령은 안전을 위해 동시에 실행되면 안된다.

 

api-server는 stateless(클러스터 상태를 변화시키지 않는다)이기에 api-server 여러 개가 동시에 작동해도 된다. 하지만 controller-manager와 scheduler는 클러스터의 상태를 변화시키기에 여러 개가 동시에 작동하면 안된다. 따라서 쿠버네티스는 여러 master들이 동시에 참여하는 상황에서도 controller-manager와 scheduler는 리더 하나만을 선택한다. 그리고 나머지는 대기를 시켜놓고 리더 오브젝트만을 이용한다. 만약 리더가 고장나 응답하지 않는다면 새로운 리더 하나를 선출하여 그 리더를 대신 실행시킨다. etcd 자체는 애초에 분산 시스템으로 설계되었기에 여러 개가 동시에 작동하여도 된다.

 

 

이상으로 쿠버네티스 클러스터의 고가용성을 위한 Multiple Masters 배포 방법에 대해서 간략히 정리하였다. 다음 포스터에서는 간단하게 고가용성 쿠버네티스 클러스터 생성을 실습할 예정이다.

 

 

 

Reference

[1] https://ko.wikipedia.org/wiki/가용성

[2] https://www.suse.com/c/rancher_blog/understanding-the-kubernetes-node/

[3] https://kubernetes.io/ko/docs/setup/production-environment/tools/kubeadm/ha-topology/