Kubernetes Liveness & Readiness Probes

Liveness Probe

A Liveness probe indicates whether or not a container is healthy and is used by Kubernetes to determine when a container should be terminated and restarted. You define your own custom criteria for determining container health. For example, if your container is running a microservice, that application will likely have a HTTP health check endpoint. The health check endpoint can be used as the Liveness probe to determine the containers health status. In other words, if the microservice is deemed healthy, the container is healthy.

The Pod definition below creates a file called health.txt and write it to a volume on startup. A liveness probe is defined as an exec command and runs cat against health.txt. If this command runs without issue, the container is deemed healthy. The liveness probe uses initialDelaySeconds to ensure Kubernetes doesn’t call the probe for at least 3 seconds after the container starts.

apiVersion: v1
kind: Pod
metadata:
  name: liveness-pod-healthy
spec:
  containers:
    - name: liveness-container
      image: busybox
      command: ['sh', '-c', 'echo healthy >> /var/demo/health.txt && sleep 3600']
      livenessProbe:
        exec:
          command: ['sh', '-c', 'cat /var/demo/health.txt']
        initialDelaySeconds: 3
        periodSeconds: 3
      volumeMounts:
        - name: health-status-volume
          mountPath: /var/demo
  volumes:
    - name: health-status-volume

Run kubectl apply -f liveness-probe-healthy.yaml to start the container. You’ll see that the container started successfully and there were no restarts. This indicates that the liveness probe is running successfully.

The Pod definition below is similar to the one defined above, except it defines a command in the liveness probe that will fail. The container creates a file called unhealthy.txt on startup but the liveness probe command tries to access health.txt. This causes the health check to fail.

apiVersion: v1
kind: Pod
metadata:
  name: liveness-pod-unhealthy
spec:
  containers:
    - name: liveness-container
      image: busybox
      command: ['sh', '-c', 'echo unhealthy >> /var/demo/unhealthy.txt && sleep 3600']
      livenessProbe:
        exec:
          command: ['sh', '-c', 'cat /var/demo/health.txt']
        initialDelaySeconds: 3
        periodSeconds: 3
      volumeMounts:
        - name: health-status-volume
          mountPath: /var/demo
  volumes:
    - name: health-status-volume

After the container starts, run kubectl describe pod liveness-probe-unhealthy to see the container metadata. In the events section at the bottom you’ll see the liveness probe failed because it couldn’t access health.txt.

Readiness Probe

A Readiness probe is similar to a Liveness probe and is specifically used on container startup to determine whether or not a container is ready to start receiving requests. When a container starts, Kubernetes will not route requests to it until the Readiness probe has returned a healthy status. This ensures containers do not prematurely receive requests when they’re starting up.

The Pod definition below includes a Readiness probe that uses a HTTP GET to check if the container is ready. 3 seconds after the container starts, Kubernetes will send a HTTP GET to nginx at / . This will result in a 200 response code and the container will be deemed ready.

apiVersion: v1
kind: Pod
metadata:
  name: readiness-probe-healthy
spec:
  containers:
    - name: readiness-probe-container
      image: nginx
      readinessProbe:
        httpGet:
          path: /
          port: 80
        initialDelaySeconds: 3
        periodSeconds: 3

The Pod definition below includes a Readiness probe, this time one that fails. The httpGet attribute is set to /bla, which doesn’t exist. This results in nginx returning a 404 and the container is deemed not ready.

apiVersion: v1
kind: Pod
metadata:
  name: readiness-probe-unhealthy
spec:
  containers:
    - name: readiness-probe-container
      image: nginx
      readinessProbe:
        httpGet:
          path: /bla
          port: 80
        initialDelaySeconds: 3
        periodSeconds: 3

Running a kubectl describe on the container shows the failed Readiness probe.

The sample code for these notes is available here.