KubernetesXV · DeploymentsDeployments
Rollout and revision history — change tracking and rollback
What you'll learn
- Explain how Deployments track revision history via annotations
- Use kubectl rollout history to inspect changes
- Use kubectl rollout undo to roll back to a previous revision
- Use kubectl rollout pause and resume for staged rollouts
Prerequisites
Verified against Kubernetes 1.34.x · kubeadm 1.34.x · kubectl 1.34.x · etcd 3.6.x · CoreDNS 1.11.x · containerd 1.7.x / 2.x · 2026-08-16
Deployments track every change as a revision. This lesson covers how revision history works, how to inspect it, and how to roll back when a change goes wrong.
Revision history
When you update a Deployment’s spec (e.g., change the image), the Deployment controller:
- Creates a new ReplicaSet with the new spec.
- Scales the new ReplicaSet up.
- Scales the old ReplicaSet down.
- Marks the old ReplicaSet with an annotation recording the change.
The annotation is kubernetes.io/change-cause:
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: web-7c8d9
annotations:
kubernetes.io/change-cause: "kubectl set image deployment/web web=nginx:1.27.2"
deployment.kubernetes.io/revision: "3"
The annotation records:
kubernetes.io/change-cause: the human-readable reason for the change (set by--recordor manually).deployment.kubernetes.io/revision: the revision number (incremented on each change).
sequenceDiagram
participant U as User
participant D as Deployment
participant RS as ReplicaSet
U->>D: kubectl apply (new image)
D->>RS: create new RS (revision 4)
D->>RS: scale up new RS
D->>RS: scale down old RS to 0
Note over RS: old RS annotated with change-cause
Inspecting revision history
kubectl rollout history deployment/web
Output:
deployment.apps/web
REVISION CHANGE-CAUSE
1 Initial deployment
2 kubectl set image deployment/web web=nginx:1.27.1
3 kubectl set image deployment/web web=nginx:1.27.2
4 Update replicas to 5
Each row is a revision. The change-cause tells you what changed.
# Inspect a specific revision
kubectl rollout history deployment/web --revision=3
Output:
deployment.apps/web with revision #3
Pod Template:
Labels: app=web
Containers:
web:
Image: nginx:1.27.2
Port: 8080/TCP
Host Port: 0/TCP
Limits:
cpu: 500m
Memory: 512Mi
Requests:
cpu: 100m
Memory: 128Mi
Environment: <set to the keys 'DB_HOST' from config map 'app-config'>
The full Pod template at that revision. Useful for understanding what changed between revisions.
The revision history limit
spec:
revisionHistoryLimit: 10
The revisionHistoryLimit controls how many old ReplicaSets
the Deployment retains. Default is 10. Each retained
ReplicaSet uses etcd storage and counts against the
namespace’s ResourceQuota.
When the limit is exceeded, the oldest ReplicaSets are deleted (along with their Pods). Production discipline: tune the limit based on the team’s rollback needs. 10 is usually enough for a few days of history.
Rolling back
# Roll back to the previous revision
kubectl rollout undo deployment/web
# Roll back to a specific revision
kubectl rollout undo deployment/web --to-revision=3
# Check the rollout status
kubectl rollout status deployment/web
rollout undo creates a new ReplicaSet with the spec from
the target revision. The Deployment rolls forward to that
revision (a new revision number, not the old one).
sequenceDiagram
participant U as User
participant D as Deployment
U->>D: kubectl rollout undo --to-revision=3
D->>D: create new RS with revision 3 spec (revision 5)
D->>D: scale up new RS
D->>D: scale down current RS to 0
The undo operation is itself a rollout; the Deployment controller rolls forward to the target spec. The result is a new revision number (because the change is recorded as a new change).
Pause and resume
# Pause the rollout
kubectl rollout pause deployment/web
# Make changes to the manifest (not via apply)
kubectl edit deployment/web
# Change image, env, etc.
# Resume the rollout
kubectl rollout resume deployment/web
rollout pause stops the Deployment from creating new
ReplicaSets. Subsequent edits to the Deployment accumulate;
when rollout resume is called, the Deployment controller
sees the cumulative changes and rolls out.
Use cases:
- Staged rollouts: make multiple changes (image, env, resources), pause, verify the staging environment, resume.
- Coordination: pause the rollout, make a manual change to a Pod (e.g., debug), resume.
- Rollout planning: pause to plan; resume when ready.
Production patterns
Stage a change in production:
# 1. Pause
kubectl rollout pause deployment/web
# 2. Apply changes
kubectl set image deployment/web web=nginx:1.27.3
kubectl set resources deployment/web -c web --limits=cpu=700m
# 3. Verify in staging
kubectl get deployment/web -o yaml | grep -A 5 template
# 4. Resume when ready
kubectl rollout resume deployment/web
Quick rollback after a failed rollout:
# Check rollout status
kubectl rollout status deployment/web --timeout=60s
# If failed, undo
kubectl rollout undo deployment/web
# Verify
kubectl rollout status deployment/web
Inspect change history before merging:
# Review recent changes
kubectl rollout history deployment/web | tail -10
# Compare revisions
kubectl rollout history deployment/web --revision=5
kubectl rollout history deployment/web --revision=6
Diagnosing rollout issues
A Deployment that won’t progress:
kubectl rollout status deployment/web --timeout=60s
# error: deployment "web" exceeded its progress deadline
The Deployment has a progressDeadlineSeconds (default 600s
= 10 minutes). If the rollout does not make progress within
this window, the Deployment is marked failed.
Check:
# Recent events
kubectl describe deployment/web | tail -20
# Pod status
kubectl get pods -l app=web
# ReplicaSet status
kubectl get replicaset -l app=web
Common causes:
- New image cannot be pulled (
ImagePullBackOff). - New Pods fail readiness probe.
- Insufficient cluster capacity.
Cross-course references
- The Linux course part
XXXVII-Linux-Resourcescovers process management; rollout history is the cluster-level equivalent of a change log. - The Ansible course part
XXXV-Ansible-Scriptingcovers staged rollouts; kubectl rollout pause/resume is the cluster-level equivalent. - The Terraform course part
XVII-Terraform-Driftcovers state-vs-config; rollout history is the cluster-level equivalent.
Quiz
Knowledge check · 4 questions
Q1. What does `kubectl rollout undo deployment/web` do?
Q2. The `kubernetes.io/change-cause` annotation on old ReplicaSets is set automatically by every kubectl apply.
Q3. A team rolls out a new image. The rollout fails with `exceeded its progress deadline` after 10 minutes. Walk through the rollback procedure.
Deployment `web` rolled out with image `nginx:1.27.3` 12 minutes ago. `kubectl rollout status deployment/web --timeout=60s` returns `deployment "web" exceeded its progress deadline`. New Pods are in `ImagePullBackOff` (image tag does not exist). The team needs to roll back.
Q4. What is the difference between `kubectl rollout pause` and `kubectl rollout resume`? When is pause useful?
Passing score: 75%. Answers are checked in this browser.
Production discipline
- Always set change-cause annotations. Rollback history without change-cause is unhelpful in incidents.
- Set
revisionHistoryLimitbased on rollback needs. 10 is the default; raise if the team needs longer history. - Test rollbacks regularly. A team that has never rolled back is unprepared for an incident.
- Use pause/resume for staged rollouts. Multiple changes; pause; verify; resume.
- Investigate failed rollouts.
kubectl rollout statusfailures are signals of broken changes; document them in the postmortem.