노드 drain이 PDB에서 멈출 때 disruptionsAllowed 읽는 법
문제 상황
kubectl drain node-dev-3이 Cannot evict pod as it would violate the disruption budget로 멈춘다.
전제 (가상 값)
policy/v1PDB를 지원하는 Kubernetes 1.21 이상 dev 클러스터. 아래 조회의 namespace는pdb-lab이며 같은 namespace에app=web인 Deployment가 준비돼 있다고 가정한다. 대상은 해당 실습 워크로드만 배치된 dev 노드다.- Deployment replicas=3, PDB minAvailable=2 (policy/v1)
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: web-pdb
namespace: pdb-lab
spec:
minAvailable: 2
selector:
matchLabels:
app: webPDB 상태 읽기
kubectl config current-context
kubectl -n pdb-lab get deployment web
kubectl -n pdb-lab get pdb web-pdb -o yaml필드 해석:
currentHealthy: 현재 건강한 pod 수 (예: 2)desiredHealthy: 유지해야 할 최소 (예: 2)disruptionsAllowed(ALLOWED DISRUPTIONS): 지금 퇴거 허용 개수. 0이면 drain이 막힌다.
왜 막히나
PDB는 Eviction API를 통한 자발적 중단만 제약한다. 정상적인 안정 상태에서는 건강한 Pod 수와 필요 수의 차이로 퇴거 여유를 이해할 수 있다. 실제 판단에는 컨트롤러가 보고한 status.disruptionsAllowed를 사용한다. 진행 중인 퇴거와 상태 갱신 때문에 단순 뺄셈만으로 판단하지 않는다. minAvailable=2, replicas=3인데 pod 하나가 이미 Ready가 아니면 currentHealthy=2 → 여유 0 → 퇴거 거부.
오해 정리
- PDB는 노드 장애 같은 비자발적 중단을 막지 못한다. 하드웨어가 죽으면 그냥 죽는다.
- PDB는 Deployment rollout이 항상 minAvailable을 지킨다고 보장하지 않는다. 그건 rollout 전략의 몫이다.
조치 순서
- capacity/Ready 먼저 확인:
kubectl -n pdb-lab get pod -l app=web -o wide로 왜 하나가 NotReady인지 본다. - 건강한 pod가 3이 되어 disruptionsAllowed가 1로 오르면 drain이 진행된다.
- dev 노드 drain(실습 환경 전용):
kubectl drain node-dev-3 --ignore-daemonsets --timeout=120s--ignore-daemonsets: DaemonSet pod는 어차피 못 빼므로 무시.--timeout: 무한 대기 방지.--force와--disable-eviction은 금지.--disable-eviction은 Eviction API를 건너뛰고 직접 삭제해 PDB 보호를 무력화한다.
dry-run: drain에는 --dry-run 플래그가 있으나 실제 퇴거 시퀀스를 완전히 모사하지는 않는다. 무엇이 대상인지 보려면 kubectl get pod -A --field-selector spec.nodeName=node-dev-3 -o wide로 목록을 먼저 확인하는 편이 확실하다.
적용과 성공 판정
위 PDB를 web-pdb.yaml로 저장한다. 기존 PDB가 있다면 이름만 같은 다른 정책을 덮어쓰지 말고 먼저 selector와 설정을 비교한다.
kubectl apply --dry-run=server -f web-pdb.yaml
kubectl apply -f web-pdb.yaml
kubectl -n pdb-lab get pdb web-pdb -o yaml
kubectl -n pdb-lab get pods -l app=web -o wide상태 예시는 currentHealthy: 3, desiredHealthy: 2, disruptionsAllowed: 1이다. drain 완료 후에는 대체 Pod가 다른 노드에서 Ready인지와 실제 서비스 요청 성공을 확인한다. 대체 Pod가 Pending이면 자원 부족·affinity·볼륨 배치 조건을 조사한다.
drain은 namespace 하나가 아니라 노드의 여러 워크로드에 영향을 준다. 다른 앱이나 로컬 데이터가 보이면 실습을 멈춘다. timeout으로 종료돼도 노드는 이미 cordon 상태이거나 일부 Pod가 퇴거됐을 수 있으므로 상태를 확인한 뒤 필요하면 uncordon한다.
되돌리기 / 한계
kubectl uncordon node-dev-3은 노드를 다시 스케줄 가능으로 바꿀 뿐, 이미 퇴거된 pod를 그 노드로 되돌리지 않는다. 재배치는 스케줄러가 결정한다.- 근본 원인(NotReady pod)을 안 고치고 timeout만 늘리면 drain은 계속 실패한다.
- 위 replicas/minAvailable 값은 가상 예시다.
출처
댓글 0개
아직 댓글이 없습니다.
