조정된 리더 선출
조정된 리더 선출 (Coordinated Leader Election)
FEATURE STATE:
Kubernetes v1.33 [beta](기본적으로 비활성화)
Kubernetes 1.37에는 **조정된 리더 선출(coordinated leader election)**을 통해 컨트롤 플레인 컴포넌트가 결정론적으로(deterministically) 리더를 선택할 수 있게 하는 베타 기능이 있어요. 이는 클러스터 업그레이드 중에 Kubernetes 버전 스큐(version skew) 제약을 충족하는 데 유용합니다.
현재 유일한 내장 선택 전략은 OldestEmulationVersion으로, **에뮬레이션 버전(emulation version)**이 가장 낮은 리더를 우선하고, 그다음 바이너리 버전, 그다음 생성 타임스탬프 순으로 선호해요.
이 기능을 사용하려면 (또는 클러스터 관리자가) 클러스터의 모든 관련 컴포넌트에 대해 CoordinatedLeaderElection 기능 게이트를 활성화해야 합니다.
조정된 리더 선출 활성화 (Enabling coordinated leader election)
API 서버를 시작할 때 CoordinatedLeaderElection 기능 게이트가 활성화되어 있고, coordination.k8s.io/v1beta1 API 그룹이 활성화되어 있는지 확인하세요.
이것은 --feature-gates="CoordinatedLeaderElection=true" 와 --runtime-config="coordination.k8s.io/v1beta1=true" 플래그를 설정해서 수행할 수 있어요.
컴포넌트 구성 (Component configuration)
CoordinatedLeaderElection 기능 게이트를 활성화하고 coordination.k8s.io/v1beta1 API 그룹을 활성화했다면, 호환되는 컨트롤 플레인 컴포넌트들은 필요에 따라 자동으로 LeaseCandidate와 Lease API를 사용해 리더를 선출해요.
Kubernetes 1.37에서는 두 개의 컨트롤 플레인 컴포넌트(kube-controller-manager와 kube-scheduler)가 기능 게이트와 API 그룹이 활성화되면 자동으로 조정된 리더 선출을 사용합니다.
Kubernetes 컴포넌트의 리더 선택 (Leader selection for Kubernetes components)
Kubernetes는 고가용성(HA) 클러스터에서 kube-controller-manager나 kube-scheduler 같은 동일한 컨트롤 플레인 컴포넌트의 여러 인스턴스 사이에서 리더 선출을 수행하는 데 Lease API를 사용해요.
Lease는 Kubernetes API 서버가 저장하는 가벼운 분산 잠금(lightweight distributed lock) 역할을 합니다. 컴포넌트의 모든 실행 중인 인스턴스는 관련 Lease 객체를 감시(watch)하거나 주기적으로 읽어서 현재 어떤 인스턴스가 리더로 활동 중인지 판단해요.
Lease API는 다음과 같은 필드를 정의합니다.
holderIdentity– 현재 리더의 아이덴티티(예: 파드 이름 또는 호스트 이름 기반 문자열)예요.acquireTime– 리더십이 획득된 시점의 타임스탬프예요.renewTime– 리더가 마지막으로 갱신한 시점의 타임스탬프예요.leaseDurationSeconds– 리스의 유효 기간이에요. 후보는 만료된 리스를 획득하려 시도하기 전에 이 시간 + 약간의 유예 기간(grace period)을 기다려야 해요.leaseTransitions– 리더십이 몇 번 바뀌었는지 세는 카운터예요.
이 필드들은 어떤 인스턴스가 리더십을 보유하고 있고, 그 리더십이 얼마나 오래 유효한지를 나타내요.
Lease가 존재하지 않거나 만료되었을 때(현재 시각 > renewTime + leaseDurationSeconds), 후보 인스턴스들은 자신의 아이덴티티로 Lease를 갱신하려 시도합니다. Kubernetes는 객체의 resourceVersion을 통한 **낙관적 동시성 제어(optimistic concurrency control)**에 의존해요. 동시 시도에서 버전 불일치 때문에 오직 하나의 갱신만 성공합니다. 갱신이 받아들여진 인스턴스가 리더가 되죠.
Kubernetes는 리더 선출을 관리하는 데 LeaseCandidate API를 사용해요. kube-controller-manager와 kube-scheduler 같은 컨트롤 플레인 컴포넌트는 LeaseCandidate 객체를 만들어 자신의 역할을 후보로 등록합니다. 이 객체는 리더십을 두고 경쟁하는 모든 인스턴스를 추적하며, 후보의 아이덴티티, 바이너리 버전, 에뮬레이션 버전을 포함한 메타데이터를 담아요.
선거 동안 후보들은 공유 Lease를 통해 조정합니다. Kubernetes 컨트롤 플레인은 오직 한 후보만 Lease를 성공적으로 획득해 리더 역할을 맡고, 나머지는 모두 팔로워로 남도록 보장해요. 현재 리더가 선택된 타임아웃 기간 내에 Lease를 갱신하지 못하면, 나머지 후보들이 리더십을 두고 경쟁해 새 리더를 선출합니다.
일단 선출되면 리더는 renewTime 필드를 갱신해 Lease를 주기적으로 갱신합니다 (예: 리스가 만료되려 할 때 충돌을 피하려고 leaseDurationSeconds ÷ 2마다 갱신). 리스가 만료되기 전에 갱신이 일어나는 한 현재 리더 인스턴스는 리더십을 유지해요. 리더가 크래시하거나, 도달 불가능해지거나, Lease 갱신을 멈추면 그 Lease는 만료됩니다. 다른 정상 인스턴스들이 만료된 Lease를 감지하고 새 선거를 시도하죠.
이 메커니즘 덕분에 안정성과 복구를 위해 컴포넌트의 여러 복제본이 실행되고 있어도, 한 번에 오직 한 인스턴스만 컨트롤 작업을 적극적으로 수행하고, 나머지는 대기 상태로 Lease를 지켜보다가 필요하면 빠르게 인계받을 수 있어요.