Kubernetes probes are your application’s vital signs, but most people configure them with a dangerous oversimplification, treating them as a mere "is it alive?" check rather than a sophisticated "is it ready to do work?" signal.

Let’s watch this in action. Imagine a simple web service deployed in Kubernetes.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-web-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-web-app
  template:
    metadata:
      labels:
        app: my-web-app
    spec:
      containers:
      - name: web-container
        image: nginx:latest
        ports:
        - containerPort: 80
        livenessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 5
          periodSeconds: 5
        readinessProbe:
          httpGet:
            path: /healthz
            port: 80
          initialDelaySeconds: 15
          periodSeconds: 10

Here, nginx:latest is a placeholder for your actual application. The livenessProbe checks if the container is running and responsive (a basic "is it alive?"). The readinessProbe checks a specific endpoint (/healthz) that indicates if the application is ready to serve traffic.

When a pod starts, Kubernetes first runs the initialDelaySeconds for both probes. Once that passes, it starts checking according to periodSeconds.

  • Liveness Probe: If this probe fails repeatedly, Kubernetes assumes the application is stuck or dead and restarts the container. This is your "firefighting" mechanism.
  • Readiness Probe: If this probe fails, Kubernetes removes the pod’s IP address from the Service endpoints, meaning no new traffic will be sent to it. The pod isn’t restarted, but it stops receiving requests until the probe passes again. This is your "traffic control" mechanism.

The key difference is the action Kubernetes takes: restart vs. de-register from service.

Consider a web application that, upon startup, needs to connect to a database and load a large configuration file.

  1. Container Starts: The nginx image (or your app) begins executing.
  2. Liveness Probe Fires: The livenessProbe might pass immediately if the web server process itself is running. However, the application might still be busy initializing its database connection or loading data, making it unready to serve requests.
  3. Readiness Probe Fires: If your /healthz endpoint is poorly designed and just checks if the web server is up, it will pass even when the app isn’t truly ready. If it’s designed correctly, it will fail until the database connection is established and configuration is loaded.
  4. Service Traffic: If the readiness probe fails, the pod is not sent traffic by the Service. If it passes, the pod’s IP is added to the Service’s endpoints.
  5. Application Becomes Ready: Once the app finishes its initialization, the /healthz endpoint starts returning a success code (e.g., 200 OK).
  6. Readiness Probe Passes: Kubernetes detects the passing probe and adds the pod’s IP to the Service endpoints, allowing traffic.
  7. Liveness Probe: If the application later crashes or becomes unresponsive after initialization, the liveness probe will fail, triggering a container restart.

The mental model is this: Liveness is about survival; Readiness is about serviceability. You want your liveness probe to be a bit more lenient (longer periodSeconds, more failureThreshold if needed) so you don’t restart a temporarily slow application. Your readiness probe needs to be strict and accurate about the application’s actual ability to fulfill requests.

The one thing most people don’t realize is that the httpGet probe, by default, considers any HTTP status code in the 2xx or 3xx range as a success. This means if your /healthz endpoint, when not ready, returns a 302 Found redirecting to a login page, your readiness probe will still pass, incorrectly signaling that your application is ready to serve traffic. You must ensure your readiness endpoint returns a 200 OK only when the application is fully functional.

The next hurdle is understanding how probes interact with Pod Disruption Budgets and how to implement more advanced checks beyond simple HTTP GETs.

Want structured learning?

Take the full Kubernetes course →