← 아티클 목록

PodDisruptionBudget으로 가용성 보장 — Kubernetes PDB 설정

2028-02-14#kubernetes#가용성#운영

야간에 노드를 점검하려고 kubectl drain을 돌렸더니, 해당 노드의 Pod가 한꺼번에 쫓겨나면서 잠깐 서비스가 5xx를 뱉었습니다. 레플리카가 3개여도 의미가 없었던 건, 마침 3개가 같은 노드에 몰려 있었거나 드레인이 한 번에 다 비웠기 때문입니다. 이런 자발적 중단(voluntary disruption) 으로부터 최소 가용 Pod 수를 지켜주는 장치가 PodDisruptionBudget(PDB)입니다.

PDB가 막는 것과 못 막는 것

PDB는 "운영자가 의도적으로 일으키는 중단"에만 작동합니다.

중단 종류예시PDB 적용
자발적 중단kubectl drain, 노드 업그레이드, 클러스터 오토스케일 축소적용됨
비자발적 중단노드 하드웨어 장애, OOM 킬, 커널 패닉적용 안 됨

즉 PDB는 장애 방어가 아니라, 계획된 작업 중에 한꺼번에 너무 많이 내려가지 않게 막는 가드레일입니다.

minAvailable vs maxUnavailable

핵심 필드는 둘 중 하나만 씁니다.

YAML
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: web-pdb
spec:
  minAvailable: 2          # 항상 최소 2개는 살아있어야 함
  selector:
    matchLabels:
      app: web

maxUnavailable을 쓰면 "동시에 내려갈 수 있는 최대 개수"로 표현합니다.

YAML
spec:
  maxUnavailable: 1        # 한 번에 1개까지만 내려감

선택 기준은 단순합니다.

상황권장 필드
레플리카 수가 고정·소수(3~5)minAvailable: N (예: 2)
레플리카가 오토스케일로 변동maxUnavailable: 1 또는 25%
최소 정족수가 중요한 상태 저장 앱minAvailable로 정족수 명시

비율(50%)도 쓸 수 있지만, 레플리카가 1개면 minAvailable: 1은 드레인을 영원히 막아버리니 주의합니다.

적용과 확인

Kubernetes
kubectl apply -f web-pdb.yaml
kubectl get pdb web-pdb

출력의 ALLOWED DISRUPTIONS 값이 핵심입니다.

OUTPUT
NAME      MIN AVAILABLE   ALLOWED DISRUPTIONS   AGE
web-pdb   2               1                     10s

ALLOWED DISRUPTIONS0이면 그 순간엔 어떤 Pod도 자발적으로 못 내려갑니다. 이 상태에서 drain을 걸면 PDB를 만족할 때까지 블로킹됩니다.

체크리스트

Kubernetes
# 1. PDB가 가리키는 selector가 실제 Pod와 맞는지
kubectl get pods -l app=web

# 2. 허용 가능한 중단 수가 0이 아닌지
kubectl get pdb web-pdb -o jsonpath='{.status.disruptionsAllowed}'

# 3. drain이 PDB를 존중하는지 테스트
kubectl drain <node> --ignore-daemonsets --dry-run=server

minAvailable이 레플리카 수와 같으면 드레인이 멈춰버리니, 항상 레플리카 - 1 이하로 잡는 게 안전합니다.


PDB를 만들어 직접 drain을 걸어보며 드레인이 멈추는 순간을 관찰하는 실습은 쿠버네티스 트랙에서 회원가입 없이 무료로 해볼 수 있습니다.