Deployments, rolling updates and rollbacks
How a Deployment runs your Pods through ReplicaSets, how to control a rolling update, and how to undo one that went wrong.
Key ideas in this lesson · tap one for a simple explanation
What you will be able to do
- Create a Deployment with one command, save it as YAML, and change its update strategy before you apply it.
- Change an image, watch the rollout, read its history and roll back to a chosen revision.
- Spot a stuck rollout from the Deployment's conditions and fix it in under two minutes.
A keeps a set number of copies of your app running, and lets you update them without downtime. Say you run a Django app as 3 . To ship version 2, you change the image, and the Deployment swaps the Pods a few at a time.
Deployments show up in almost every CKA exam. Sometimes the task is direct: create, scale, update, roll back. Sometimes it is a troubleshooting task where an update got stuck. The commands are short. What costs time is not knowing which field the grader reads, so this lesson names those fields as it goes.
What a Deployment actually manages
A Deployment does not manage Pods directly. It works through a middle layer, the . A ReplicaSet keeps an exact number of identical Pods running.
Deployment
what you create and edit
ReplicaSets
one per version
Version 2
current: 3 Pods
Version 1
old: 0 Pods, kept for rollback
Pods
3 running copies of version 2
You create and edit the Deployment. It creates one ReplicaSet per version of the Pod template, and each ReplicaSet runs the Pods.
- Every change to the Pod template (
spec.template), such as a new image, creates a new ReplicaSet. - The Deployment then scales the new ReplicaSet up and the old one down, following its strategy.
- Old ReplicaSets are kept, scaled to zero. They are your rollback points. A Deployment keeps 10 by default, and
spec.revisionHistoryLimitchanges that number.
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 outside the template, such as spec.replicas, does not create a new ReplicaSet. The current one just grows or shrinks, and no new revision is made. This matters when a task says "roll back to the previous version": scaling up is not a version.
Shaping the rollout
A rolling update replaces old Pods with new ones a few at a time, so the app keeps serving. It is the default strategy, RollingUpdate. Two settings control its pace:
maxSurge: how many extra Pods may exist abovereplicasduring the update.maxUnavailable: how many Pods may be missing belowreplicasduring the update.
Both take a number or a percentage, and both default to 25%. Example: with 4 replicas, maxSurge: 1 and maxUnavailable: 0, you never have fewer than 4 ready Pods and never more than 5 Pods in total.
The other strategy is Recreate. It stops every old Pod first, and only then starts the new ones. Use it when two versions must never run at the same time, for example an app whose old and new versions cannot share one database.
ReplicaSet web-v1old image
ReplicaSet web-v2new image
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
These are the commands you will use most. Each one names the Deployment as deploy/api: the type, a slash, then the name.
# 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 image deploy/api nginx=nginx:1.27
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 comes from the annotation kubernetes.io/change-cause on the Deployment. If a task wants a cause recorded, set it yourself right after the change: kubectl annotate deploy/api kubernetes.io/change-cause="image to 1.26".
When a rollout gets stuck
A is stuck when the new Pods never become ready. The usual causes are a wrong image tag, a missing , a that never passes, or no with room.
Kubernetes does not roll back by itself. It waits for spec.progressDeadlineSeconds (600 seconds by default). Then it sets the Progressing condition to False, with reason ProgressDeadlineExceeded, and keeps waiting.
- 1.Read the Deployment's conditions with
kubectl describe deploy. - 2.Find the new ReplicaSet and its Pods.
- 3.Read those Pods' events. They usually name the cause.
- 4.Decide: fix the problem, or undo to the version that worked.
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 official docs· open on exam day too
- Deploymentssearch: deployment rolling update
- kubectl rolloutsearch: kubectl rollout
- kubectl cheat sheetsearch: cheat sheet
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.Cluster:kubectl config use-context kind-cka
- 1
Set up the scenario
curl -fsSL https://codewithmuh.com/labs/cka/t/wl-rollout-1/setup | bash - 2
Solve it in your terminal
Use kubectl and the Kubernetes docs, like on exam day. Save any answer files under
/tmp/cka/. - 3
Check your work
curl -fsSL https://codewithmuh.com/labs/cka/t/wl-rollout-1/verify | bashGot FAIL? Read which check failed, fix it, run it again. - 4
Clean up (optional)
curl -fsSL https://codewithmuh.com/labs/cka/t/wl-rollout-1/cleanup | bash
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.Cluster:kubectl config use-context kind-cka
- 1
Set up the scenario
curl -fsSL https://codewithmuh.com/labs/cka/t/wl-rollout-2/setup | bash - 2
Solve it in your terminal
Use kubectl and the Kubernetes docs, like on exam day. Save any answer files under
/tmp/cka/. - 3
Check your work
curl -fsSL https://codewithmuh.com/labs/cka/t/wl-rollout-2/verify | bashGot FAIL? Read which check failed, fix it, run it again. - 4
Clean up (optional)
curl -fsSL https://codewithmuh.com/labs/cka/t/wl-rollout-2/cleanup | bash
Finished this lesson?
0 of 2 tasks passed. Your readiness counts tasks, so run them before you move on.