apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: web-pdb
spec:
minAvailable: 2 # 또는 maxUnavailable: 1
selector:
matchLabels: { app: web }
drain 이나 클러스터 오토스케일러가 파드를 뺄 때 이 조건을 지킨다
- 세 개 중 두 개는 항상 살아 있어야 한다면 minAvailable: 2
자발적 중단만 막는다
-
자발적(voluntary) — drain · 오토스케일러 축소 · 노드 업그레이드
- PDB 가 막는다
-
비자발적(involuntary) — 노드가 갑자기 죽음 · 하드웨어 장애 · 커널 패닉
- PDB 로 못 막는다. 애초에 막을 방법이 없다
"PDB 를 걸었으니 항상 N개가 산다" 는 틀렸다 비자발적 중단에 대비하려면 복제 수와 영역 분산으로 푼다
가장 흔한 사고
minAvailable 을 replicas 와 같게 두면
- 하나도 뺄 수 없다
- drain 이 영원히 멈춘다
- 노드 업그레이드가 진행되지 않는다
| replicas: 3, minAvailable: 3 | ← 이렇게 두면 안 된다 | |
|---|---|---|
| replicas: 3, minAvailable: 2 | ← 하나씩 교체 가능 |
drain 이 안 끝나면 PDB 를 먼저 확인한다 kubectl get pdb -A
- kubectl describe pdb web-pdb — # ALLOWED DISRUPTIONS 가 0 인지
퍼센트로도 쓸 수 있다
spec:
maxUnavailable: 25%
replicas 가 자주 바뀌는 워크로드에는 퍼센트가 안전하다 다만 반올림 규칙이 있어 작은 replicas 에서는 의도와 다를 수 있다
- replicas 2 에 maxUnavailable: 50% 면 1개
- replicas 3 에 minAvailable: 50% 면 2개 (올림)
함께 봐야 할 것
PDB 만으로는 무중단이 되지 않는다
- 파드가 여러 노드·영역에 퍼져 있어야 한다 (topologySpread)
- readiness 프로브가 정확해야 한다 (Ready 판정이 곧 가용성 판정이다)
- graceful shutdown 이 동작해야 한다
네 가지가 함께 있어야 노드 교체가 무중단이 된다
확인 명령
kubectl get pdb -A
kubectl describe pdb web-pdb
# ALLOWED DISRUPTIONS: 0 ← 0 이면 drain 이 멈춘다
ALLOWED DISRUPTIONS 가 0 인 이유
- 현재 가용 파드 수가 이미 minAvailable 과 같다
- Ready 가 아닌 파드가 있어 여유가 없다
- 파드를 먼저 정상화해야 drain 이 진행된다
즉 PDB 가 막고 있을 때 "PDB 를 지운다" 가 아니라 "왜 가용 파드가 부족한가" 를 본다
어떤 워크로드에 필요한가
-
필요하다 — 상시 트래픽을 받는 서비스
- 복제본이 2개 이상이고 동시에 빠지면 안 되는 것
-
필요 없다 — replicas: 1 인 것 (어차피 못 지킨다)
- Job · CronJob (일회성)
- DaemonSet (노드마다 하나라 옮길 곳이 없다)
replicas: 1 에 PDB 를 걸면 drain 이 아예 불가능해진다 단일 인스턴스는 중단을 감수하거나 복제본을 늘린다
면접 함정
- ❌ "PDB를 걸면 파드가 안 죽는다" → 노드가 갑자기 죽는 것은 못 막는다.
- ❌ "drain이 멈춘 건 버그" → 대개 PDB가 의도대로 막고 있는 것이다.