Kubernetes Pod Disruption Budget PDB Guide
Protect application availability with Kubernetes PodDisruptionBudgets. Configure minAvailable and maxUnavailable for voluntary disruptions like node
π‘ Quick Answer: A PodDisruptionBudget (PDB) limits how many pods can be simultaneously unavailable during voluntary disruptions (node drain, cluster upgrade, autoscaler). Set
minAvailable: 2(always keep at least 2 running) ormaxUnavailable: 1(remove at most 1 at a time). PDBs protect againstkubectl drainand voluntary evictions but NOT against crashes or resource limits.
The Problem
- Node drain during maintenance evicts all pods on that node simultaneously
- Cluster autoscaler removing nodes can kill critical services
- Kubernetes upgrades rolling nodes leave services with zero replicas briefly
- Need to guarantee minimum available replicas during planned disruptions
- Rolling updates + node drains can combine to take down all replicas
The Solution
Basic PDB (minAvailable)
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: api-server-pdb
namespace: production
spec:
minAvailable: 2 # Always keep at least 2 pods running
selector:
matchLabels:
app: api-serverPDB with maxUnavailable
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: api-server-pdb
namespace: production
spec:
maxUnavailable: 1 # At most 1 pod can be disrupted at a time
selector:
matchLabels:
app: api-serverPercentage-Based PDB
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: worker-pdb
spec:
maxUnavailable: "25%" # Allow 25% of pods to be unavailable
selector:
matchLabels:
app: worker
# With 10 replicas: at most 2 can be disrupted simultaneously (ceil 25% of 10 = 2.5 β 2)When PDB Blocks Drain
# Attempt to drain a node
kubectl drain node-1 --ignore-daemonsets
# If PDB would be violated:
# error when evicting pods/api-server-xyz: Cannot evict pod as it would violate
# the pod's disruption budget. The disruption budget api-server-pdb needs 2 healthy
# pods and has 2, but we can only tolerate 0 disruptions.
# Force drain (bypasses PDB β use with extreme caution)
kubectl drain node-1 --ignore-daemonsets --force --delete-emptydir-dataCheck PDB Status
kubectl get pdb -n production
# NAME MIN AVAILABLE MAX UNAVAILABLE ALLOWED DISRUPTIONS AGE
# api-server-pdb 2 N/A 1 5d
# worker-pdb N/A 25% 3 5d
kubectl describe pdb api-server-pdb -n production
# Status:
# Current Healthy: 3
# Desired Healthy: 2
# Disruptions Allowed: 1
# Expected Pods: 3PDB for StatefulSets
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: database-pdb
spec:
maxUnavailable: 1 # Only 1 replica down at a time (safe for quorum)
selector:
matchLabels:
app: database
# For a 3-node database cluster: ensures quorum (2/3) is maintainedCommon PDB Patterns
Workload Type β Replicas β Recommended PDB
ββββββββββββββββββββββΌβββββββββββΌββββββββββββββββββββββββββ
Stateless API β 3 β maxUnavailable: 1
Stateless API β 10 β maxUnavailable: 25%
Database (quorum) β 3 β minAvailable: 2
Database (quorum) β 5 β minAvailable: 3
Message queue β 3 β maxUnavailable: 1
Singleton (1 replica)β 1 β minAvailable: 1 (blocks all drains!)
Worker pool β 20 β maxUnavailable: 5
ββββββββββββββββββββββ΄βββββββββββ΄ββββββββββββββββββββββββββUnhealthy Pod Eviction (K8s 1.27+)
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: api-server-pdb
spec:
maxUnavailable: 1
selector:
matchLabels:
app: api-server
unhealthyPodEvictionPolicy: AlwaysAllow
# AlwaysAllow: unhealthy pods can always be evicted (don't count toward budget)
# IfHealthyBudget: only evict unhealthy pods if budget allows (default)Common Issues
PDB blocking node drain indefinitely
- Cause: Deployment has fewer ready pods than PDB requires; or single-replica with minAvailable: 1
- Fix: Scale up first; fix unhealthy pods; or use
maxUnavailable: 1instead ofminAvailablefor single-replica
PDB not protecting during rolling update
- Cause: Rolling updates are managed by the Deployment controller, which respects
maxUnavailablein strategy, not PDB - Fix: PDB protects against external disruptions (drain); Deployment strategy protects during updates. Configure both.
Cluster autoscaler canβt scale down
- Cause: PDB blocking eviction of pods on underutilized nodes
- Fix: Ensure
ALLOWED DISRUPTIONS > 0; scale up replicas; or reduceminAvailable
βCannot evictβ for pods without controller
- Cause: Bare pods (no Deployment/ReplicaSet owner) wonβt be recreated after eviction
- Fix: Use
kubectl drain --forceor (better) always use Deployments
Best Practices
- Every production Deployment should have a PDB β protect against unexpected drains
- Use
maxUnavailableoverminAvailableβ scales better with replica count - Donβt set
minAvailable= replicas β blocks ALL voluntary disruptions (drains stuck forever) - Ensure disruptions allowed > 0 β or node maintenance becomes impossible
- Pair with anti-affinity β spread pods across nodes so drain only hits 1 pod
- Use
unhealthyPodEvictionPolicy: AlwaysAllowβ donβt let stuck pods block drains - Single-replica services β
maxUnavailable: 1(allows drain);minAvailable: 1(blocks drain)
Key Takeaways
- PDB limits voluntary disruptions: node drains, cluster upgrades, autoscaler scale-down
- Does NOT protect against: crashes, OOMKilled, node failures (involuntary)
minAvailable: minimum pods that must stay runningmaxUnavailable: maximum pods that can be simultaneously disrupted- Percentage values:
maxUnavailable: "25%"adapts to replica count kubectl get pdbshowsALLOWED DISRUPTIONSβ must be > 0 for drains to work- Combine with pod anti-affinity for true HA across nodes

Recommended
Kubernetes Recipes β The Complete Book100+ production-ready patterns with detailed explanations, best practices, and copy-paste YAML. Everything in one place.
Get the Book βLearn by Doing
CopyPasteLearn β Hands-on Cloud & DevOps CoursesMaster Kubernetes, Ansible, Terraform, and MLOps with interactive, copy-paste-run lessons. Start free.
Browse Courses βπ Deepen Your Skills β Hands-on Courses
Courses by CopyPasteLearn.com β Learn IT by Doing
