Keep Your Kubernetes Apps Running with PodDisruptionBudgets


In a busy Kubernetes cluster, pods come and go. Nodes get upgraded. Maintenance happens. When that occurs, some pods may be removed. If we're not careful, critical services can go down—even briefly. That moment of silence may break an app or cause lost data.


This is where a PodDisruptionBudget (PDB) steps in. It acts like a safety line. It tells Kubernetes: “Don’t remove too many pods at once.”
With PDBs, we gain control over disruptions. We ensure high availability. Our users stay happy. Let’s understand how this works.


What is a PodDisruptionBudget (PDB)?

A PodDisruptionBudget sets a limit on how many pods can be taken down during voluntary disruptions. These include:
  • Node drains (for upgrades or maintenance)
  • Cluster autoscaling
  • Manual deletions
PDBs do not block involuntary disruptions. If a node crashes, Kubernetes still tries to reschedule pods as usual.
With a PDB, we define:
  • minAvailable: The minimum number of pods that must be available.
  • or
  • maxUnavailable: The maximum number of pods that can be taken down at once.
We tie a PDB to a set of pods using labels. Kubernetes checks the labels to find which pods it should protect.


Why should we use PodDisruptionBudget?

Without a PodDisruptionBudget, Kubernetes might evict all pods of a service at once, which can lead to user outages or broken sessions. 

In the case of stateful applications, this can cause a loss of quorum, leading to crashes and data issues. With a PDB in place, we ensure that enough pods stay running to keep services available during upgrades or node maintenance. It gives us a safeguard against unexpected disruptions and helps maintain system stability during scaling or operational changes.



How to create a PodDisruptionBudget

Let’s walk through an example. We will:
  1. Deploy a simple app with 3 replicas.
  2. Add a PodDisruptionBudget to protect it.
  3. Test how it works during a node drain.


Step 1: Deploy an App

We start with a basic deployment. Save this as nginx-deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80

Apply it:

kubectl apply -f nginx-deployment.yaml

Wait for all 3 pods to become ready:

kubectl get pods -l app=nginx


Step 2: Add a PodDisruptionBudget

Create a file named nginx-pdb.yaml:

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

This tells Kubernetes - keep at least 2 nginx pods running at all times. Then, apply it:

kubectl apply -f nginx-pdb.yaml

Check the status:

kubectl get pdb nginx-pdb

You’ll see something like this:

NAME        MIN AVAILABLE   ALLOWED DISRUPTIONS   AGE
nginx-pdb 2 1 5s

This means: only 1 pod can be taken down at once.


Step 3: Test with Node Drain

Find the node running one of the nginx pods:

kubectl get pod -o wide -l app=nginx

Then drain that node:

kubectl drain <node-name> --ignore-daemonsets --delete-emptydir-data

If only one pod is affected, it should succeed. Try draining a second node. Kubernetes will block it because it would violate the PDB.

This shows the power of a PDB. It prevents too much disruption at once.

 

Previous Post Next Post