새소식

Recent Study/udemy - CKA with Practice Tests

Section 10 : Design and Install a k8s cluster

  • -

Cofigure high availability

클러스터의 마스터 노드가 없어진다면 어떻게 될까요? workers가 작동하고 있다면, 컨테이너가 살아있는 동안 어플리케이션은 작동합니다. 사용자는 실패할 때까지 앱에 접속할 수 있어요. 만약 컨테이너나 pod가 문제가 생겼다면? pod는 ReplicaSet에서 생성되었고, master의 replication Controller가 작업자에게 새 Pod의 Load를 지시합니다. 하지만 마스터는 사용할 수 없죠.

 

pod의 재생성이 불가하고, node schedule도 설정할 수 없습니다. kube-apiserver도 사용이 불가하여, 관리 목적으로 kube

 control tool이나 API를 통해 외부적으로 클러스터에 액세스할 수 없습니다. 그래서 프로덕션 환경에서는 고가용성 구성에서 다중 마스터 노드를 고려해야 하죠.

 

 

고가용성 구조클러스터 내 모든 components에 대해 중복을 갖는 것이죠. 마스터 노드는 컨트롤 플레인 컴포넌트를 호스팅합니다. API, Controller Manager, ETCD 등을 포함해서요. 추가 마스터 노드를 설치하면, 새로운 마스터에서도 같은 구성 요소가 실행됩니다. 어떻게 작동할까요? 같은 컴포넌트의 여러 인스턴스를 실행하면 같은 일을 2번 할까요? 일을 분담하나요? 이는 상황마다 다르죠.

 

 

API 서버는 요청을 수신하고 프로세싱하고 클러스터에 관한 정보를 제공할 책임이 있습니다. 한 번에 하나씩 요청에 따라 작업됩니다. 클러스터 노드 전체의 API 서버가 액티브 모드에서 동시에 실행되는 것입니다. 지금까지는 kubectl 유틸리티가 API 서버와 교신해 작업을 완료했습니다. 그 kubectl 유틸리티를 마스터 노드의 포트 6443로 보내도록 했습니다. API 서버가 listening하는 곳입니다. 이건 kube config 파일에서 구성되어 있습니다.

 

마스터가 둘인데 kbuectl2는 어디 있죠? 어느 쪽이든 요청할 수 있지만 양쪽 다 같은 요청을 해선 안 됩니다. 그래서 API 서버 간의 트래픽을 분할하는 마스터 노드 앞에 일종의 로드밸런서를 갖는 게 좋습니다. 그런 다음 kubectl 유틸리티가 로드밸런서를 가리키게 합니다. 이 목적으로 Nginx나 HA 프록시 또는 다른 로드밸런서를 사용할 수 있습니다.

 

 

Controller Manager 프로세스가 구성되면 --leader-elect 옵션을 지정할 수 있습니다. default로 True으로 설정됩니다. 컨트롤러 매니저 프로세스가 시작되면 kube-controller-manager endpoint이라는 이름의 endpoint 오브젝트에 lease나 lock를 얻으려고 합니다. 어떤 프로세스든 해당 정보와 함께 endpoint를 업데이트하는 쪽이 lease를 획득해 둘 중 하나가 활성화되고, 다른 한 명은 passive가 됩니다.

 

default 설정 15초인 --leader-elect-lease-duration 옵션을 이용하여 지정된 lease(임대) 기간을 위한 lock을 설정합니다. active 프로세스가 10초마다 lease를 갱신하는데, 이는 옵션 --leader-elect-renew-deadline 의 default값입니다. 두 과정 모두 leader elect retry period 옵션에서 정한 2초마다 리더가 되려고 노력합니다. 그래야 첫 번째 마스터가 실패해도 두 번째 마스터가 lease를 획득해 리더가 될 수 있습니다. 스케쥴러는 유사한 접근법을 따르고 커맨드라인 옵션은 동일합니다.

 

 

위는 강의를 진행하며 보아온 아키텍처입니다. etcd는 쿠버네티스 마스터 노드의 일부이며, 이를 stacked control plane nodes topology라고 합니다. 설정, 관리가 더 쉽고, 노드도 더 적게 요구하죠. 하지만 하나의 노드가 다운되면 etcd, control plane 인스턴스는 둘다 없어지고, 피해를 입게 됩니다.

 

 

또다른 형태는 etcd가 컨트롤 플레인 노드에서 분리되어 그 자체 서버 세트에서 실행되는 것입니다. topology with external etcd servers입니다. 이전 토폴로지와 비교하면 이것은 덜 위험합니다. 실패한 controlplane이 etcd 클러스터와 저장된 데이터에 영향을 주지 않습니다. 하지만 셋업은 더 어렵고 외부 노드에 대한 서버 수도 두 배가 필요합니다. API 서버는 etcd 서버에 통신하는 유일한 컴포넌트임을 기억하세요.

 

API 서비스 config 옵션을 보면 etcd 서버 위치를 지정하는 옵션 집합이 있습니다. 토폴로지에 상관없이 ETCD 서버 구성 장소가 동일 서버든 분리된 서버든 궁극적으로 API 서버가 etcd 서버의 올바른 주소를 가리키도록 해야만 합니다. etcd는 분산 시스템이란 걸 기억하세요. 따라서 API 서버나, 통신하고자 하는 다른 컴포넌트는 그 인스턴스에서 해당 etcd서버에 도달할 수 있습니다. 이용 가능한 etcd 서버 인스턴스를 통해 데이터를 읽고 쓸 수 있습니다. 이것이 kupe-apiserver configuration에서 etcd 서버 리스트를 명시하는 이유입니다.

 

 

ETCD In HA

ETCD는 분산되고 신뢰할 수 있는 key-value store로 간단하고 안전하며, 빠릅니다.

 

전통적인 방법으로는 아래와 같은 테이블에 저장했습니다.

 

 

key-value stroe는 문서나 페이지의 형태로 정보를 저장하빈다. 각 개인은 문서를 하나 가지고 있고, 그 개인데 관한 모든 정보가 해당 파일에 저장되죠. 이 파일들은 어떤 형식이나 구조로든 존재할 수 있습니다. 한 파일의 변화는 다른 파일에 영향을 주지 않으며, 위 경우 근로 개인은 급여 필드가 있는 파일을 가질 수 있습니다. 단순한 키와 값을 저장하고 회수할 수 있는 반면에, 데이터가 복잡해지면 일반적으로 JSON, YAML 같은 데이터 포맷을 사용하게 됩니다. 이것이 ETCD입니다.

 

 

ETCD는 분산되어있다는 뜻이 있었습니다. 단일 서버에 etcd가 있지만, 데이터베이스라 중요한 정보도 저장이 가능합니다. 따라서 여러 서버에 걸쳐 데이터 저장소를 가질 수 있습니다. 아래 3개의 서버에 모두 etcd가 실행중이며, 데이터베이스의 동일한 복사본을 유지하고 있습니다. 하나를 잃어도 데이터는 2개가 남습니다.

 

 

모든 노드의 데이터가 일관적인지 어떻게 확인하죠? 어떤 인스턴스에서든 쓰고 데이터를 읽을 수 있습니다. ETCD는 데이터의 동일한 복사본이 모든 인스턴스에서 동시에 사용 가능하도록 보장합니다. 어떻게 가능할까요? 읽는 건 쉽습니다. 같은 데이터가 모든 노드에서 사용 가능하기 때문에, 어떤 노드에서든 쉽게 읽을 수 있습니다. 하지만 쓰기는 다릅니다. 2개의 쓰기 요청이 2개의 다른 인스턴스에서 온다면요? 어떤 것이 통과할까요?

 

예를 들어, 한 쪽 끝에는 John 다른 쪽 끝에는 Joe라는 이름을 쓰도록 했습니다. 물론 두 노드에 두 개의 다른 데이터를 둘 순 없습니다. ETCD는 어떤 인스턴스에도 쓸 수 있다고 했는데 100% 맞는 건 아니었습니다. ETCD는 노드마다 쓰기를 처리하지 않습니다. 대신 한 인스턴스만이 쓰기를 처리합니다.

 

 

내부에서 두 노드가 선출하는 리더는 하나 입니다. 전체 인스턴스에서 노드 하나는 리더가 되고 다른 노드는 팔로워가 됩니다. 쓰기가 리더 노드를 통해 들어오면 리더가 쓰기를 처리하고, 리더가 다른 노드들에게 데이터 복사본을 보내도록 합니다. 팔로워 노드를 통해 쓰기가 들어오면 팔로워 노드가 리더에게 쓰기를 전달하고 리더는 쓰기를 처리합니다. 쓰기가 처리되면 리더는 쓰기의 복사본이 클러스터의 다른 인스턴스로 분산되도록 보장합니다. 따라서 집단의 다른 멤버들로부터 리더가 동의를 얻어야만 완성된 것으로 간주됩니다.

 

 

Leader election - RAFT

그럼 리더 선출은 어떻게 할까요? 쓴 글이 모두에게 퍼지는 걸 어떻게 보장할까요? raft 프로토콜을 이용해 distributed consensus을 구현합니다. 세 노드 클러스터에서 어떻게 작동하는지 보겠습니다.

 

클러스터가 설정될 때, 3개의 노드에는 Leader가 선출되지 않았습니다. raft 알고리즘은 무작위로 타이머를 맞춰 신호를 보냅니다. 예를 들어 3명의 매니저에게 무작위 타이머가 작동하죠 타이머가 먼저 완료된 매니저가 다른 노드에게 리더가 될 권한을 투표합니다. 다른 매니저들의 투표로 요청에 대한 답변을 받으면 그 노드가 리더 역할을 맡습니다. 이제 리더로 선출됐으니 다른 마스터들에게 주기적으로 정기적으로 공지를 보내 자신이 계속 리더의 역할을 하고 있다고 알립니다.

 

다른 노드들이 리더로부터 어떤 시점에 알림을 받지 못할 수 있습니다. 리더가 다운되었거나 네트워크 연결이 끊겼기 때문일 수 있습니다. 그러면 노드들 사이에서 재선 프로세스를 시작합니다. 새 리더가 선출되는 것입니다. 이전 예제로 돌아가겠습니다. 쓰기가 들어오면 리더에 의해 처리되고, 클러스터 내 다른 노드로 복제됩니다. 쓰기는 클러스터의 다른 인스턴스로 복제됐을 때만 완료된 것으로 간주됩니다. ETCD 클러스터는 고가용성이라고 했습니다. 즉, 노드를 잃어도 기능은 할 것입니다.

 

 

가령, 새 쓰기가 들어왔는데 노드 하나가 응답하지 않는다고 칩시다. 따라서 리더가 클러스터에서 두 노드에만 쓸 수 있습니다. 이 때 다 쓴 건가요? 아니면 세 번째 노드가 올라올 때까지 기다려야 하나요? 아니면 실패한 걸까요? 이 때는 클러스터 내 대부분의 노드에 쓰기가 되었다면 완료로 간주합니다. 가령, 노드가 3개면 대다수는 2개 입니다. 데이터가 두 개의 노드에 작성될 수 있다면 쓰기 완료로 간주됩니다. 세 번째 노드가 온라인이 되면, 데이터도 거기에 복사됩니다.

 

 

여기서 대다수는 무엇인가요? quorum이라고 하는 게 더 적절하겠네요. quorum클러스터가 제대로 기능하고 성공적으로 쓰기 위해 반드시 필요한 최소의 노드 수입니다. N이 3이면 2인 것입니다. 어떤 노드든 쿼럼은 노드를 2로 나누고 1을 더한 수입니다.

 

여기 1부터 7까지 클러스터의 쿼럼을 보여주는 표가 있습니다. 인스턴스1의 쿼럼은 1입니다. 그 말은 단일 노드 클러스터라면 이런 건 프로토콜이 적용이 안 된다는 것입니다. 그 노드를 잃으면 모든 게 사라집니다. 두 개를 보고 같은 공식을 적용하면 쿼럼은 2입니다. 클러스터에 인스턴스가 2개라도 대다수는 여전히 2입니다. 하나가 실패하면 쿼럼이 없어 쓰기도 할 수 없습니다. 인스턴스가 2개인 건 1개인 것과 같습니다. 쿼럼이 충족될 수 없는 어떤 실질적 가치도 제공하지 않습니다. 그래서 추가적인 클러스터에 최소 3개의 인스턴스를 갖도록 권장하는 것입니다. 그렇게 하면 적어도 한 노드의 결함 허용 내역을 제공합니다. 하나를 잃어도 쿼럼을 가질 수 있고 클러스터는 계속 기능할 것입니다.

 

 

첫 번째 칼럼에서 두 번째 칼럼을 뺀 것을 fault tolerance 라고 합니다. 클러스터가 작동하는 동안 손실할 수 있는 노드의 수입니다. 노드가 1개에서 7개가 있습니다. 1개과 2개의 상황은 제외하고 3개부터 7개까지 뭘 고려해야 할까요? 보시다시피 3개와 4개의 fault tolerance는 1로 같습니다. 5개와 6개의 fault tolerance는 2로 같아요. 마스터 노드의 수를 정할 때는 테이블에서 강조했듯이 홀수를 선택해야 합니다. 3개, 5개, 7개처럼요. 노드 클러스터가 6개라고 치겠습니다. 예를 들어 네트워크의 교란으로 인해 망이 실패해 네트워크가 분할되었습니다. 1번 노드에는 4개, 다른 노드에는 2개가 있습니다. 이 경우 4개의 노드를 가진 그룹은 쿼럼이 있고 정상적으로 작동합니다. 하지만 네트워크가 다른 방법으로 파티션을 가지면 노드가 둘 사이에 동등하게 분배됩니다. 각 그룹은 3개의 노드만 가지게 되죠. 그런데 원래 노드가 6개였기 때문에 클러스터가 계속 살려면 쿼럼이 4개여야 합니다.

 

 

하지만 여기 그룹을 보시면 이 그룹들은 쿼럼에 부합하는 관리자가 네 명이 없습니다 따라서 실패한 클러스터로 끝나게 됩니다. 따라서 노드의 수가 짝수일 경우, 네트워크 세분화 중 클러스터 결함이 발생할 가능성이 있습니다. 원래 매니저 수가 홀수였다면 (예를 들어 7명) 네트워크 세그먼트화 이후 한 세그먼트화 네트워크에서 4명 다른 세그먼트화 네트워크에서 3명이 됩니다. 그래서 우리 클러스터는 여전히 관리자가 4명인 그룹에 살아있습니다. 4명의 쿼럼을 충족하면서요. 네트워크 세그먼트가 어떻든, 홀수 노드의 네트워크 세그먼트화 경우 클러스터가 생존할 확률이 더 높습니다. 따라서 짝수보다 홀수 노드가 선호됩니다. 5개가 6개보다 낫고, 노드가 5개 이상이면 충분합니다. 5개는 fault tolerance이 충분하니까요.

 

 

설계로 돌아가서 클러스터에 노드가 몇 개 있어야 하죠? HA 환경에서 보다시피 인스턴스 한두 개를 갖는 건 말이 안 됩니다. 노드 하나를 잃으면 쿼럼 없이 남겨지게 되고 클러스터가 비기능 상태가 됩니다. 따라서 HA에서 필요한 최소 노드는 3개입니다. 짝수보다 홀수가 좋은 이유도 얘기했습니다. 같은 수의 인스턴스를 갖는 것은 특정 네트워크 파티션 시나리오에서 쿼럼 없이 클러스터를 떠날 수 있습니다. 짝수 노드는 범위를 벗어납니다.

 

그럼 이제 3, 5, 7이나 그 위의 홀수만 남았습니다. 3개도 좋지만 내결함성(fault tolerance)이 높은 걸 원한다면 5개가 더 좋아요. 그 이상은 불필요합니다. 여러분의 환경, fault tolerance, 요구 사항,그리고 감당할 수 있는 비용을 고려할 때 이 목록에서 숫자 하나를 골라야 합니다. 우리 경우엔 3입니다.

 

 

지금 우리 설계는 어떤가요? HA는 내결함성을 위해 필요한 최소 노드 수가 3개입니다. 마스터 노드가 3개면 좋겠지만 노트북 용량에 한계가 있어서 2개로 하겠습니다. 하지만 다른 환경에서 셋업을 배포하고 충분한 용량을 확보한다면 3개를 사용하세요. 또한 스택된 topology를 선택했습니다. 마스터 노드 자체에 여러 서버들이 있는 형태입니다.

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.