Deployments, rolling updates and rollbacks
How a Deployment drives ReplicaSets, how to shape a rollout with maxSurge and maxUnavailable, and how to undo one that went wrong.
After this lesson
- 01You can create a Deployment imperatively, dump it to YAML and change its update strategy before applying it.
- 02You can update an image, watch the rollout, read its history and roll back to a named revision.
- 03You can recognize a stuck rollout from the Deployment's conditions and recover it in under two minutes.
Deployments appear in almost every CKA sitting, either directly (create, scale, update, roll back) or inside a troubleshooting task where a rollout has stalled. The commands are short. What costs people time is not knowing exactly which field the grader will read, so this lesson names the fields as it goes.
What a Deployment actually manages
A Deployment does not own Pods. It owns ReplicaSets, and each ReplicaSet owns Pods that match its selector. Every change to spec.template creates a new ReplicaSet with a new pod-template hash; the Deployment then scales the new set up and the old set down according to its strategy. Old ReplicaSets are kept (ten by default, spec.revisionHistoryLimit) and those are your rollback points.
kubectl create deployment web --image=nginx:1.27 --replicas=3
kubectl get deploy,rs,pods -l app=web
# The ReplicaSet name is <deployment>-<pod-template-hash>; the hash also lands on every Pod.Changing something that is not in the template, such as spec.replicas, scales the current ReplicaSet in place and does not create a revision. That matters when a question says "roll back to the previous version": a scale-up is not a version.
Shaping the rollout
The default strategy is RollingUpdate with both knobs at 25%. maxSurge is how many extra Pods may exist above replicas during the update; maxUnavailable is how many may be missing. Both accept an absolute number or a percentage. Recreate kills every old Pod first and only then starts the new ones, which is the right answer when two versions must never run at the same time.
apiVersion: apps/v1
kind: Deployment
metadata:
name: api
namespace: wl-rollout
spec:
replicas: 3
revisionHistoryLimit: 5
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
selector:
matchLabels:
app: api
template:
metadata:
labels:
app: api
spec:
containers:
- name: nginx
image: nginx:1.27
ports:
- containerPort: 80Driving a rollout
# Change the image (container name is "nginx" when created with kubectl create deployment --image=nginx:…)
kubectl -n wl-rollout set image deploy/api nginx=nginx:1.26
# Block until the rollout finishes or fails. Always run this before moving to the next question.
kubectl -n wl-rollout rollout status deploy/api --timeout=120s
# Revisions, and the template of one revision
kubectl -n wl-rollout rollout history deploy/api
kubectl -n wl-rollout rollout history deploy/api --revision=2
# Undo to the previous revision, or to a specific one
kubectl -n wl-rollout rollout undo deploy/api
kubectl -n wl-rollout rollout undo deploy/api --to-revision=1
# Pause so several edits become one revision, then resume
kubectl -n wl-rollout rollout pause deploy/api
kubectl -n wl-rollout set resources deploy/api -c nginx --limits=cpu=200m
kubectl -n wl-rollout rollout resume deploy/api
# Scale (not a revision)
kubectl -n wl-rollout scale deploy/api --replicas=5The CHANGE-CAUSE column in rollout history is just the annotation kubernetes.io/change-cause on the Deployment, copied onto the ReplicaSet at rollout time. The old --record flag no longer exists in current kubectl, so if a task wants a recorded cause, set it yourself: kubectl annotate deploy/api kubernetes.io/change-cause="image to 1.26" right after the change.
When a rollout gets stuck
A rollout that cannot make progress for spec.progressDeadlineSeconds (600 by default) flips the Progressing condition to False with reason ProgressDeadlineExceeded. Nothing is rolled back automatically; the Deployment simply waits. Read the conditions with kubectl describe deploy, find the new ReplicaSet's Pods, and the Pod events will usually name the cause: a typo in the image tag, a Secret that does not exist, a readiness probe that never passes, or no node with enough resources.
kubectl -n wl-rollout describe deploy api | sed -n '/Conditions/,/OldReplicaSets/p'
kubectl -n wl-rollout get rs -l app=api
kubectl -n wl-rollout get pods -l app=api
kubectl -n wl-rollout describe pod <new-pod> | tail -20
# Undo is almost always the exam answer when the question says "the previous version worked".
kubectl -n wl-rollout rollout undo deploy/api
kubectl -n wl-rollout rollout status deploy/api --timeout=120sIn the docs · the tab you get on exam day
- Deployments ↗search: “deployment rolling update”
- kubectl rollout ↗search: “kubectl rollout”
- kubectl cheat sheet ↗search: “cheat sheet”
context · kubectl config use-context kind-cka
Create a Deployment with a zero-downtime strategy
wl-rollout create a Deployment named api with 3 replicas using image nginx:1.27. The Deployment must use a RollingUpdate strategy that never reduces capacity below 3 Pods and adds at most one extra Pod during an update. Keep no more than 5 old ReplicaSets.- 01
Set up the scenario
curl -fsSL https://codewithmuh.com/labs/cka/t/wl-rollout-1/setup | bash - 02
Solve it in your terminal
Work the way the exam makes you: kubectl, the docs, nothing else. Put any answer files under
/tmp/cka/. - 03
Check your work
curl -fsSL https://codewithmuh.com/labs/cka/t/wl-rollout-1/verify | bashCounts toward your readiness score. - 04
Clean up
curl -fsSL https://codewithmuh.com/labs/cka/t/wl-rollout-1/cleanup | bash
context · kubectl config use-context kind-cka
Recover a stuck rollout and scale
web in namespace wl-rollout was updated a few minutes ago and the new Pods are not starting. Roll the Deployment back to the last working version, then scale it to 4 replicas. All 4 Pods must be available when you are done.- 01
Set up the scenario
curl -fsSL https://codewithmuh.com/labs/cka/t/wl-rollout-2/setup | bash - 02
Solve it in your terminal
Work the way the exam makes you: kubectl, the docs, nothing else. Put any answer files under
/tmp/cka/. - 03
Check your work
curl -fsSL https://codewithmuh.com/labs/cka/t/wl-rollout-2/verify | bashCounts toward your readiness score. - 04
Clean up
curl -fsSL https://codewithmuh.com/labs/cka/t/wl-rollout-2/cleanup | bash
Finished reading?
0 of 2 tasks passed. Readiness counts tasks, so run them before you move on.