Add Health Probes
Teach Kubernetes when a container is ready, when it should restart, and when startup needs extra time.
A running process is not necessarily ready to serve traffic. Kubernetes probes turn application-specific health signals into controller decisions. This chapter is a small observability story: your app “looks up,” then you break a probe on purpose and use logs, events, and Pod conditions to find the cause.
Last updated: 2026-07-20
Who this chapter is for
This chapter is for beginners who can deploy the static app with Helm (Chapters 5–6). You need two terminal windows. No separate monitoring stack is required.
Download this chapter's files
Use your browser to download either ivia-chapter-07.tar.gz or ivia-chapter-07.zip. The archive is self-contained; you do not need this tutorial repository.
Open a terminal after the browser download:
cd ~/Downloads
tar -xzf ivia-chapter-07.tar.gz
cd ivia-chapter-07
All remaining relative paths in this chapter start from that extracted directory.
The challenge
Challenge: observe healthy probes, deliberately point them at a missing path, diagnose the evidence, and restore the release.
Prerequisites
- A running Minikube cluster and the extracted static source.
- Helm and kubectl.
- Two terminal windows.
- A text editor or
sedavailable in your shell (commands below usesedonly).
Learning goals
After this chapter, you will be able to:
- Distinguish readiness, liveness, and startup probes
- Read rendered probe configuration
- Diagnose failures from Pod conditions, events, and logs
- Choose conservative probe timings
- Restore a healthy release after a controlled failure
Prepare the standalone exercise
minikube image build -t simple-static:local static-app
kubectl label node minikube ivia.ch/nodetype=app --overwrite
kubectl create namespace tutorial \
--dry-run=client -o yaml \
| kubectl apply -f -
Three different questions
- Readiness: may this Pod receive Service traffic now? Failure removes it from endpoints without restarting it.
- Liveness: is this process stuck beyond recovery? Repeated failure restarts the container.
- Startup: has a slow application finished starting? It suppresses the other probes until startup succeeds.
Logging records what the process printed. Events record what Kubernetes decided. Together they replace guessing when the app feels “slow” or “down.”
Inspect the snapshot and rendered probes:
sed -n '1,200p' static-app/values.yaml
helm template simple-app \
oci://harbor.ivia.ch/ivia-generic-helm-chart/ivia-generic-helm-chart \
--version 4.8.0 -n tutorial \
-f static-app/values.yaml \
| grep -A10 -E 'readinessProbe:|livenessProbe:'
You should see HTTP probes pointing at the health path from values.
Deploy healthy probes
helm upgrade --install simple-app \
oci://harbor.ivia.ch/ivia-generic-helm-chart/ivia-generic-helm-chart \
--version 4.8.0 -n tutorial --atomic --timeout 5m \
-f static-app/values.yaml
kubectl rollout status deployment/simple-app-frontend -n tutorial --timeout=120s
kubectl get pods -n tutorial
You should see 1/1 Running before you break anything.
Introduce one controlled failure
We point the health path at a missing URL so probes fail while nginx still runs. Use sed so you do not need Python installed.
mkdir -p work
sed 's|health: /healthz|health: /missing|' \
static-app/values.yaml > work/broken-probe.yaml
helm upgrade simple-app \
oci://harbor.ivia.ch/ivia-generic-helm-chart/ivia-generic-helm-chart \
--version 4.8.0 -n tutorial -f work/broken-probe.yaml
Observe briefly and gather evidence:
kubectl get pods -n tutorial -w
# Press Ctrl+C after readiness is 0/1 or restarts appear.
kubectl describe pod -l deploymentName=simple-app -n tutorial
kubectl get events -n tutorial --sort-by=.lastTimestamp
kubectl logs -l deploymentName=simple-app -n tutorial --tail=40
Look for HTTP probe failures (often status 404) in events and for readiness becoming false.
Restore immediately:
helm upgrade simple-app \
oci://harbor.ivia.ch/ivia-generic-helm-chart/ivia-generic-helm-chart \
--version 4.8.0 -n tutorial --atomic --timeout 5m \
-f static-app/values.yaml
kubectl rollout status deployment/simple-app-frontend -n tutorial --timeout=120s
Expected validation
Initially the Pod is 1/1 Running. With /missing, events include an HTTP probe failure with status 404; readiness becomes false and liveness may increase RESTARTS. Restoration returns the newest Pod to 1/1 Running.
Troubleshooting and common pitfalls
- Remote dependency in liveness: avoid it; a temporary dependency outage can create a restart storm.
- Probe port mismatch: use the container port, not a port-forward host port.
- Startup takes longer than delays: add a startup probe instead of making liveness overly patient.
- Atomic rollback hides failure: the deliberate upgrade omits
--atomic; the restoration includes it. - Several matching Pods: describe each Pod by name to separate old and new revisions.
- Release left broken: always perform the restoration before continuing.
sedpath differs on Windows Git Bash vs PowerShell: run thesedblock from the chapter’s Bash-friendly environment, or edithealth:manually inwork/broken-probe.yaml.
Recap and practice
Recap: Readiness controls traffic, liveness triggers restarts, and events plus logs tell you which probe failed and why.
Try to explain in your own words:
- Why might readiness fail while the container process is still running?
- How would you investigate “the app is slow” with only kubectl?
Exercise: After restoration, run kubectl get endpoints -n tutorial (or EndpointSlice) and confirm the Service has an address again.
Stretch: Temporarily lengthen periodSeconds on the readiness probe in a values copy, upgrade, break the path again, and note how long it takes for Ready to flip.