Probes: Liveness, Readiness, and Startup Probes

Probes are periodical checks (performed by Kubelet, every 10 seconds by default) that determine if your pod is healthy or is ready.

Note that the checks are performed by Kubelet: if the entire pod fails and you don't have something like ReplicationController, pods failing the probes will not be replaced.

Types of probes

  • Liveness probes Checks to see if a container is running and healthy ("healthchecks"). If a container fails a liveness probe, Kubelet will restart it.
  • Readiness probes Checks to see if a container can receive client requests. A pod is ready if all of its containers are ready. If a pod is ready, it is added to the service; if a pod is not ready, it is removed from the service.
  • Startup probes Disables liveness probes and readiness probes for the container until this probe succeeds (can be used on slow starting containers).

Probe descriptor

Here's an example that adds a liveness probe to a container. (Adding a readiness probe or a startup probe works similarly, but you use readinessProbe or startupProbe instead.)

In this example, Kubelet will hit the path /healthcheck on port 8080 and expects to get a non-error response (2xx or 3xx).

apiVersion: v1
kind: Pod
metadata:
  name: kubia-liveness
spec:
  containers:
    - image: luksa/kubia-unhealthy
      name: kubia
      livenessProbe:
        httpGet:
          path: /healthcheck
          port: 8080

Types of probes

If you are running a Java (JVM-based) app: use an HTTP get probe instead of an Exec probe because it will otherwise spin up a whole new JVM just to get the liveness information (you waste a considerable of resources).

There are three types of probes.

We use livenessProbe as an example, but you can also use these for readinessProbe or startupProbe.

HTTP GET probe

Performs an HTTP GET request on the container's IP address, a port, and path you specify. Succeeds if it gets a non-error response (2xx or 3xx).

# Under .spec.containers[i]:
livenessProbe:
  httpGet:
    path: /healthcheck
    port: 8080
    httpHeaders:
      - name: Custom-Header
        value: Awesome
  initialDelaySeconds: 3
  periodSeconds: 3

TCP socket probe

Opens a TCP connection to the specified port of the container. Succeeds if the connection is established successfully.

# Under .spec.containers[i]:
livenessProbe:
  tcpSocket:
    port: 8080
  initialDelaySeconds: 15
  periodSeconds: 20

Exec probe

Executes an arbitrary command inside the container. Succeeds if the command exited with exit code 0.

# Under .spec.containers[i]:
readinessProbe:
  exec:
    # this works too:
    # command: ["cat", "/tmp/healthy"]
    command:
      - cat
      - /tmp/healthy
  initialDelaySeconds: 5
  periodSeconds: 5

Working with liveness probes

Checking if a pod has been restarted

See the RESTARTS column.

kubectl get pod kubia-liveness
# NAME             READY     STATUS    RESTARTS   AGE
# kubia-liveness   1/1       Running   1          2m

Checking why a pod is restarted

You can see the previous pod's log:

kubectl logs <podName> --previous

Or see the pod's events:

kubectl describe po kubia-liveness
# ... (some other description)
# Events:
# ... Killing container with id docker://95246981:pod "kubia-liveness ..."
#     container "kubia" is unhealthy, it will be killed and re-created.

References