CRD 와 오퍼레이터 · 조정이 두 번 일어났다 · 실습
조정이 두 번 일어났다 — 임차 만료와 인수, 그리고 사고 진단
목표
Lease 의 다섯 필드를 직접 다루며 갱신·만료·인수를 만들어 보고, 리더 선출에 필요한 최소 권한을 맞춘 뒤, 리더가 둘일 때 실제로 무슨 일이 생기는지 필드 관리자 충돌로 증명하고 운영 점검표로 묶는다.
왜 중요한가
오퍼레이터를 두 개 이상 띄우는 이유는 가용성이다. 그런데 조정 루프는 클러스터 상태를 바꾸는 코드라 동시에 둘이 돌면 안 된다. 그래서 쿠버네티스는 아주 작은 오브젝트 하나에 '지금 누가 리더인가' 를 적어 두고, 리더가 주기적으로 갱신하며 살아 있음을 알린다. 여기서 중요한 것은 이 오브젝트에 '만료됨' 같은 필드가 없다는 사실이다. 살아 있는지는 renewTime + leaseDurationSeconds 를 지금과 견주는 계산으로 정해지고, 그 계산은 각 인스턴스가 자기 시계로 한다. 시계가 어긋나거나 API 서버 응답이 늦으면 두 인스턴스가 동시에 자기가 리더라고 믿는 구간이 생긴다. 그 구간에 두 조정 루프가 같은 자원을 만들려 하면 무슨 일이 생기는지, 그리고 그 흔적을 어디서 찾는지가 이 실습의 주제다.
단계
1. 네임스페이스 op-leader 를 만들고 /root/op-leader/lease-widget.yaml 에 coordination.k8s.io/v1 Lease widget-operator 를 쓰세요 — holderIdentity 는 widget-operator-0, leaseDurationSeconds 는 15, acquireTime 과 renewTime 은 지금 시각, leaseTransitions 는 0 입니다. 적용한 뒤 kubectl -n op-leader get lease widget-operator -o yaml 출력을 /root/op-leader/lease-initial.yaml 에 저장하세요.
2. 리더가 하는 일을 손으로 세 번 해 보세요 — renewTime 만 지금 시각으로 갱신하는 patch 를 1초 간격으로 세 번 돌리고, 그때마다 갱신된 renewTime 을 /root/op-leader/renew-log.txt 에 한 줄씩 남깁니다(세 줄). holderIdentity 와 leaseTransitions 는 건드리지 않습니다.
3. 두 개의 임차를 더 만드세요 — /root/op-leader/lease-stale.yaml 은 stale-operator(holder stale-operator-0, leaseDurationSeconds 15, renewTime 을 10분 전으로), /root/op-leader/lease-fresh.yaml 은 fresh-operator(holder fresh-operator-0, leaseDurationSeconds 86400, renewTime 은 지금)입니다. /root/op-leader/leases.tsv 에 <임차이름><탭><기대: EXPIRED 또는 LIVE> 두 줄을 적고, /root/op-leader/expiry.sh 가 각 임차의 renewTime + leaseDurationSeconds 를 지금과 견줘 분류한 뒤 맞으면 OK …, 틀리면 MISMATCH … 를 표준출력에만 찍고 한 줄이라도 틀리면 0 이 아닌 코드로 끝나게 하세요. 출력을 /root/op-leader/expiry.txt 에 저장합니다.
4. widget-operator 임차를 다른 인스턴스가 가져갔다고 보고 한 번의 patch 로 네 값을 바꾸세요 — holderIdentity 를 widget-operator-1 로, acquireTime 과 renewTime 을 지금 시각으로, leaseTransitions 를 1 로. /root/op-leader/takeover.txt 에 네 줄을 남기세요 — before-holder=, after-holder=, before-transitions=, after-transitions=.
5. 초 단위 시각으로 갱신을 시도해 보세요 — renewTime 을 2026-01-01T00:00:00Z 처럼 소수점 없는 값으로 patch 합니다. 결과를 /root/op-leader/microtime-error.txt 에 모으세요 — 첫 줄은 patch-rc=<종료 코드> 이고 그 아래에 서버가 낸 문장을 그대로 붙입니다.
6. /root/op-leader/rbac.yaml 에 세 오브젝트를 담아 적용하세요 — ServiceAccount widget-operator, Role leader-election(coordination.k8s.io 그룹의 leases 에 get·create·update 만), 그리고 둘을 잇는 RoleBinding leader-election. 그다음 kubectl auth can-i <동사> leases.coordination.k8s.io --as=system:serviceaccount:op-leader:widget-operator -n op-leader 를 get·create·update·delete 네 번 돌려 결과를 /root/op-leader/rbac-check.txt 에 <동사>=<yes 또는 no> 네 줄로 저장하세요.
7. 두 인스턴스가 동시에 자기가 리더라고 믿는 상황을 재현하세요 — /root/op-leader/child-a.yaml 에 ConfigMap order-1(네임스페이스 op-leader, data.phase 는 A)을 쓰고 kubectl apply --server-side --field-manager=widget-operator-0 로 적용합니다. 그다음 /root/op-leader/child-b.yaml 에 같은 이름의 ConfigMap 을 data.phase 는 B 로 써서 --field-manager=widget-operator-1 로 적용해 보세요. 결과를 /root/op-leader/split-brain.txt 에 모으세요 — apply-b-rc=<종료 코드>, 서버가 낸 문장, 그리고 마지막 줄에 final-phase=<지금 값>.
8. /root/op-leader/lease-audit.sh 를 만드세요 — op-leader 의 모든 임차를 <이름> holder=<홀더> transitions=<전환 횟수> duration=<임차 길이> 한 줄씩 정렬해 표준출력에만 찍습니다(나이나 시각은 넣지 않습니다). 출력을 /root/op-leader/lease-audit.txt 에 저장하고, /root/op-leader/runbook.txt 에 운영 규칙을 적으세요 — --leader-elect-lease-duration·--leader-elect-renew-deadline·--leader-elect-retry-period 세 값의 이름이 모두 나와야 하고, 갱신 기한이 임차 길이보다 짧아야 하는 이유와 전환 횟수가 계속 늘 때 무엇을 의심할지가 들어가야 합니다.
참고
acquireTime과renewTime은 MicroTime 이라 소수점 이하 여섯 자리가 필요합니다.- 갱신은
renewTime만 바꾸고, 인수는 홀더·acquireTime·leaseTransitions를 함께 바꿉니다. - 리더 선출에 필요한 동사는
get·create·update셋뿐입니다. kubectl auth can-i --as=로 다른 주체의 권한을 대신 물어볼 수 있습니다.- 흔한 실수: 갱신할 때
leaseTransitions를 함께 올려 전환 횟수를 의미 없게 만든다. - 흔한 실수: 임차가 만료됐는지 오브젝트의 어떤 필드에서 찾으려 한다 — 계산해야 합니다.
- 참고: https://kubernetes.io/docs/concepts/architecture/leases/
- 참고: https://kubernetes.io/docs/reference/kubernetes-api/cluster-resources/lease-v1/
- 참고: https://kubernetes.io/docs/reference/command-line-tools-reference/kube-controller-manager/
단계 8개
- 임차 한 장이 리더를 정한다
- 리더는 쉬지 않고 갱신한다
- 살아 있는지는 계산으로 정한다
- 인수는 전환 횟수로 드러난다
- 시각 형식 하나가 갱신을 막는다
- 리더 선출에 필요한 최소 권한
- 리더가 둘이면 같은 필드를 놓고 싸운다
- 점검표와 운영 규칙으로 묶는다