Safe Rollouts & PodDisruptionBudgets
Rolling updates protect you from bad deploys; PodDisruptionBudgets protect you from the cluster itself during node drains and upgrades.
You already know rolling updates replace Pods gradually. Two things separate a hobby rollout from a production one: tuning the surge so you never dip below capacity, and adding a PodDisruptionBudget (PDB) so voluntary disruptions cannot wipe out your app.
Voluntary vs involuntary disruption
A node crashing is involuntary — nothing can stop it. But draining a node for an upgrade, a cluster autoscaler scaling down, or kubectl drain are voluntary. A PDB tells Kubernetes: "you may evict my Pods for maintenance, but never take me below this floor." During a rolling node upgrade the eviction API respects your PDB and drains one node at a time only when it is safe.
minAvailable vs maxUnavailable
minAvailable: 2— always keep at least 2 Pods serving.maxUnavailable: 1— never take more than 1 Pod down at once (scales naturally as you grow replicas).
The gotcha that pins a node forever
A PDB of minAvailable: 1 on a Deployment with a single replica means the node can never be drained — the eviction is refused forever and your cluster upgrade hangs. PDBs assume you run more than one replica. Combine the PDB with readiness gates so surging Pods actually pass health checks before old ones leave.
Example
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 4
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 0 # never dip below full capacity
maxSurge: 1 # bring up one extra, then retire an old one
selector:
matchLabels: { app: web }
template:
metadata:
labels: { app: web }
spec:
containers:
- name: web
image: nginx:1.27
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: web-pdb
spec:
maxUnavailable: 1 # node drains take at most 1 web Pod at a time
selector:
matchLabels: { app: web }When to use it
- A team creates a PodDisruptionBudget requiring minAvailable=2 so that rolling updates and node drains never take a three-replica service below two running pods.
- An SRE uses maxSurge=2 and maxUnavailable=0 to get zero-downtime rolling updates by always bringing new pods up before old ones are removed.
- A platform team uses Argo Rollouts for canary releases, sending 10% of traffic to the new version and watching error rates before promoting to 100%.
More examples
PodDisruptionBudget
Guarantees at least 2 API pods remain running during voluntary disruptions like Deployment rollouts or node drains.
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: api-pdb
spec:
minAvailable: 2
selector:
matchLabels:
app: apiZero-downtime rolling update config
Configures maxUnavailable=0 so old pods are only removed after new pods pass readiness checks, achieving zero-downtime updates.
spec:
replicas: 4
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 0 # Never remove old pod before new is ready
maxSurge: 2 # Run 2 extra pods during the updateVerify rollout progress
Monitors a rolling update to completion and reviews the revision history to confirm the change cause annotation.
kubectl rollout status deployment/api
# Waiting for deployment api rollout to finish: 2 of 4 new replicas have been updated...
# deployment api successfully rolled out
kubectl rollout history deployment/api
# REVISION CHANGE-CAUSE
# 1 Initial deploy
# 2 Update to v1.2.0
Discussion