PodDisruptionBudget Basics
Learn to implement PodDisruptionBudget for availability in Kubernetes — hands-on steps to protect workloads during disruptions.
Focus: implement poddisruptionbudget for availability
You've built a resilient Kubernetes cluster, but what happens when you need to drain a node for maintenance or a cluster autoscaler decides to scale down? Without a safety net, your application could experience downtime during these voluntary disruptions. PodDisruptionBudgets (PDBs) are that net—a Kubernetes-native way to guarantee a minimum number of your pods remain available during controlled operations. This lesson teaches you how to implement PodDisruptionBudget for availability, ensuring your critical workloads survive node drains, upgrades, and cluster scaling events without a hiccup.
The problem this lesson solves
Kubernetes admins and operators frequently perform actions that intentionally terminate pods: rolling out a new node image, draining a node for patching, or scaling down a cluster. These are called voluntary disruptions. While a single pod restart is often harmless, a large-scale drain can wipe out every replica of a service at once, causing a full outage.
Consider a three-replica deployment of a payment processing API. If you drain the three nodes hosting those replicas without constraints, Kubernetes evicts all three pods. Your service becomes unavailable until new pods spin up on remaining nodes. Users see 503 errors, and you scramble to explain why a routine maintenance window turned into an incident.
PodDisruptionBudget exists to solve exactly this. It lets you declare: "During all voluntary disruptions, I need at least N pods of this application to stay running at all times." Kubernetes respects this contract, blocking evictions that would violate it and only proceeding when there's enough spare capacity.
Core concept / mental model
Think of a PDB as a runway for evictions. Imagine an airport with a single runway. Each plane (pod) needs to land or take off. If you try to land three planes at once, gridlock. The PDB is like air traffic control: "You can send one plane at a time, and only so many planes can be in the air simultaneously."
Formally, a PDB is a Kubernetes resource that specifies:
- Selector: a label query to identify the pods it protects (usually matching a deployment's
applabel). - Budget: expressed as
minAvailable(minimum number of pods that must be healthy) ormaxUnavailable(maximum number of pods that can be unavailable at once).
Pro tip:
minAvailableandmaxUnavailableare mutually exclusive in a PDB spec. Choose the one that matches your intent: "I want at least 2 running" → useminAvailable: 2; "I can tolerate at most 1 down" → usemaxUnavailable: 1.
Key distinction: voluntary vs. involuntary disruptions
- Voluntary disruptions: Node drains, cluster scaling down, rolling updates of a DaemonSet — actions you control. PDBs restrict these.
- Involuntary disruptions: Node crashes, disk failures, network partitions — hardware/software failures. PDBs do not prevent these; they only limit the impact during controlled evictions.
By implementing a PDB, you trade off flexibility for availability: you can't drain a node fast if it hosts critical pods, but your users never see a full outage.
How it works step by step
- Create a PDB resource with
kubectl apply. You define the selector and eitherminAvailableormaxUnavailable. - Kubernetes controller watches the PDB. The kube-controller-manager tracks pod evictions, monitoring how many matching pods are healthy.
- Voluntary disruption requested (e.g.,
kubectl drain node-1). The drain operation first checks the PDB: does evicting this pod violate the budget? - If the budget would be broken (e.g.,minAvailable: 2and only 1 would remain), eviction is blocked. The drain command hangs until enough pods become available. - If the budget is satisfied (e.g.,maxUnavailable: 1and only 1 is already down), the eviction proceeds. - Pod is evicted and rescheduled elsewhere, but only if the budget remains intact.
Causal chain: No PDB → drain can evict all pods → service disabled. With PDB → drain blocks until safe → service stays up.
Hands-on walkthrough
Let's implement a PDB for a sample web app deployment.
Prerequisites
- A Kubernetes cluster (Minikube, Kind, or a real one)
kubectlinstalled
Step 1: Create a deployment
# sample-webapp.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: webapp
spec:
replicas: 3
selector:
matchLabels:
app: webapp
template:
metadata:
labels:
app: webapp
spec:
containers:
- name: nginx
image: nginx:1.26
ports:
- containerPort: 80
Apply it:
kubectl apply -f sample-webapp.yaml
Step 2: Create the PodDisruptionBudget
# webapp-pdb.yaml
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: webapp-pdb
spec:
minAvailable: 2
selector:
matchLabels:
app: webapp
kubectl apply -f webapp-pdb.yaml
Verify it works and check status:
kubectl get pdb webapp-pdb
Expected output (columns may vary):
NAME MIN AVAILABLE MAX UNAVAILABLE ALLOWED DISRUPTIONS AGE
webapp-pdb 2 N/A 1 5s
ALLOWED DISRUPTIONS shows how many pods can be evicted without violating the budget — here, it's 1 (because 3 total, minAvailable 2 → at most 1 can be down).
Step 3: Test eviction blocking
Try draining one of the nodes where a webapp pod runs:
# First, find a node running a webapp pod
kubectl get pods -o wide | grep webapp
# Then attempt to drain that node (replace node-1 with actual node name)
kubectl drain node-1 --ignore-daemonsets
Observe: the drain command hangs because evicting that pod would drop the available count below 2. Press Ctrl+C to cancel. This is working as intended: your budget prevents the disruption.
Step 4: Scale up to test allowed disruption
Increase deployment replicas to 5:
kubectl scale deployment/webapp --replicas=5
Now drain a node again. With 5 replicas and minAvailable: 2, you have 3 allowed disruptions — the eviction proceeds smoothly.
Compare options / when to choose what
PDBs can be defined with minAvailable (absolute number or percentage) or maxUnavailable. The table below helps you choose.
| Budget type | Syntax example | Best for | Downside |
|---|---|---|---|
| minAvailable (absolute) | minAvailable: 2 |
Small, fixed-size deployments | Doesn't scale with replicas |
| minAvailable (percent) | minAvailable: 50% |
Deployments with variable replicas | Rounded down, may be 0 for 1 replica |
| maxUnavailable (absolute) | maxUnavailable: 1 |
Tolerant workloads; allows rolling | Can lead to cascading failures on small deployments |
| maxUnavailable (percent) | maxUnavailable: 25% |
Large, multi-instance services | Same rounding issue |
Pro tip: For critical stateful apps (databases, message queues), prefer
minAvailablewith a hard number like 2 or 3. For stateless web tiers with 10+ replicas,maxUnavailable: 25%is common.
When not to use a PDB
- Single-replica deployments: A PDB with
minAvailable: 1makes a single pod un-evictable, which renders node drains impossible. Use with caution or skip. - Batch jobs: PDBs only apply to pods controlled by controllers (Deployments, StatefulSets). Batch jobs auto-terminate.
Troubleshooting & edge cases
Problem: Drain hangs forever
Cause: PDB is too restrictive, or pods aren't being replaced quickly enough.
Fix: Either increase minAvailable (lower the number) or scale up the deployment temporarily. Check kubectl describe pdb webapp-pdb for current status.
Problem: PDB shows 0 allowed disruptions
Cause: Either no pods match the selector, or all matching pods are unhealthy (not Ready).
Fix: Verify labels match your deployment. Check pod readiness with kubectl get pods -l app=webapp.
Edge case: Rolling update during drain
A deployment rolling update also counts as a voluntary disruption. If you drain a node while a rollout is in progress, the PDB might block evictions even if pods exist—because some pods are being terminated by the rollout. Solve by sequencing: finish the rollout, then drain.
Misconception: PDB protects against all disruptions
PDBs only guard voluntary disruptions (node drains, cluster scale-down). Involuntary failures (node crash, disk failure) can still take down pods. Use anti-affinity, multi-zone deployments, and cluster autoscaler in addition.
What you learned & what's next
You now understand how to implement PodDisruptionBudget for availability — you can explain the problem (voluntary disruptions causing outages), define the mental model (air traffic control for evictions), create a PDB with minAvailable, test eviction blocking, and troubleshoot common issues. You've completed a hands-on exercise and know when to choose absolute vs. percentage budgets.
Your next lesson covers topology spread constraints — ensuring your pods are evenly distributed across failure domains (zones, nodes) to maximize availability even during involuntary disruptions. Combined with PDBs, you'll build rock-solid applications.
# Quick tip: delete your test resources
kubectl delete pdb webapp-pdb
kubectl delete deployment webapp
Practice recap
Create a deployment with 4 replicas and a PDB with minAvailable: 3. Then simulate a node drain on a node running one of those pods. Verify the drain blocks initially. Scale the deployment to 6 replicas and observe that the drain can now proceed. Use kubectl describe pdb to see the allowed disruptions change.
Common mistakes
- Creating a PDB with
minAvailableequal to the number of replicas (e.g.,minAvailable: 3for 3 replicas) – this makes eviction impossible for any pod and can block all node drains. - Forgetting to match labels exactly between the PDB selector and the deployment’s pod template labels, resulting in a PDB that applies to zero pods and provides no protection.
- Using
maxUnavailable: 0orminAvailable: 100%on a single-replica deployment – these effectively pin the pod and prevent any voluntary disruptions. - Assuming a PDB protects against involuntary failures (node crashes, disk issues) – it only limits voluntary disruptions like node drains and cluster scaling.
Variations
- Use
maxUnavailableinstead ofminAvailablefor deployments where you know the tolerable downtime, e.g.,maxUnavailable: 1for a 5-replica web tier. - Apply percentage-based budgets (
minAvailable: 80%) for auto-scaled deployments where replica count varies over time. - Combine PDBs with Pod Anti-Affinity to ensure pods are spread across nodes, so a single node drain affects at most one replica.
Real-world use cases
- Protecting a 3-replica payment gateway during a Kubernetes node upgrade – a PDB with
minAvailable: 2ensures the service never goes down. - Allowing cluster autoscaler to scale down safely for a stateless web app by using
maxUnavailable: 1across 10+ replicas. - Preventing a stateful database cluster (e.g., Cassandra with 5 nodes) from losing quorum during a rolling node patching – using
minAvailable: 3.
Key takeaways
- PodDisruptionBudget limits voluntary disruptions (node drains, scaling) by enforcing a minimum number of pods that must remain healthy.
- Use
minAvailable(absolute or percent) for critical apps; usemaxUnavailablefor tolerant, large deployments. - A PDB does not protect against involuntary failures – combine it with anti-affinity and multi-zone deployments.
- Label selectors must match exactly – a mismatched PDB applies to zero pods and provides no safety.
- Too strict a PDB can block all evictions, making node drains impossible; always account for maintenance needs.
Keep learning
Related tutorials, quizzes, and articles for this topic.
Discussion
Questions, corrections, and tips help everyone reading this page.
0 comments
Add a comment
No comments yet — start the thread.