Workloads with no liveness probe
What does ZopNight detect here?
Without a liveness probe Kubernetes only restarts a container when its process exits. A deadlocked application that keeps its process alive stays in the Ready pool receiving traffic indefinitely. ZopNight checks 3 workload kinds and reports this as a pure configuration read.
Signal and threshold
| Field | Value |
|---|---|
| Rule IDs | RC-1707 · RC-1807 · RC-1907 · RC-1708 · RC-1808 · RC-1908 · RC-1718 · RC-1818 · RC-1918 |
| Category | reliability |
| Severity | medium |
| Metric | none — pure configuration read |
| Source | internal/rules/k8s/missing_liveness_probe.go |
Where it applies
Kubernetes cannot detect a hung process on its own
The default health signal is the process exit code. A container whose main process is running is, as far as the kubelet is concerned, healthy.
That covers crashes. It does not cover deadlock, an exhausted thread pool, a wedged event loop, or a connection pool that will never recover. In every one of those the process is alive and the application is not, and without a liveness probe nothing ever restarts it.
Liveness and readiness answer different questions
Worth separating, because conflating them causes real outages:
- Readiness: “should traffic go here right now?” Failing removes the pod from Service endpoints. Recoverable and routine.
- Liveness: “is this container beyond saving?” Failing kills and restarts it.
A liveness probe that is really a readiness check is actively harmful. If it fails during a slow dependency, Kubernetes restarts a container that was merely waiting. Under a shared outage it restarts every replica simultaneously, converting degradation into an outage.
The dependency trap
A liveness endpoint that checks the database is the classic mistake. When the database has a bad minute, every pod fails liveness, every pod restarts, and the application cannot recover even after the database does.
Liveness should test the process itself and nothing downstream.
Slow starts need startupProbe
An application taking two minutes to warm up will be killed repeatedly by a liveness probe with a
short initialDelaySeconds. A startupProbe suspends liveness until the app is up, which is the
correct tool. Extending initialDelaySeconds instead delays genuine failure detection forever.
Selecting containers where livenessProbe is null
kubectl get deploy,statefulset,daemonset -A -o json | jq -r ' .items[] | . as $w | .spec.template.spec.containers[] | select(.livenessProbe == null) | "\($w.kind) \($w.metadata.namespace)/\($w.metadata.name): \(.name)"'A missing probe is sometimes right
A batch worker that exits on failure already has the behaviour a liveness probe would provide. Adding one there is ceremony. This finding is worth reviewing per workload rather than applying across the board.