PodDisruptionBudget(PDB)으로 voluntary disruption의 동시 종료 수를 제한해 무중단을 유지kubectl delete pod는 못 막음maxUnavailable과 PDB의 maxUnavailable은 서로 다른 상황에서 동작하는 별개의 설정. 둘 다 설정해야 진짜 무중단| 구분 | 정의 | 대표 예시 |
|---|---|---|
| Voluntary | 운영자·시스템 컴포넌트가 의도적으로 종료 | kubectl drain, 노드 업그레이드, Cluster Autoscaler scale-down, Deployment rollout |
| Involuntary | 의도하지 않은 사고로 종료 | 하드웨어 장애, 커널 패닉, 노드 네트워크 단절, 노드 OOM으로 인한 강제 종료, kubelet 비정상 종료 |
kubectl drain — 노드를 비우고 점검·교체할 때kubectl drain, Cluster Autoscaler, descheduler 등이 내부적으로 Eviction API 호출DELETE pod ≠ Eviction
kubectl delete pod는 PDB를 무시하고 즉시 삭제 — eviction을 우회함AllowedDisruptions ≥ 1인지 확인. 0이면 거부(429 Too Many Requests)terminationGracePeriodSeconds 존중 — preStop hook → SIGTERM → grace 경과 후 SIGKILLapiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: my-app-pdb
spec:
selector:
matchLabels:
app: my-app
minAvailable: 2 # 또는 maxUnavailable 중 택1
selector — 보호 대상 pod 셀렉터minAvailable — 항상 가용해야 할 최소 pod 수. 절대값 또는 백분율maxUnavailable — 동시에 unavailable 될 수 있는 최대 pod 수. 절대값 또는 백분율minAvailable과 maxUnavailable은 XOR — 둘 중 하나만 지정 (둘 다 쓰면 거부됨)ownerReferences를 따라가 상위 워크로드의 desired replicas를 산출
spec.replicas 값을 참조minAvailable/maxUnavailable로 현재 허용 가능한 evict 수(AllowedDisruptions) 를 계산
minAvailable=4 → AllowedDisruptions = 5 - 4 = 1AllowedDisruptions를 1 감소시키고, pod가 다시 ready가 되면 회복replicas=1 + minAvailable=1minAvailable: 1을 걸면 eviction이 영원히 거부됨
kubectl drain이 멈추고, Cluster Autoscaler가 노드를 회수하지 못함minAvailable: 1 (또는 maxUnavailable: 1) — 가장 일반적unhealthyPodEvictionPolicy: AlwaysAllow로 우회 가능성 확보unhealthyPodEvictionPolicy| 값 | 동작 | 사용 시점 |
|---|---|---|
IfHealthyBudget (기본) |
ready인 pod도 PDB budget 안에서만 evict. unhealthy pod라도 PDB를 위반하면 막힘 | 안정성 우선. 정상 pod를 갑자기 빼앗기지 않음 |
AlwaysAllow |
unhealthy(non-ready) pod는 PDB와 무관하게 항상 evict 허용 | 죽은 pod 때문에 drain이 멈추는 상황 해소 |
IfHealthyBudget의 함정
AlwaysAllow는 그 교착을 푸는 안전판 — 운영 자동화가 멈추는 사고를 줄임kubectl delete pod — eviction을 우회한 직접 삭제. PDB는 무시됨노드 종료에 의한 graceful node shutdown — 환경에 따라 PDB를 고려하기도/안 하기도 함
maxUnavailable vs PDB의 maxUnavailable| 구분 | Deployment maxUnavailable |
PDB maxUnavailable |
|---|---|---|
| 적용 시점 | rollout 진행 중 | 모든 voluntary disruption 시점 |
| 누가 사용 | Deployment Controller가 새 ReplicaSet으로 교체할 때 | Eviction API가 evict 허용 여부 판단할 때 |
| 보호 대상 | rollout 진행 속도 | 노드 drain·오토스케일 등 외부 evict |
| 단독으로 막는가 | rollout 외에는 무력 | rollout 자체에는 적용되지 않음 (rollout은 PDB 우회) |
maxUnavailable=0 만 있으면 — rollout은 안전하지만 노드 drain 한 번에 다 빠질 수 있음maxUnavailable=1 만 있으면 — drain은 안전하지만 rollout이 한꺼번에 25%(기본) 빠질 수 있음replicas ≥ 2 (또는 HPA minReplicas ≥ 2)
maxSurge ≥ 1, maxUnavailable: 0
minAvailable 또는 maxUnavailable을 desired보다 작게 설정
minAvailable: 2 또는 maxUnavailable: 1preStop hook + terminationGracePeriodSeconds
PodAntiAffinity (선택)
kubectl get pdb -A
NAMESPACE NAME MIN AVAILABLE MAX UNAVAILABLE ALLOWED DISRUPTIONS AGE
default my-app-pdb 2 N/A 1 3d
0이면 노드 drain·오토스케일이 막힌 상태. unhealthy pod 존재 또는 desired 부족이 흔한 원인kubectl drain <node> --dry-run=server --ignore-daemonsets
kubectl get pdb my-app-pdb -o yaml
status.disruptionsAllowed, status.currentHealthy 값을 직접 확인해 디버깅