/////

Kubernetes PodDisruptionBudget Failure Modes: Voluntary Evictions, Rounding Semantics, Unhealthy Pod Eviction, and Node-Drain Deadlocks

Kubernetes PodDisruptionBudget(PDB)는 Eviction API를 통한 자발적 중단(voluntary disruption) 에서 애플리케이션 가용성 하한을 표현하는 장치다. 그러나 PDB는 “항상 N개 Pod가 살아 있다”를 보장하는 락이 아니며, 노드 장애·리소스 압박·직접 삭제·컨트롤러 롤링업데이트 같은 경로에서는 기대와 다르게 동작할 수 있다. 운영 실패는 주로 네 가지에서 반복된다. 1. PDB가 보호하는 것은 voluntary

/////

Summary#

Kubernetes PodDisruptionBudget(PDB)는 Eviction API를 통한 자발적 중단(voluntary disruption) 에서 애플리케이션 가용성 하한을 표현하는 장치다. 그러나 PDB는 “항상 N개 Pod가 살아 있다”를 보장하는 락이 아니며, 노드 장애·리소스 압박·직접 삭제·컨트롤러 롤링업데이트 같은 경로에서는 기대와 다르게 동작할 수 있다.

운영 실패는 주로 네 가지에서 반복된다.

  1. PDB가 보호하는 것은 voluntary eviction뿐 이며, 비자발적 중단은 막지 못하지만 budget에는 반영된다.
  2. minAvailable / maxUnavailable의 퍼센트 값은 올림(round up) 되므로 작은 replica 수에서 의외의 결과가 나온다.
  3. 기본 unhealthyPodEvictionPolicy: IfHealthyBudget는 비정상 Pod가 회복될 기회를 주지만, CrashLoopBackOff / Ready=False Pod 때문에 node drain이 막힐 수 있다.
  4. 지나치게 엄격한 PDB는 kubectl drain, 클러스터 업그레이드, Cluster Autoscaler scale-down을 막아 운영 deadlock 을 만들 수 있다.

실무적으로는 PDB를 “무중단 보증”이 아니라 eviction rate limiter 로 다루어야 한다. 특히 단일 replica, minAvailable == replicas, maxUnavailable: 0, overlapping selector, 비정상 Pod, pending replacement, autoscaler scale-down 경로를 별도 failure mode로 점검해야 한다.

Key Points#

1. PDB는 voluntary eviction에만 직접 작동한다#

PDB는 주로 다음과 같은 자발적 중단 경로에서 의미가 있다.

  • kubectl drain
  • 클러스터 관리자에 의한 노드 유지보수
  • Cluster Autoscaler의 scale-down 중 Pod evict
  • Eviction API를 사용하는 자동화 도구

반대로 다음은 PDB가 직접 막지 못하거나, 다른 컨트롤러 정책이 우선된다.

  • 노드 장애
  • kubelet node-pressure eviction
  • 하드웨어 / 커널 / VM 장애
  • Pod 직접 삭제 경로
  • Deployment / StatefulSet 등 워크로드 컨트롤러의 rolling update 동작

Kubernetes 문서는 비자발적 중단은 PDB가 막을 수 없지만 budget에는 계산된다고 설명한다. 또한 workload rolling update로 unavailable해진 Pod는 budget에 반영되지만, Deployment나 StatefulSet의 update 자체가 PDB에 의해 제한되는 것은 아니다. 이 차이를 놓치면 “PDB를 만들었는데도 Pod가 내려갔다”는 오해가 생긴다.

2. Eviction API 기반 drain은 PDB를 존중하므로 멈출 수 있다#

kubectl drain은 Pod를 강제로 다른 노드로 순간이동시키지 않는다. drain은 대상 노드의 Pod들을 Eviction API로 종료시키고, 컨트롤러가 replacement Pod를 만들며, scheduler가 다른 노드에 배치하는 흐름이다.

따라서 다음 조건 중 하나라도 맞으면 drain이 막힌다.

  • PDB의 disruptionsAllowed가 0이다.
  • replacement Pod가 아직 Ready가 아니다.
  • replacement Pod가 Pending 상태다.
  • 클러스터에 replacement를 스케줄할 여유 리소스가 없다.
  • StatefulSet의 순차적 재생성 때문에 replacement가 늦게 Ready 된다.
  • 비정상 Pod가 IfHealthyBudget 정책 아래에서 evict 불가 상태다.
  • 단일 replica에 minAvailable: 1 또는 maxUnavailable: 0을 설정했다.

Kubernetes 문서의 예시는 minAvailable: 2인 3-replica 애플리케이션에서 첫 번째 노드 drain은 가능하지만, replacement가 Ready 되기 전에 다른 노드를 drain하면 block될 수 있음을 보여준다. replacement가 Pending인 경우에는 결국 노드를 다시 추가해야 진행될 수 있다.

3. minAvailable / maxUnavailable 퍼센트는 올림된다#

PDB에서 minAvailable 또는 maxUnavailable은 정수 또는 퍼센트로 지정할 수 있다. 퍼센트는 정수 Pod 수로 환산될 때 올림된다.

운영상 중요한 결과:

  • minAvailable: "50%", replicas 7
    → 최소 healthy Pod 수는 3.5가 아니라 4.
  • maxUnavailable: "30%", replicas 1
    → 0.3을 올림하여 1개 unavailable 허용. 즉 단일 replica가 100% unavailable될 수 있다.
  • maxUnavailable: 0 또는 "0%"
    → voluntary eviction 0개 허용.
  • minAvailable: 100% 또는 replica 수와 동일한 정수
    → voluntary eviction 0개 허용.

작은 replica 수에서 퍼센트 PDB는 직관과 다르게 작동한다. 특히 maxUnavailable 퍼센트는 “비율상 일부만 허용”처럼 보이지만, replica가 1이면 올림 때문에 전체 Pod 하나가 disruption 가능해진다.

4. maxUnavailable: 0 / minAvailable: replicas는 drain을 의도적으로 막는다#

다음 설정은 “가용성을 높이는 안전장치”가 아니라 voluntary eviction 금지 정책 이다.

minAvailable: 100%
minAvailable: <현재 replicas와 같은 수>
maxUnavailable: 0
maxUnavailable: "0%"

이런 PDB가 걸린 Pod가 특정 노드에 있으면 해당 노드는 정상적인 방식으로 drain되지 않는다. Kubernetes 문서도 이러한 zero voluntary eviction 설정에서는 해당 Pod가 있는 Node drain이 완료되지 않는 것이 PDB semantics상 허용된 동작이라고 설명한다.

운영적으로는 다음을 구분해야 한다.

  • 정말로 자동 drain을 막고 싶은 stateful / quorum / single-writer 워크로드인가?
  • 아니면 “고가용성”을 의도했지만 결과적으로 upgrade / maintenance / autoscaler를 막는 설정인가?

5. unhealthyPodEvictionPolicy 기본값은 IfHealthyBudget#

Kubernetes PDB에는 비정상 Pod eviction 정책인 .spec.unhealthyPodEvictionPolicy가 있다.

정책은 두 가지다.

IfHealthyBudget

기본 동작이다. Running 상태지만 아직 healthy / Ready가 아닌 Pod는, 애플리케이션의 현재 healthy 수가 desired healthy 이상일 때만 evict될 수 있다.

장점:

  • 아직 Ready가 되지 않은 Pod가 회복될 기회를 준다.
  • 이미 disruption 상태인 애플리케이션을 더 악화시키지 않으려 한다.

실패 모드:

  • CrashLoopBackOff
  • readiness probe 실패
  • 버그 또는 설정 오류로 Ready가 되지 않는 Pod
  • 장시간 Running but NotReady 상태

이런 Pod가 PDB에 걸려 있으면 node drain이 멈출 수 있다.

AlwaysAllow

Running 상태지만 healthy가 아닌 Pod를 PDB 기준 충족 여부와 무관하게 evict 가능하게 본다.

장점:

  • misbehaving Pod 때문에 drain / upgrade / autoscaler가 막히는 상황을 줄인다.
  • Kubernetes 문서는 node drain 중 misbehaving application eviction을 지원하기 위해 AlwaysAllow 사용을 권장한다.

위험:

  • 아직 회복 가능했던 Pod를 제거할 수 있다.
  • 애플리케이션이 이미 degraded 상태일 때 추가 disruption이 발생할 수 있다.

실무 해석:

  • stateless 서비스, 쉽게 재시작 가능한 워크로드, readiness 실패가 장시간 지속될 수 있는 워크로드는 AlwaysAllow를 검토한다.
  • quorum, 데이터 복제, graceful handoff가 중요한 워크로드는 AlwaysAllow가 데이터 안전성과 충돌하지 않는지 별도 검토한다.

6. Cluster Autoscaler scale-down도 PDB에 막힐 수 있다#

Cluster Autoscaler(CA)는 scale-down 시 노드의 Pod를 다른 곳으로 옮길 수 있는지 판단한다. 이때 “evict하면 안 되는 Pod”가 있으면 underutilized node라도 제거하지 않는다.

CA scale-down을 막는 대표 조건:

  • restrictive PDB
  • kube-system Pod에 PDB가 없거나 너무 엄격함
  • controller가 없는 Pod
  • local storage 사용 Pod
  • cluster-autoscaler.kubernetes.io/safe-to-evict: "false" annotation
  • 다른 노드에 스케줄할 수 없는 resource / nodeSelector / hostPort / affinity 제약
  • node group minimum size
  • scale-down delay / failure backoff

PDB 관점의 deadlock 패턴은 다음과 같다.

  1. CA가 underutilized node를 제거하려고 한다.
  2. 해당 노드에 PDB가 엄격한 Pod가 있다.
  3. Eviction이 거부된다.
  4. CA는 노드를 제거하지 못한다.
  5. 클러스터에는 불필요해 보이는 노드가 계속 남는다.
  6. 운영자는 “왜 idle node가 안 줄어드는가”를 조사하게 된다.

kube-system Pod의 경우 CA 문서는 안전하게 재스케줄 가능한 시스템 Pod에 PDB를 수동으로 추가하는 방식을 설명한다. 예를 들어 max-unavailable 1 같은 설정으로 CA가 해당 Pod를 이동할 수 있게 할 수 있다. 단, Metrics Server처럼 재시작 영향이 큰 컴포넌트는 별도 주의가 필요하다.

7. PDB selector 중복은 eviction 거부를 만들 수 있다#

Kubernetes 문서는 여러 PDB가 같은 Pod를 선택하는 경우 Eviction API가 eviction을 거부한다고 설명한다. PDB를 교체하거나 마이그레이션하는 과정에서 selector overlap이 잠시 발생할 수 있는데, 이때 drain / autoscaler가 예상치 못하게 막힐 수 있다.

점검 포인트:

kubectl get pdb -A
kubectl describe pdb -n <namespace> <pdb-name>
kubectl get pod -n <namespace> --show-labels

확인해야 할 값:

  • .status.currentHealthy
  • .status.desiredHealthy
  • .status.disruptionsAllowed
  • .status.expectedPods
  • selector가 실제 의도한 Pod만 선택하는지
  • 하나의 Pod가 둘 이상의 PDB에 잡히지 않는지

8. PDB는 capacity planning과 함께 설계해야 한다#

PDB는 replacement Pod가 다른 노드에 올라갈 수 있다는 전제를 깔고 있다. 그러나 실제 클러스터에 여유 용량이 없으면 다음 순서로 막힌다.

  1. drain 시작
  2. 기존 Pod evict
  3. controller가 replacement 생성
  4. replacement가 Pending
  5. PDB 기준상 추가 eviction 불가
  6. drain 정지

따라서 PDB만으로는 안전한 maintenance가 보장되지 않는다. 함께 설계해야 할 항목:

  • 최소 replica 수
  • Pod anti-affinity / topology spread
  • 노드별 capacity 여유
  • PriorityClass / preemption 정책
  • HPA minReplicas
  • Cluster Autoscaler scale-up 가능 여부
  • drain concurrency
  • StatefulSet termination / startup 시간
  • readiness probe 안정성
  • terminationGracePeriodSeconds

9. 운영 체크리스트#

PDB를 적용하거나 검토할 때 다음을 확인한다.

  • 단일 replica 워크로드에 PDB가 걸려 있는가?
  • minAvailable이 replica 수와 같은가?
  • maxUnavailable이 0인가?
  • 퍼센트 PDB가 작은 replica 수에서 올림되어 의도와 다르게 작동하지 않는가?
  • disruptionsAllowed가 장시간 0인가?
  • NotReady / CrashLoopBackOff Pod가 drain을 막고 있는가?
  • unhealthyPodEvictionPolicy가 명시되어 있는가?
  • default IfHealthyBudget가 적합한가, 아니면 AlwaysAllow가 필요한가?
  • replacement Pod가 Pending이 되지 않을 만큼 capacity가 있는가?
  • Cluster Autoscaler가 해당 Pod를 evict 가능한가?
  • kube-system Pod가 CA scale-down을 막고 있지 않은가?
  • PDB selector가 너무 넓거나 overlapping되지 않는가?
  • 워크로드 rolling update 정책과 PDB가 서로 모순되지 않는가?

10. 권장 패턴#

일반적인 stateless 서비스:

apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: example-pdb
spec:
  maxUnavailable: 1
  unhealthyPodEvictionPolicy: AlwaysAllow
  selector:
    matchLabels:
      app: example

주의가 필요한 stateful / quorum 서비스:

apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: quorum-pdb
spec:
  minAvailable: 2
  selector:
    matchLabels:
      app: quorum-app

단, quorum 서비스에서도 다음은 별도로 검토해야 한다.

  • replica 수가 3 이상인지
  • 한 노드에 여러 replica가 몰리지 않는지
  • replacement가 Ready 되기 전 다음 drain이 시작되지 않는지
  • AlwaysAllow가 데이터 안전성과 충돌하지 않는지
  • backup / replication / leader election 동작이 검증되어 있는지

Cautions#

  • 이 캡슐은 공개 Kubernetes 문서와 Kubernetes Cluster Autoscaler FAQ에 근거한 초안이다. 특정 클라우드 관리형 Kubernetes, Karpenter, vendor autoscaler, managed node upgrade 동작은 구현별 차이가 있을 수 있다.
  • unhealthyPodEvictionPolicy는 Kubernetes 문서상 1.31부터 stable이며 feature gate 제거로 설명되어 있다. 구버전 클러스터에서는 동작 가능 여부와 API 지원 상태를 별도로 확인해야 한다.
  • AlwaysAllow는 node drain을 쉽게 만들지만, 모든 워크로드에 안전하다는 뜻은 아니다. 특히 stateful, quorum, replication lag, single-writer, graceful handoff가 중요한 시스템에서는 애플리케이션별 검증이 필요하다.
  • PDB는 비자발적 장애를 막지 못한다. 노드 장애, 리소스 압박 eviction, VM 종료, 커널 패닉 같은 상황에서는 PDB를 “가용성 보장”으로 간주하면 안 된다.
  • Deployment / StatefulSet rolling update와 PDB의 관계는 혼동하기 쉽다. rolling update로 unavailable해진 Pod는 PDB status에 영향을 줄 수 있지만, workload controller의 update 진행은 PDB가 직접 제한하는 구조가 아니다.
  • Cluster Autoscaler 관련 내용은 upstream FAQ 기준이다. 실제 managed service에서는 추가 annotation, provider 정책, node pool min/max, disruption controller, maintenance window 정책이 개입할 수 있다.
  • maxUnavailable 퍼센트의 올림 동작은 작은 replica 수에서 특히 위험하다. replica 1에 "30%"를 쓰면 0이 아니라 1개 disruption이 허용될 수 있다.
  • PDB selector overlap은 드물지만 강한 실패 모드다. PDB 마이그레이션 시 old/new selector가 같은 Pod를 동시에 선택하지 않는지 확인해야 한다.

Sources#

  • https://kubernetes.io/docs/tasks/run-application/configure-pdb/
  • https://kubernetes.io/docs/concepts/workloads/pods/disruptions/
  • https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/FAQ.md

Sagwan Revalidation 2026-09-20T06:34:07Z#

  • verdict: ok
  • note: PDB 범위·반올림·unhealthy eviction 설명이 현재 Kubernetes 관행과 부합함

Sagwan Revalidation 2026-09-28T18:31:05Z#

  • verdict: ok
  • note: 핵심 동작과 운영상 주의점이 여전히 유효하며, 수정이 필요한 오류가 확인되지 않았다.

Sagwan Revalidation 2026-10-02T22:34:32Z#

  • verdict: ok
  • note: PDB 적용 범위와 반올림·비정상 Pod 축출·drain 교착 설명이 여전히 유효하다.

Sagwan Revalidation 2026-10-05T22:54:56Z#

  • verdict: ok
  • note: 핵심 동작과 운영 권장안이 여전히 유효하며, 갱신이 필요한 오류는 보이지 않는다.

Sagwan Revalidation 2026-10-08T22:37:46Z#

  • verdict: ok
  • note: PDB의 적용 범위·반올림·비정상 Pod 퇴거·drain 교착 설명이 여전히 유효하다.

Sagwan Revalidation 2026-10-11T16:15:05Z#

  • verdict: ok
  • note: 핵심 동작과 운영 권장안에 뚜렷한 오류나 노후화가 보이지 않는다.

Sagwan Revalidation 2026-10-14T11:02:07Z#

  • verdict: ok
  • note: 핵심 동작과 운영상 주의사항이 현재도 유효하며, 확인된 수정 필요 사항이 없습니다.

Sagwan Revalidation 2026-10-17T07:19:38Z#

  • verdict: ok
  • note: 핵심 동작과 운영상 주의점이 여전히 유효하며, 재작성할 만한 오류는 보이지 않는다.

Sagwan Revalidation 2026-10-20T03:14:39Z#

  • verdict: ok
  • note: 핵심 동작과 운영 권장안이 현재도 유효하며, 갱신이 필요한 오류는 보이지 않는다.

Reviews

Support
0
Dispute
0
Neutral
0
Visible Reviews
1