Implement Kubernetes pod disruption budgets for high availability during scaling events

Intermediate 25 min Apr 27, 2026 20 views
Ubuntu 24.04 Debian 12 AlmaLinux 9 Rocky Linux 9

Configure Pod Disruption Budgets to ensure application availability during cluster maintenance and scaling operations. Learn to implement PDB policies, test disruption scenarios, and maintain service continuity in Kubernetes.

Prerequisites

  • Kubernetes cluster with kubectl access
  • Administrative privileges on the cluster
  • At least 2 worker nodes for testing

What this solves

Pod Disruption Budgets (PDBs) protect your applications from voluntary disruptions during cluster maintenance, node drains, and scaling operations. Without PDBs, Kubernetes may terminate all replicas of a service simultaneously, causing downtime during routine operations like cluster upgrades or node maintenance.

Understanding Pod Disruption Budgets

A Pod Disruption Budget defines the minimum number or percentage of pods that must remain available during voluntary disruptions. Kubernetes respects these constraints when performing operations like node drains, ensuring your applications maintain availability.

PDBs only protect against voluntary disruptions (maintenance, scaling) not involuntary ones (node failures, hardware issues). They work by preventing the eviction API from removing pods below your specified threshold.

Note: PDBs require at least 2 replicas to be effective. Single-replica deployments cannot guarantee availability during disruptions.

Step-by-step configuration

Verify kubectl access

Confirm you have administrative access to your Kubernetes cluster.

kubectl cluster-info
kubectl get nodes

Create a sample application

Deploy a multi-replica application to demonstrate PDB functionality.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
  namespace: default
spec:
  replicas: 4
  selector:
    matchLabels:
      app: web-app
  template:
    metadata:
      labels:
        app: web-app
    spec:
      containers:
      - name: nginx
        image: nginx:1.25
        ports:
        - containerPort: 80
        resources:
          requests:
            cpu: 100m
            memory: 64Mi
          limits:
            cpu: 200m
            memory: 128Mi
---
apiVersion: v1
kind: Service
metadata:
  name: web-app-service
spec:
  selector:
    app: web-app
  ports:
  - port: 80
    targetPort: 80
  type: ClusterIP

Apply the deployment

Create the application deployment and service.

kubectl apply -f web-app-deployment.yaml
kubectl get pods -l app=web-app

Create a Pod Disruption Budget with minimum available

Configure a PDB ensuring at least 2 pods remain available during disruptions.

apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: web-app-pdb-min
  namespace: default
spec:
  minAvailable: 2
  selector:
    matchLabels:
      app: web-app

Create a Pod Disruption Budget with maximum unavailable

Alternative PDB configuration limiting disruptions to 50% of pods.

apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: web-app-pdb-max
  namespace: default
spec:
  maxUnavailable: 50%
  selector:
    matchLabels:
      app: web-app

Apply the Pod Disruption Budget

Choose one PDB configuration and apply it to your cluster.

kubectl apply -f web-app-pdb-min.yaml
kubectl get pdb

Create PDB for critical system components

Configure PDBs for essential services like DNS and ingress controllers.

apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: coredns-pdb
  namespace: kube-system
spec:
  minAvailable: 1
  selector:
    matchLabels:
      k8s-app: kube-dns
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: ingress-nginx-pdb
  namespace: ingress-nginx
spec:
  minAvailable: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: ingress-nginx

Apply system PDBs

Protect critical cluster components with disruption budgets.

kubectl apply -f system-pdbs.yaml
kubectl get pdb --all-namespaces

Testing PDB behavior

Test node drain with PDB protection

Simulate maintenance by draining a node to observe PDB enforcement.

# Identify node with your pods
kubectl get pods -l app=web-app -o wide

Drain the node (replace NODE_NAME)

kubectl drain NODE_NAME --ignore-daemonsets --delete-emptydir-data

Monitor pod evictions in another terminal

kubectl get pods -l app=web-app -w

Verify PDB status during drain

Check PDB status to see how it prevents excessive pod evictions.

kubectl get pdb web-app-pdb-min -o yaml
kubectl describe pdb web-app-pdb-min

Test manual pod eviction

Attempt to evict pods manually to verify PDB protection.

# Get pod name
POD_NAME=$(kubectl get pods -l app=web-app -o jsonpath='{.items[0].metadata.name}')

Try to evict the pod

kubectl delete pod $POD_NAME

Check remaining pods

kubectl get pods -l app=web-app

Restore node availability

Uncordon the drained node to restore normal scheduling.

kubectl uncordon NODE_NAME
kubectl get nodes

Advanced PDB configurations

Create PDB with unhealthy pod handling

Configure PDB behavior when pods are unhealthy or not ready.

apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: web-app-advanced-pdb
  namespace: default
spec:
  minAvailable: 2
  selector:
    matchLabels:
      app: web-app
  unhealthyPodEvictionPolicy: AlwaysAllow

Create namespace-scoped PDB

Configure PDBs for specific namespaces to organize policies.

# Create production namespace
kubectl create namespace production

Create PDB for production namespace

kubectl apply -f - <

Configure PDB with label selectors

Use complex label selectors for precise pod targeting.

apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: multi-tier-pdb
  namespace: default
spec:
  minAvailable: 1
  selector:
    matchExpressions:
    - key: tier
      operator: In
      values:
      - frontend
      - backend
    - key: environment
      operator: NotIn
      values:
      - development

Monitoring and alerting

Create PDB monitoring script

Monitor PDB violations and disruption events with a monitoring script.

#!/bin/bash

echo "=== Pod Disruption Budget Status ==="
kubectl get pdb --all-namespaces -o wide

echo "\n=== PDB Details ==="
for pdb in $(kubectl get pdb --all-namespaces -o jsonpath='{range .items[*]}{.metadata.namespace}{" "}{.metadata.name}{"\n"}{end}'); do
    namespace=$(echo $pdb | cut -d' ' -f1)
    name=$(echo $pdb | cut -d' ' -f2)
    
    echo "\nPDB: $namespace/$name"
    kubectl get pdb $name -n $namespace -o jsonpath='{"Allowed Disruptions: "}{.status.disruptionsAllowed}{"\n"}'
    kubectl get pdb $name -n $namespace -o jsonpath='{"Current Healthy: "}{.status.currentHealthy}{"\n"}'
    kubectl get pdb $name -n $namespace -o jsonpath='{"Desired Healthy: "}{.status.desiredHealthy}{"\n"}'
done

echo "\n=== Recent Events ==="
kubectl get events --sort-by=.metadata.creationTimestamp | grep -i disruption

Make monitoring script executable

Set proper permissions and test the monitoring script.

chmod +x monitor-pdb.sh
./monitor-pdb.sh

Verify your setup

# Check all PDBs
kubectl get pdb --all-namespaces

Verify PDB status

kubectl describe pdb web-app-pdb-min

Check pod distribution

kubectl get pods -l app=web-app -o wide

Verify node status

kubectl get nodes

Test PDB API

kubectl get pdb -o json | jq '.items[].status'

Common issues

SymptomCauseFix
PDB shows 0 allowed disruptions Not enough healthy pods Check pod status: kubectl get pods -l app=web-app
Node drain hangs indefinitely PDB preventing eviction Scale up replicas or adjust PDB: kubectl scale deployment web-app --replicas=6
PDB not selecting any pods Incorrect label selector Verify labels match: kubectl get pods --show-labels
Pods evicted despite PDB Involuntary disruption Check node status and events: kubectl describe node NODE_NAME
PDB conflicts with other PDBs Overlapping selectors Review all PDBs: kubectl get pdb -o yaml

Next steps

Running this in production?

Ready for production workloads? Setting this up once is straightforward. Keeping it patched, monitored, backed up and performant across environments is the harder part. See how we run infrastructure like this for European teams.

Need help?

Don't want to manage this yourself?

We handle managed devops services for businesses that depend on uptime. From initial setup to ongoing operations.