How to Configure Pod Disruption Budgets in Kubernetes
Configure and test Kubernetes PodDisruptionBudgets for safe drains and upgrades without mistaking eviction limits for an availability guarantee.
A PodDisruptionBudget (PDB) limits how many replicas of a workload can be down simultaneously due to voluntary disruptions — node drains, cluster upgrades, autoscaler scale-downs — protecting availability during planned operational events, distinct from involuntary failures a PDB has no control over.
Step 1: understand voluntary vs. involuntary disruption first
A PDB only governs voluntary disruptions — actions initiated deliberately, like draining a node for maintenance. It has no effect on involuntary disruptions like a node crashing unexpectedly or a pod being OOMKilled — those aren’t something a PDB can prevent.
Step 2: create a PDB specifying minimum available replicas
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: myapp-pdb
spec:
minAvailable: 2
selector:
matchLabels:
app: myapp
This guarantees at least 2 pods matching app: myapp remain available at all times during voluntary disruptions — kubectl drain on a node hosting one of these pods will respect this and wait rather than evicting a pod that would violate it.
More precisely, the eviction API refuses a voluntary eviction that would take healthy matching pods below the threshold. A PDB cannot guarantee that two pods are serving customers: readiness may be wrong, both pods may share a failure domain, or the application itself can be unhealthy. Pair it with accurate probes and topology spread or anti-affinity.
Step 3: alternatively, specify maximum unavailable replicas
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: myapp-pdb
spec:
maxUnavailable: 1
selector:
matchLabels:
app: myapp
maxUnavailable can be convenient when a workload’s desired scale changes because the calculation follows its controller. Percentages are also allowed, but Kubernetes rounds them according to documented rules; test small replica counts because rounding can permit more disruption than intuition suggests. Specify only one of minAvailable or maxUnavailable.
Step 4: apply the PDB
kubectl apply -f myapp-pdb.yaml
Step 5: verify the PDB’s current status
kubectl get pdb myapp-pdb
This shows ALLOWED DISRUPTIONS — the number of pods that could currently be voluntarily evicted without violating the budget, a directly useful number when planning a maintenance operation.
Compare CURRENT HEALTHY, DESIRED HEALTHY, and EXPECTED PODS, and inspect the selected pods. A selector error can produce an object that protects the wrong workload or none. In policy/v1, an empty selector matches all pods in the namespace; do not use ambiguous selectors intentionally.
Step 6: test the PDB actually blocks an over-aggressive drain
kubectl drain NODE_NAME --ignore-daemonsets --dry-run=server
Start with server-side dry run where supported, then test a real drain only in a disposable environment with a recovery plan. kubectl drain retries eviction while a PDB blocks it and can wait for replacements to become Ready. Forced or direct pod deletion can bypass eviction protections; access controls and runbooks should prevent operators from treating force as routine.
Step 7: use a PDB alongside a properly configured replica count
A PDB with minAvailable: 2 on a deployment running only 2 replicas total leaves zero tolerance for any voluntary disruption at all — the PDB and the actual replica count need to be considered together, not configured independently, for the budget to provide genuine flexibility during maintenance.
A drain can also stall when replacement pods cannot schedule because of insufficient capacity, affinity, quota, or a broken image. Confirm spare capacity before maintenance. Multiple PDBs can select the same pod, and an eviction must satisfy all applicable budgets, so audit overlapping selectors.
Step 8: check PDB status during an actual cluster upgrade or node maintenance event
kubectl get pdb -A
Reviewing this across all namespaces before a planned cluster-wide maintenance operation shows exactly which workloads have protection configured — and, implicitly, which ones don’t and might be more exposed to disruption during the maintenance window.
For unhealthy pods, current Kubernetes supports unhealthyPodEvictionPolicy. IfHealthyBudget is the conservative behavior; AlwaysAllow can help drain a node containing a permanently unready pod when other safeguards exist. Choose deliberately and confirm the cluster version supports the field.
Know what a PDB does not cover
A PDB does not constrain Deployment rolling updates; the controller’s maxUnavailable and maxSurge settings govern them. It does not prevent node failure, preemption, resource pressure, OOM termination, or administrator deletion. It also does not create replicas or distribute them across zones.
Monitor budgets reporting zero allowed disruptions for long periods before automated upgrades or autoscaler activity. The correct fix may be more replicas, spare capacity, a corrected readiness probe, or a revised availability objective—not weakening the budget until a drain succeeds.
Why PDBs matter specifically during cluster upgrades and autoscaling events
Without a PDB, a node drain or cluster autoscaler scale-down has no built-in awareness of how many replicas of a given service it’s safe to take down at once — it could, in principle, evict every replica of a critical service simultaneously if they happened to land on nodes being drained together. A PDB is the mechanism that makes “always keep at least N replicas up” an enforced constraint during these voluntary operations, rather than a hope resting on replica placement working out favorably by chance.
Related:
Sources: