~13 min
Kubernetes recognizes three kinds of probe, and each has a genuinely different consequence when it fails. A livenessProbe that fails gets the container restarted — use it for a process that can deadlock or get stuck in a way it will never recover from on its own. A readinessProbe that fails removes the Pod from every Service's list of endpoints, but does not restart anything — the container keeps running, it just stops receiving new traffic until the probe passes again. A startupProbe runs once at container start and blocks the liveness and readiness probes from running until it succeeds, giving a slow-initializing application room to boot; once it succeeds, it is never evaluated again for that container's lifetime.
Conflating liveness and readiness is a common, costly mistake: a liveness probe tuned as if it were a readiness check restarts a container that was only ever temporarily busy, and a readiness probe tuned as if it were a liveness check leaves a genuinely stuck process quietly serving no traffic forever rather than getting restarted.
bash
apiVersion: v1
kind: Pod
metadata:
name: web
spec:
containers:
- name: web
image: web:4.1
startupProbe:
httpGet:
path: /healthz
port: 8080
failureThreshold: 30
periodSeconds: 2
livenessProbe:
httpGet:
path: /healthz
port: 8080
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8080
periodSeconds: 5Each probe picks exactly one mechanism. httpGet sends an
HTTP request and treats status codes 200–399 as success — the
right fit for anything that already speaks HTTP. tcpSocket
only checks whether a port accepts a connection, a weaker
signal than a real protocol check. exec runs a command
inside the container and checks its exit code — flexible, but
it spawns a new process on every single check, which can pile
up if the container's main process is PID 1 with no init
process to reap the children. grpc speaks the standard gRPC
Health Checking Protocol directly and has been a stable,
built-in probe mechanism since Kubernetes v1.27, with the one
limitation that the port must be numeric — a named port is not
supported.
Just stop receiving traffic — the Pod is pulled from Service endpoints, but nothing about the container itself is restarted.