Chapter 7

Add Health Probes

Teach Kubernetes when a container is ready, when it should restart, and when startup needs extra time.

Just started Saved in this browser.

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

Audience

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.

Step by step

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.

Do this

The challenge

Challenge: observe healthy probes, deliberately point them at a missing path, diagnose the evidence, and restore the release.

Prepare

Prerequisites

  • A running Minikube cluster and the extracted static source.
  • Helm and kubectl.
  • Two terminal windows.
  • A text editor or sed available in your shell (commands below use sed only).
Outcome

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
Step by step

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 -
Step by step

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.

Step by step

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.

Step by step

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
Verify

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.

Troubleshoot

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.
  • sed path differs on Windows Git Bash vs PowerShell: run the sed block from the chapter’s Bash-friendly environment, or edit health: manually in work/broken-probe.yaml.
Practice

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:

  1. Why might readiness fail while the container process is still running?
  2. 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.

Reference

Official references

Just started Saved in this browser.