Lab โ Kubernetes Readiness & Liveness Probes¶
Difficulty: Beginner ยท Estimated time: 30-45 min
Configure readiness and liveness probes on a Deployment, then deliberately break them to see exactly what Kubernetes does in each case โ the two failure modes look similar in the dashboard but mean very different things to an on-call engineer.
๐ฏ Objective¶
- Deploy an app with a
/healthzendpoint you can toggle on and off - Add a
readinessProbeand watch a pod get pulled out of Service traffic without being restarted - Add a
livenessProbeand watch kubelet restart the container instead - Understand why conflating the two is a common cause of cascading outages
๐ Prerequisites¶
- Kubernetes cluster with
kubectlaccess - Any image that serves a toggleable health endpoint (nginx + a mounted static file works fine, or reuse the hello app from the earlier lab)
๐งญ How the two probes differ¶
flowchart TD
A[Pod starts] --> B{Readiness probe}
B -- passing --> C[Added to Service endpoints<br/>receives traffic]
B -- failing --> D[Removed from Service endpoints<br/>no traffic, pod keeps running]
C --> E{Liveness probe}
D --> E
E -- passing --> C
E -- failing --> F[kubelet kills & restarts container]
F --> A
- Readiness answers "can this pod take traffic right now?" โ failing it just removes the pod from the Service's endpoint list. No restart.
- Liveness answers "is this process still healthy, or is it stuck?" โ failing it gets the container killed and restarted. Get this wrong (e.g. tying liveness to a downstream dependency) and one flaky dependency can restart-loop your entire fleet.
๐ฆ Step 1 โ Deploy without probes¶
kubectl create deployment probes-demo --image=nginxdemos/hello --port=80
kubectl expose deployment probes-demo --port=80 --target-port=80
kubectl get endpoints probes-demo
Note the pod IP is already in the endpoint list โ with no readiness probe, Kubernetes assumes "running container" means "ready for traffic" the moment it starts.
โ Step 2 โ Add a readiness probe¶
kubectl patch deployment probes-demo --type=json -p='[
{"op": "add", "path": "/spec/template/spec/containers/0/readinessProbe", "value": {
"httpGet": {"path": "/", "port": 80},
"initialDelaySeconds": 3,
"periodSeconds": 5
}}
]'
kubectl rollout status deployment/probes-demo
kubectl get pods -l app=probes-demo -o wide
The READY column now shows 1/1 only once the probe has passed at least once.
๐ฅ Step 3 โ Break readiness and watch traffic drain¶
# Point the probe at a path that doesn't exist
kubectl patch deployment probes-demo --type=json -p='[
{"op": "replace", "path": "/spec/template/spec/containers/0/readinessProbe/httpGet/path", "value": "/does-not-exist"}
]'
kubectl get pods -l app=probes-demo -w
Watch READY drop to 0/1 after a few failed probes. Now check the Service:
kubectl get endpoints probes-demo
The endpoint list is empty โ the pod is still running (kubectl get pods shows Running, not CrashLoopBackOff), it's just no longer receiving traffic. This is the behavior you want during a slow startup or a temporary dependency outage: fail closed, don't restart.
โป๏ธ Step 4 โ Add and break a liveness probe¶
kubectl patch deployment probes-demo --type=json -p='[
{"op": "add", "path": "/spec/template/spec/containers/0/livenessProbe", "value": {
"httpGet": {"path": "/does-not-exist", "port": 80},
"initialDelaySeconds": 3,
"periodSeconds": 5,
"failureThreshold": 3
}}
]'
kubectl get pods -l app=probes-demo -w
This time watch RESTARTS climb instead of READY staying pinned at 0/1 โ kubelet is killing and restarting the container each time the liveness probe fails its threshold. Run kubectl describe pod -l app=probes-demo and look at the Events section to see the Liveness probe failed / Killing container entries.
๐งน Step 5 โ Fix it and clean up¶
kubectl patch deployment probes-demo --type=json -p='[
{"op": "replace", "path": "/spec/template/spec/containers/0/readinessProbe/httpGet/path", "value": "/"},
{"op": "replace", "path": "/spec/template/spec/containers/0/livenessProbe/httpGet/path", "value": "/"}
]'
kubectl rollout status deployment/probes-demo
# Cleanup
kubectl delete deployment probes-demo
kubectl delete service probes-demo
โ Success Criteria¶
- [ ] Deployed a pod with no probes and observed it receives traffic immediately on start
- [ ] Added a readiness probe and confirmed
READYgates on it - [ ] Broke readiness and confirmed the pod stays
Runningbut drops out of Service endpoints - [ ] Broke liveness and confirmed the container gets restarted instead
- [ ] Can explain, in one sentence each, when you'd want readiness-only vs. liveness failing
A readiness probe protects your users from a pod. A liveness probe protects a pod from itself. Wiring a downstream dependency into liveness turns one bad dependency into a restart storm โ keep liveness checks local to the process.