Files
ced4568andClaude Sonnet 5 28c925069b feat(root): author the health-probes gold-standard module
content/root/root-10-kubernetes-troubleshooting-observability/m01-health-probes/:
lesson (probe concepts) -> demonstration (reading kubectl describe pod
Events for a probe failure) -> knowledge check -> guided exercise
(write a readiness probe on paper) -> Launch Lab intro
(rootnode-probe-port-mismatch) -> reflection (root cause + Real Ops
prevention takeaway). 5 of 6 activities carry instructor notes (demo
plan, misconceptions, timing, discussion questions, extensions).

This is the reference implementation docs/COURSE_AUTHORING_STANDARD.md
documents for all future RootNode lesson authoring.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-08-25 23:29:32 -05:00

87 lines
5.2 KiB
Markdown

# Why Health Checks Exist & Probe Types
Kubernetes cannot see inside your application. It doesn't know if your process is deadlocked,
stuck in an infinite loop, or quietly failing every request while the process itself stays
alive. Without a way to ask "are you actually working?", the only signal Kubernetes has is
whether the container's process is still running — and a hung process still counts as running.
**A health probe is how your application tells Kubernetes the truth.** It's a small check —
an HTTP request, a TCP connection attempt, or a command run inside the container — that
Kubernetes runs on a schedule and uses to make real decisions: restart this container, or stop
sending it traffic.
## The three probe types
Kubernetes supports three distinct probes, and they answer three different questions. Mixing
them up is the single most common probe mistake in production.
**Liveness probe — "Is this container still alive, or should it be restarted?"**
If a liveness probe fails repeatedly, the kubelet kills the container and it gets restarted per
its restart policy. Use this for detecting a genuinely stuck process — a deadlock, a crashed
event loop. Don't use liveness to mean "not ready for traffic yet" — that's what readiness is
for, and confusing the two causes the exact incident you're about to fix.
**Readiness probe — "Is this container ready to receive traffic right now?"**
If a readiness probe fails, the Pod is removed from the Service's list of endpoints —
Kubernetes stops routing traffic to it, but does **not** restart the container. This is the
right tool for "still starting up," "warming a cache," or "temporarily overloaded, back off for
a bit." A Pod can be Running and healthy but still correctly Not Ready.
**Startup probe — "Has this slow-starting container finished starting up yet?"**
Some applications take a long time to become ready (loading a large dataset, running
migrations). A startup probe disables liveness/readiness checks until it succeeds once, so a
slow-but-healthy startup doesn't get killed by an impatient liveness probe. Once it succeeds,
liveness and readiness take over as normal.
## How a probe is actually defined
Every probe has a **mechanism** (how the check runs) and a **schedule** (how often, how long to
wait, how many failures before acting):
- `httpGet` — a GET request to a path and **port** on the container. A 2xx or 3xx response
counts as success.
- `tcpSocket` — a TCP connection attempt to a **port**. A successful connection counts as
success — this doesn't check application-level health, just "is something listening."
- `exec` — runs a command inside the container. Exit code `0` counts as success.
Timing fields (`initialDelaySeconds`, `periodSeconds`, `timeoutSeconds`, `failureThreshold`,
`successThreshold`) control how patient Kubernetes is before it acts — but no amount of correct
timing fixes a probe that's pointed at the wrong port or path in the first place.
## Common production mistakes
1. **Wrong port.** The probe's `httpGet.port` (or `tcpSocket.port`) doesn't match the port the
application actually listens on. The container is completely healthy — Kubernetes is just
asking the wrong door to open. This is the exact failure you'll diagnose in this module's lab.
2. **Liveness probe too aggressive on a slow-starting app**, with no startup probe — the app
gets killed for "not being ready yet," restarts, and never gets far enough to pass.
3. **Readiness probe that always passes** (e.g. checking a static file instead of real
dependencies) — traffic gets routed to a Pod that can't actually serve it.
4. **No probes configured at all** — Kubernetes has no way to know the container is stuck, so a
deadlocked process just sits there serving nothing, forever, looking "Running" the whole time.
## Instructor Notes
**Approximate timing:** 12-15 minutes for a live read-through with pauses for questions;
10 minutes for a self-paced read.
**Demo plan:** Before moving to the guided exercise, it's worth live-editing one Deployment's
`readinessProbe.httpGet.port` in front of the class to an obviously wrong value and running
`kubectl get pods` / `kubectl describe pod` together, so students see the Ready column and the
Events section change in real time before they do it themselves.
**Likely misconceptions to watch for:**
- Students often assume a failing liveness probe and a failing readiness probe look the same in
`kubectl get pods` — they don't (liveness failures show restart counts climbing; readiness
failures show `0/1` Ready with no restarts). Worth calling out explicitly.
- Students sometimes think `tcpSocket` checks are "less safe" than `httpGet` — reframe as
"checks a different, shallower thing," not "worse."
**Discussion question:** "Why might a team deliberately choose a readiness probe that fails
under high load, even though it takes healthy capacity out of rotation?" (Answer: shedding load
from an overloaded Pod is often better than serving every request slowly or with errors.)
**Optional extension:** Ask students to sketch what would happen if liveness and readiness
probes were swapped (readiness probe restarts on failure, liveness probe just removes from
Service) — this clarifies the distinction by making the wrong version visibly worse.