반응형
Kubernetes Leader Election for Fun and Profit
Nick Young, VMware
소개할 내용은 세 가지
- What is Leader Election & how do you implement
- Guides for using it
- Common Patterns
What is Leader Election
k8s는 API server에서 쓰는 leader election code를 사용자의 controller에서도 쓸 수 있게 지원하고 있다.
- Elect 1 instance as a leader.
- only 1 instance can make changes.
사용할 수 있는 기능으로는
- write changes back = Controller Pattern
- 클러스터 외부에서 작업을 수행한 뒤, 결과를 k8s API로 전달. = Operator Pattern.
- 여러 인스턴스가 Watch하되, writes back은 하나의 인스턴스만 수행
- 나머지 인스턴스는 status update가 필요하지 않은, async한 작업을 수행한다던가..
- 등등
애플리케이션의 reliability, High Availability 확보에 도움이 되는 기능.
어떻게 동작하는가?
- leader election -> Lock 기능을 하는 Shared Object를 update하는 식으로 동작.
- k8s api server controller를 비롯한 k8s component에서 사용하는 코드임
- Shared Object는 k8s object
- v1.14 이전: Only Configmap (endpoints라는 Object가 있었으나 금방 deprecated)
- v1.14 이후: Lease / Configmap 중 선택 가능.
- Lease: Configmap의 election 기능을 동일하게 수행하되 Dedicated Object임.
- Configmap 방식일 경우 정보가 annotation에 저장되며, lease의 경우 spec에 저장된다.
- 애플리케이션이 configmap / lease를 update할 수 있는 permission (role) 줘야 동작한다.
Docs : k8s.io/client-go/tools/leaderelection/resourcelock
How to Implement
Kubebuilder 사용하기
- kubebuilder 이미 쓰고 있다면 -enable-leader-election 옵션만 주면 됨
- NewManager() 함수의 options으로 파라미터 넣어도 됨.
- LeaderElectionID = 내가 정의한 leader election이 uniqueness.
Informer 사용하기 - 발표자가 Contour라는 프로젝트의 maintainer이므로 Contour의 방식을 소개.
- 두 가지 작업을 해야 함
- leader Election을 동작시키고
- leader election 결과로 나오는 go channel을 watching
Contour의 경우
- Create and run the Kubernetes leader elector, this returns the “I became leader” channel.
- Run another goroutine that triggers when we become leader by watching the channel.
- Have a number of other processes that watch the same channel to check if we’re the leader.
docs: k8s.io/client-go/tools/leaderelection.
Usage Guideline
- instance가 deposed 되었을 때 clean up 시도하지 마라. k8s 기능을 활용해라.
- 예컨대 Instance가 leader 권한을 가져갔는데, 모종의 이유로 properties가 변경되어 leader가 아니게 된 경우..
- leadership election을 다시 실행해야 함.
- 근데 이걸 굳이 소스코드 따로 만드는 대신, 해당 인스턴스를 close down만 해주면 된다.
- k8s가 알아서 restart 해준다.
- this is a human-scale lock.
- leader가 사라졌을 때, 다른 컴포넌트가 다시 leader가 되기까지 걸리는 시간은 대략 30초 정도.
- 즉 30초 정도의 no leader 상태가 있다는 뜻.
- 만약 약 30초 정도의 공백이 있으면 안 되는 서비스라면, k8s distributed lock을 쓰면 안 된다.
- 이 기능을 k8s의 reconcile 로직이 동작하는 수준에서 가능한 범위의 서비스에만 적용하라는 뜻.
- Be aware of what you're using your distributed lock for.
- distributed lock 기능 써서 뭐 하려고 하는지 명확하게 정의한 뒤 적용해야 한다.
- 특징 / 한계점 명확히 알고 쓰라는 의미인 듯.
Common Pattern
Basic Controller / Operator
k8s object의 변경사항을 기반으로 특정 작업을 수행함.
- health check / metrics 외에는 따로 endpoint가 있진 않음.
- leader가 특정 동작을 수행해야 하는 코드 영역에 leader lock 적용하면 된다.
Kubebuilder를 쓸 경우
- Reconciler가 leader-elected 방식으로 동작함. 따라서 HA를 위해 여러 노드나 클러스터에 instance를 배포한다 해도, 특정 동작을 시행하는 건 only one instance at a time.
informer 쓸 경우
- 가장 단순한 방법은 block the main on becoming the leader.
- blocking 로직 실행하기 전에 health / metric 관련 endpoint는 initialized되어 있어야 한다
- 동작해야 하는 코드를 작성하고, leader election을 시행한다. 그럼 leader가 된 녀석만 코드를 실행한다.
- shut down / lose leadership일 경우... k8s가 알아서 election process에 넣어 준다.
- 문제가 생겼다? 그냥 process shut down하면 된다. cleanup 로직 같은 거 필요 없음
아까도 이야기했지만 health / metrics가 lock 이전에 initialized 되어야 한다.
Multi-Read, Leader Write
k8s object Watching은 여러 컴포넌트에서 동시에 수행. 단, leader만 Write / Update 가능함.
Contour의 예시를 들면
- Contour는 Watch k8s object -> translate it to envoy xDS endpoints
- allow envoys to connect to those endpoints & configure themselves appropriately.
- Every instance watches k8s objects, only Leader can write status update back to Contour CRDs (http proxy).
예시: kubebuilder의 Webhook 방식
- main reconciler는 elected leader. -> 실제 reconcile 로직 수행
- Non-leader instance는 defaulting, conversion, validation webhooks 로직 수행.
Advanced Pattern
Per-CRD leader election.
- knative가 이 방식을 쓰고 있으며, leader election을 object Type별로 수행한다.
- knative는 4~5개의 CRD가 있음.
- spreading the reconciliation workload over instances of the controller.
- 예컨대 Controller에 instance가 5개 있다면, each one holding a lock for a particular type of CRD.
Summary
반응형
'학습일지 > kubernetes' 카테고리의 다른 글
KubeCon2023 - Building Better Controllers (0) | 2024.08.11 |
---|---|
Naver Engineering Day 2024 - Kubernetes에서 DNS 다루는 방법 (0) | 2024.06.26 |
kubernetes Dynamic Informers with client-go (0) | 2023.07.25 |
if kakao 2022 - Kubernetes Controller를 위한 테스트코드 작성 (0) | 2023.02.24 |
ContainerDays 2021 - Into the Core of Kubernetes: the internals of etcd 정리 (0) | 2022.12.30 |