Pod disruption budgets: keeping maintenance from removing too many replicas
Understand how Kubernetes PodDisruptionBudgets constrain voluntary eviction, why drains stall, and how readiness and replacement capacity affect maintenance.
TL;DR: A PodDisruptionBudget (PDB) limits how many selected pods can be voluntarily disrupted through the Kubernetes eviction API. It gives node maintenance a workload-specific availability constraint. A drain may have to wait for a replacement to become healthy before it can evict another pod.
The guarantee has boundaries. A PDB cannot prevent a node failure, and deleting a pod directly bypasses the eviction check. Workload controllers also manage their own rolling updates. A Deployment's rollout settings therefore remain necessary even when its pods have a PDB. Unavailable pods from those events still reduce the room for a subsequent voluntary eviction. Kubernetes disruptions explains these separate responsibilities.
Work through the budget before draining
Consider three replicas of a repair API. The service owner has measured that two healthy replicas can carry the expected maintenance traffic. This example permits one unavailable replica:
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: repair-api
namespace: workshop
spec:
maxUnavailable: 1
selector:
matchLabels:
app: repair-api
The namespace and labels must match the actual workload. Use either minAvailable or maxUnavailable, never both. In policy/v1, an empty selector matches every pod in the namespace, so an accidentally empty selector can constrain unrelated services.
Assuming a supported controller reports three desired replicas, the budget requires two healthy pods. With all three healthy and no eviction in progress, one disruption is allowed. After one becomes unavailable, the next eviction waits. The disruption controller's observed status matters; computing a number from yesterday's replica count does not authorize today's drain.
| Configuration and desired replicas | Required healthy replicas | Allowance when all are healthy |
|---|---|---|
maxUnavailable: 1, three replicas | 2 | 1 |
minAvailable: 2, three replicas | 2 | 1 |
minAvailable: "80%", three replicas | 3 | 0 |
maxUnavailable: "30%", one replica | 0 | 1 |
Percentage values round up. The last row can permit the only replica to be disrupted, despite the small-looking percentage. Prefer integer budgets for small replica sets when the maintenance contract is a specific number of survivors. These rounding rules and selector semantics are documented in configuring a PDB.
Why a safe drain can get stuck
Suppose the first eviction succeeds, but its replacement stays Pending because the remaining nodes lack memory. The second eviction is correctly blocked. Relaxing the budget may finish the infrastructure operation while breaking the service's capacity requirement. Add schedulable capacity or resolve the placement constraint first. A spare node in the wrong zone will not help a volume that can attach only in the original zone.
Inspect the budget's currentHealthy, desiredHealthy, and disruptionsAllowed, then compare its selector with pod labels. Read pending-pod events and readiness failures. A pod that is running but fails its readiness probe does not restore the healthy count. A probe that passes before the application can serve traffic creates the opposite problem: maintenance proceeds on a false signal.
For already unhealthy pods, unhealthyPodEvictionPolicy: AlwaysAllow can let a drain remove broken instances that would otherwise stall it. Kubernetes recommends this setting for that purpose. Confirm that the cluster supports the field and that replacement and data-recovery behavior fit the workload. It does not grant extra permission to evict healthy pods beyond their budget.
Availability still depends on the application
A three-member consensus database may require two communicating members for quorum, but three Ready pods alone do not prove that quorum exists. Replication lag, leader placement, and shared failure domains need separate checks. Use a PDB alongside application-aware health and topology placement; see StatefulSet identity and storage.
A useful maintenance rehearsal records the time from eviction to a serving replacement, checks client errors throughout, and includes a constrained-capacity case. This exposes a budget that looks correct in YAML but makes routine upgrades impossible. Schedule enough maintenance time for graceful termination and replacement startup instead of repeatedly forcing the drain.
Check your understanding
Three desired replicas use minAvailable: 2. One pod is already unready. How many healthy pods can maintenance evict now? None, assuming the other two are healthy and status is current. The existing unhealthy pod has consumed the spare capacity.
An interviewer says the PDB guarantees that two replicas survive a zone outage. What is missing? PDBs cannot stop involuntary failures. Replica placement across failure domains, available capacity after the outage, and application behavior determine the outcome. The budget governs permitted maintenance evictions.