kubectl
Kubernetes
rollout revision
troubleshooting
DevOps

How to know more details about a previous rollout revision using kubectl?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Kubernetes tracks revision history for Deployments, StatefulSets, and DaemonSets. To inspect a previous rollout revision, use kubectl rollout history deployment/<name> --revision=<number>, which shows the pod template, container images, environment variables, and annotations for that specific revision. This is essential for debugging failed deployments, understanding what changed between releases, and deciding whether to roll back.

Viewing Rollout History

List all recorded revisions for a deployment:

bash
kubectl rollout history deployment/nginx-deployment
 
1REVISION  CHANGE-CAUSE
21         kubectl create --filename=nginx-deployment.yaml
32         kubectl set image deployment/nginx-deployment nginx=nginx:1.16.1
43         kubectl set image deployment/nginx-deployment nginx=nginx:1.25.0

The CHANGE-CAUSE column is populated from the kubernetes.io/change-cause annotation. If no annotation exists, it shows <none>.

Inspecting a Specific Revision

Use the --revision flag to see full details of any revision:

bash
kubectl rollout history deployment/nginx-deployment --revision=2
 
1deployment.apps/nginx-deployment with revision #2
2Pod Template:
3  Labels:       app=nginx
4                pod-template-hash=abc123
5  Annotations:  kubernetes.io/change-cause: kubectl set image deployment/nginx-deployment nginx=nginx:1.16.1
6  Containers:
7   nginx:
8    Image:      nginx:1.16.1
9    Port:       80/TCP
10    Host Port:  0/TCP
11    Environment: <none>
12    Mounts:     <none>
13  Volumes:      <none>

This shows the exact pod template — container image, ports, environment variables, volumes, and labels — for that revision.

Setting Change-Cause Annotations

Record why a change was made by setting the kubernetes.io/change-cause annotation:

bash
1# Method 1: Annotate after updating
2kubectl set image deployment/nginx-deployment nginx=nginx:1.25.0
3kubectl annotate deployment/nginx-deployment \
4  kubernetes.io/change-cause="Upgrade nginx to 1.25.0 for security patch"
5
6# Method 2: Use --record (deprecated in 1.25+, but still works)
7kubectl set image deployment/nginx-deployment nginx=nginx:1.25.0 --record
8
9# Method 3: Set in the YAML manifest
10apiVersion: apps/v1
11kind: Deployment
12metadata:
13  name: nginx-deployment
14  annotations:
15    kubernetes.io/change-cause: "Initial deployment with nginx 1.24.0"

Without this annotation, CHANGE-CAUSE shows <none>, making it difficult to understand what each revision changed.

Comparing Revisions

Kubernetes does not have a built-in diff command, but you can compare revisions using output redirection:

bash
1# Save two revisions to files
2kubectl rollout history deployment/nginx-deployment --revision=2 > rev2.txt
3kubectl rollout history deployment/nginx-deployment --revision=3 > rev3.txt
4
5# Diff the revisions
6diff rev2.txt rev3.txt
 
< Image:      nginx:1.16.1
---
> Image:      nginx:1.25.0

For a more structured comparison, use JSON or YAML output with kubectl get:

bash
# Get the ReplicaSet for a specific revision
kubectl get replicaset -l app=nginx -o json | \
  jq '.items[] | select(.metadata.annotations["deployment.kubernetes.io/revision"]=="2")'

Rolling Back to a Previous Revision

Once you identify the revision you want, roll back to it:

bash
1# Roll back to the previous revision
2kubectl rollout undo deployment/nginx-deployment
3
4# Roll back to a specific revision
5kubectl rollout undo deployment/nginx-deployment --to-revision=2
6
7# Verify the rollback
8kubectl rollout status deployment/nginx-deployment
bash
# Check which revision is now active
kubectl rollout history deployment/nginx-deployment

Rolling back creates a new revision number (e.g., revision 4) with the same pod template as revision 2. The original revision 2 is removed from history.

Controlling Revision History Limits

By default, Kubernetes keeps 10 revisions. Control this with revisionHistoryLimit:

yaml
1apiVersion: apps/v1
2kind: Deployment
3metadata:
4  name: nginx-deployment
5spec:
6  revisionHistoryLimit: 20   # Keep 20 old ReplicaSets
7  replicas: 3
8  selector:
9    matchLabels:
10      app: nginx
11  template:
12    metadata:
13      labels:
14        app: nginx
15    spec:
16      containers:
17      - name: nginx
18        image: nginx:1.25.0
bash
# Check current setting
kubectl get deployment nginx-deployment -o jsonpath='{.spec.revisionHistoryLimit}'

Each revision corresponds to an old ReplicaSet object. Setting revisionHistoryLimit: 0 disables rollback capability entirely.

Rollout History for Other Resource Types

The same commands work for StatefulSets and DaemonSets:

bash
1# StatefulSet
2kubectl rollout history statefulset/postgres
3kubectl rollout history statefulset/postgres --revision=3
4
5# DaemonSet
6kubectl rollout history daemonset/fluentd
7kubectl rollout history daemonset/fluentd --revision=2

Common Pitfalls

  • Missing CHANGE-CAUSE in history: The --record flag is deprecated since Kubernetes 1.25. Use kubectl annotate with kubernetes.io/change-cause after each update to record meaningful change descriptions.
  • Revision history is empty or shows only one entry: The revisionHistoryLimit defaults to 10, but if set to a low number (or 0), old revisions are garbage collected. Check .spec.revisionHistoryLimit in the deployment spec.
  • Rolling back does not restore the old revision number: A rollback to revision 2 creates a new revision (e.g., 4) and removes revision 2 from history. This can be confusing when tracking changes — always check kubectl rollout history after a rollback.
  • Expecting --revision to show diff between revisions: The --revision flag shows a single revision's details, not a comparison. To compare, redirect two revisions to files and use diff.
  • ConfigMap/Secret changes not triggering new revisions: If you update a ConfigMap or Secret referenced by a deployment, the deployment does not get a new revision unless the pod template itself changes. Use a hash annotation pattern (e.g., checksum/config) to force new revisions when configs change.

Summary

  • kubectl rollout history deployment/<name> lists all recorded revisions
  • kubectl rollout history deployment/<name> --revision=N shows full pod template details for revision N
  • Annotate deployments with kubernetes.io/change-cause to record why each change was made
  • kubectl rollout undo --to-revision=N rolls back to a specific revision
  • Set revisionHistoryLimit to control how many old ReplicaSets are retained
  • Compare revisions by saving --revision output to files and using diff

Course illustration
Course illustration

All Rights Reserved.