Full lesson
Explore the full explanation, examples, and visuals at your own pace.
Deployment web: 3 Ready v1 Pods
A well-configured rolling update keeps broken Pods away from your users. Here's our starting point: a Deployment called web, with one v1 ReplicaSet owning three Ready Pods. Service web routes traffic to all three, so everything is healthy before we change anything.
deployment.yaml (excerpt) and the bad update
maxSurge one allows a single extra Pod. maxUnavailable zero means we never drop below three Ready Pods. The readinessProbe hits slash healthz on port 8080. Then set image pushes web v2, whose healthz returns 500.
spec:
replicas: 3
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
spec:
containers:
- name: web
image: web:v1
readinessProbe:
httpGet:
path: /healthz
port: 8080
$ kubectl set image deployment/web web=web:v2The surge Pod fails readiness
The controller creates one v2 Pod through a new ReplicaSet. The kubelet probes /healthz and gets an HTTP 500, so it reports Ready false, then keeps probing. The container is running, but it never becomes Ready. Because of that, no v1 Pod gets deleted.
Stuck: 3 Ready v1 + 1 unready v2
The Service routes only to Ready Pods, so all traffic lands on the three v1 Pods. The v2 Pod gets nothing. And since maxUnavailable is zero, Kubernetes can't delete any v1 Pod. Users stay on v1. A rollout retires old Pods only after new ones prove Ready.
If maxUnavailable were one instead of zero, what happens to the v1 Pods when the broken rollout starts?
If maxUnavailable were one instead of zero, what happens to the v1 Pods when the broken rollout starts?
- One v1 Pod is terminated, leaving two serving
- All three v1 Pods keep serving
- All v1 Pods are replaced immediately
If maxUnavailable were one instead of zero, what happens to the v1 Pods when the broken rollout starts?
One v1 Pod is terminated, leaving two serving. maxUnavailable one lets the controller remove an old Pod without waiting for any new Pod to become Ready. So capacity drops to two v1 Pods, the broken v2 Pods still never pass readiness, and the rollout stalls anyway, just with less headroom.
- One v1 Pod is terminated, leaving two serving
- All three v1 Pods keep serving
- All v1 Pods are replaced immediately
What you observe (illustrative output)
Rollout status stalls at one new replica and eventually errors with the progress deadline exceeded. The three original Pods are still Running and Ready. The new Pod, ending 8b2d4f, shows zero of one ready. Kubernetes flags the failure, but it doesn't revert anything.
$ kubectl rollout status deployment/web
Waiting for deployment "web" rollout to finish: 1 out of 3 new replicas have been updated...
error: deployment "web" exceeded its progress deadline
$ kubectl get pods
NAME READY STATUS
web-5f9c7d-k2p4x 1/1 Running
web-5f9c7d-m8q1z 1/1 Running
web-5f9c7d-t6w3n 1/1 Running
web-8b2d4f-x9r7c 0/1 Runningkubectl rollout undo deployment/web
When you run rollout undo, the Deployment sets its Pod template back to the previous revision. That matches the existing v1 ReplicaSet, which already has three Pods, so nothing restarts. Then the v2 ReplicaSet scales to zero, deleting the broken Pod. The v1 Pods just keep serving.
Why this failure was harmless
This was harmless because the probe caught the bug and maxUnavailable 0 kept capacity. But it only works if the probe detects the problem, and someone, you or your CI, must trigger the rollback.
- Readiness probe caught the bug
- maxUnavailable 0 kept full capacity
- No auto-rollback: deadline only flags
Old Pods stay until new Pods prove Ready
Old Pods stay until new Pods prove Ready. That's why the stuck state is safe: three Ready v1 Pods serving, one unready v2 Pod waiting. After every deploy, watch kubectl rollout status, and roll back yourself.



