Kubernetes Rolling Updates and Rollback Strategies
Master zero-downtime deployments with Kubernetes rolling updates, rollback commands, and deployment strategies like blue-green and canary.
What you'll learn
- ✓How Kubernetes rolling updates work under the hood
- ✓Tuning maxSurge and maxUnavailable for your workload
- ✓How to roll back failed deployments quickly and safely
Prerequisites
- •Basic Kubernetes knowledge — see Pods, Deployments, Services
- •kubectl installed and cluster access configured
When you update a Deployment in Kubernetes, the default strategy is a rolling update. Kubernetes gradually replaces old pods with new ones, ensuring your application stays available throughout the process. If something goes wrong, you can roll back to the previous version in seconds. This article covers how rolling updates work, how to tune them, and what to do when things go wrong.
How Rolling Updates Work
A Deployment manages ReplicaSets. When you update the pod template (change the image tag, environment variable, or any pod spec field), Kubernetes creates a new ReplicaSet and scales it up while scaling the old ReplicaSet down.
apiVersion: apps/v1
kind: Deployment
metadata:
name: api
spec:
replicas: 4
selector:
matchLabels:
app: api
template:
metadata:
labels:
app: api
spec:
containers:
- name: api
image: myapp:1.0.0
ports:
- containerPort: 3000
Update the image:
kubectl set image deployment/api api=myapp:1.1.0
Kubernetes does the following:
- Creates a new ReplicaSet with the
myapp:1.1.0image - Scales the new ReplicaSet up by one pod
- Waits for the new pod to pass readiness checks
- Scales the old ReplicaSet down by one pod
- Repeats until all pods run the new version
The Service continues routing traffic only to pods that pass their readiness probes, so users experience no downtime.
Configuring the Rolling Update Strategy
The strategy field controls how fast and how aggressively Kubernetes rolls out changes:
apiVersion: apps/v1
kind: Deployment
metadata:
name: api
spec:
replicas: 4
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
labels:
app: api
spec:
containers:
- name: api
image: myapp:1.1.0
ports:
- containerPort: 3000
readinessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 5
periodSeconds: 10
maxSurge — the maximum number of pods that can be created above the desired replica count. With 4 replicas and maxSurge: 1, Kubernetes runs at most 5 pods during the update.
maxUnavailable — the maximum number of pods that can be unavailable during the update. With maxUnavailable: 0, all 4 replicas must stay running at all times.
Common configurations:
| Pattern | maxSurge | maxUnavailable | Behavior |
|---|---|---|---|
| Conservative | 1 | 0 | One new pod at a time, zero downtime |
| Balanced | 25% | 25% | Default, good for most workloads |
| Fast | 50% | 50% | Rolls out quickly, some capacity reduction |
| Full replace | 100% | 0 | Doubles pods briefly, fastest zero-downtime |
The values can be absolute numbers or percentages. Percentages are rounded up for maxSurge and rounded down for maxUnavailable.
Readiness Probes Are Critical
Without readiness probes, Kubernetes considers a pod ready the moment the container starts. It will scale down old pods before new ones are actually serving traffic, causing errors.
Always define readiness probes for rolling updates:
containers:
- name: api
image: myapp:1.1.0
readinessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 5
periodSeconds: 10
failureThreshold: 3
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 15
periodSeconds: 20
The readiness probe tells Kubernetes when the pod is ready to serve traffic. The liveness probe tells Kubernetes when to restart the pod. Use different thresholds — readiness should be checked more frequently with a lower initial delay.
Monitoring a Rollout
Watch the rollout progress:
# Watch rollout status
kubectl rollout status deployment/api
# See rollout history
kubectl rollout history deployment/api
# See details of a specific revision
kubectl rollout history deployment/api --revision=3
Check which ReplicaSets are active:
kubectl get replicasets -l app=api
During a rollout, you will see two ReplicaSets — the old one scaling down and the new one scaling up.
Rolling Back a Deployment
If the new version has bugs, roll back immediately:
# Roll back to the previous version
kubectl rollout undo deployment/api
# Roll back to a specific revision
kubectl rollout undo deployment/api --to-revision=2
The rollback is another rolling update, just in reverse. Kubernetes scales up the old ReplicaSet and scales down the current one.
To preserve rollout history, set revisionHistoryLimit:
spec:
revisionHistoryLimit: 10
This keeps the last 10 ReplicaSets so you can roll back to any of them. The default is 10.
Pausing and Resuming Rollouts
For large changes that involve multiple updates, pause the rollout to batch changes:
# Pause the rollout
kubectl rollout pause deployment/api
# Make multiple changes
kubectl set image deployment/api api=myapp:1.2.0
kubectl set env deployment/api API_VERSION=1.2.0
# Resume -- applies all changes as one rollout
kubectl rollout resume deployment/api
Without pausing, each kubectl set triggers a separate rollout. Pausing lets you batch them into a single rollout.
Deployment Deadline
Set progressDeadlineSeconds to fail the rollout if it takes too long:
spec:
progressDeadlineSeconds: 300
If the Deployment does not make progress for 300 seconds, Kubernetes marks it as failed. This prevents a broken rollout from hanging forever. The default is 600 seconds.
Check for a stalled rollout:
kubectl get deployment api -o jsonpath='{.status.conditions[?(@.type=="Progressing")].message}'
Recreate Strategy
For applications that cannot run two versions simultaneously (database migrations, stateful services), use the Recreate strategy:
spec:
strategy:
type: Recreate
This terminates all old pods before creating new ones. There is downtime between the old pods stopping and the new pods starting. Use it only when rolling updates are not possible.
Blue-Green with Deployments
Simulate blue-green deployments using two Deployments and a Service:
# Blue deployment (current)
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-blue
spec:
replicas: 4
selector:
matchLabels:
app: api
version: blue
template:
metadata:
labels:
app: api
version: blue
spec:
containers:
- name: api
image: myapp:1.0.0
---
# Service pointing to blue
apiVersion: v1
kind: Service
metadata:
name: api
spec:
selector:
app: api
version: blue
ports:
- port: 80
targetPort: 3000
Deploy the green version alongside blue, verify it works, then switch the Service selector:
# Deploy green
kubectl apply -f api-green.yaml
# Verify green works
kubectl run test --rm -it --image=busybox -- wget -qO- http://api-green:3000/health
# Switch traffic
kubectl patch service api -p '{"spec":{"selector":{"version":"green"}}}'
# Scale down blue after verification
kubectl scale deployment api-blue --replicas=0
Canary Deployments
Run a small percentage of traffic on the new version before full rollout:
# Stable: 9 replicas
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-stable
spec:
replicas: 9
selector:
matchLabels:
app: api
track: stable
template:
metadata:
labels:
app: api
track: stable
spec:
containers:
- name: api
image: myapp:1.0.0
---
# Canary: 1 replica
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-canary
spec:
replicas: 1
selector:
matchLabels:
app: api
track: canary
template:
metadata:
labels:
app: api
track: canary
spec:
containers:
- name: api
image: myapp:1.1.0
---
# Service selects both
apiVersion: v1
kind: Service
metadata:
name: api
spec:
selector:
app: api
ports:
- port: 80
targetPort: 3000
The Service selects all pods with app: api, so roughly 10% of traffic goes to the canary. Monitor error rates, then gradually increase canary replicas while decreasing stable replicas.
Summary
Rolling updates are the default and usually the best strategy for Kubernetes deployments. Configure maxSurge and maxUnavailable based on your availability requirements, always use readiness probes, and set a progress deadline. When things go wrong, kubectl rollout undo gets you back to the previous version in seconds. For more control, blue-green and canary patterns give you explicit traffic switching at the cost of additional complexity.
Related articles
- Kubernetes Kubernetes DaemonSets Explained with Practical Examples
Learn how DaemonSets run exactly one pod per node for logging, monitoring, and networking agents. Includes tolerations and update strategies.
- Kubernetes Kubernetes Persistent Volumes and Storage Classes
Understand PersistentVolumes, PersistentVolumeClaims, and StorageClasses to give your Kubernetes workloads reliable, portable storage.
- Kubernetes Kubernetes Network Policies: Pod-to-Pod Security Guide
Lock down pod communication with Kubernetes NetworkPolicies. Learn ingress and egress rules, label selectors, and namespace isolation.
- Kubernetes Kubernetes Resource Limits, Requests, and QoS Classes
Set CPU and memory requests and limits correctly. Understand QoS classes, OOMKilled errors, and CPU throttling in Kubernetes.