Maintenance

Site is under maintenance — quizzes are still available.

Go to quizzes

Implement Readiness Probes

Learn how to implement readiness probes in Kubernetes. This lesson covers the core concept, step-by-step implementation, hands-on walkthrough, troubleshooting, and edge cases. Master readiness probes to control when your pods receive traffic, ensuring stable, reliable deployments.

Focus: implement readiness probes

Sponsored

Picture this: you've just deployed a new version of your API, and within seconds, traffic starts hitting the pod before your application has finished initializing its database connections. Users see 502 errors, your on-call phone buzzes, and you have a bad day. This is the exact pain that Kubernetes readiness probes solve — by ensuring a pod only receives traffic when it's genuinely ready to serve requests.

The problem this lesson solves

A running pod isn't necessarily a ready pod. Containers can start before the application inside has finished loading configuration, warming caches, or migrating schemas. Without a readiness probe, Kubernetes assumes any pod in Running state is fit for service. The result? Flaky deployments, partial outages, and frustrated users. Readiness probes give you a way to tell the control plane: "This pod is now ready; send traffic." They decouple the container's lifecycle from the application's readiness.

Core concept / mental model

Think of a readiness probe as a health gatekeeper at the door of your pod. It performs a regular check (HTTP GET, TCP socket, or executing a command). When the check passes, the gate opens and traffic flows. When it fails, the gate closes — the pod is removed from the Service's endpoints, but the container keeps running (unlike a liveness probe, which would restart it).

Key definitions: - Readiness probe: A diagnostic that determines if a pod should receive traffic - Endpoints: The list of pod IPs that a Service uses to forward requests - Initial delay: Time to wait before the first probe (give your app time to start) - Period: How often the probe runs after the initial delay - Success/Failure threshold: Number of consecutive passes or fails before the pod is marked ready/unready

Pro tip: A readiness probe is not for detecting crashes — that's the job of a liveness probe. Readiness probes handle traffic gating, not pod restarts.

How it works step by step

  1. Define the probe in your pod spec (inside the container definition).
  2. Kubelet starts the container and waits for the initialDelaySeconds.
  3. Kubelet performs the check at every periodSeconds interval.
  4. If the probe succeeds, the pod is added to the Service's endpoints.
  5. If the probe fails, the pod is removed from endpoints until it passes again.
  6. The container keeps running — no restart, just traffic removal.

Hands-on walkthrough

Let's implement a readiness probe for an Nginx web server. We'll create a deployment with a readiness check that looks for a specific file (/usr/share/nginx/html/ready) to exist.

Step 1: Create the readiness probe deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-ready
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx-ready
  template:
    metadata:
      labels:
        app: nginx-ready
    spec:
      containers:
      - name: nginx
        image: nginx:1.25
        ports:
        - containerPort: 80
        readinessProbe:
          httpGet:
            path: /ready
            port: 80
          initialDelaySeconds: 5
          periodSeconds: 10
          failureThreshold: 3

Step 2: Create a Service to test traffic routing

apiVersion: v1
kind: Service
metadata:
  name: nginx-ready-svc
spec:
  selector:
    app: nginx-ready
  ports:
  - port: 80
    targetPort: 80

Apply both manifests:

kubectl apply -f nginx-deployment.yaml
kubectl apply -f nginx-service.yaml

Step 3: Verify the probe behavior

# Check pod status -- note the READY column
kubectl get pods

# Expected output (first few seconds):
# NAME                          READY   STATUS    RESTARTS   AGE
# nginx-ready-7d4f8b7c6f-abc12  0/1     Running   0          6s
# nginx-ready-7d4f8b7c6f-xyz34  0/1     Running   0          6s

# Wait 10+ seconds and check again:
kubectl get pods
# Expected output:
# NAME                          READY   STATUS    RESTARTS   AGE
# nginx-ready-7d4f8b7c6f-abc12  1/1     Running   0          20s
# nginx-ready-7d4f8b7c6f-xyz34  1/1     Running   0          20s

Step 4: Simulate pod unreadiness by removing the file

# Exec into a pod and remove the ready file
kubectl exec -it nginx-ready-7d4f8b7c6f-abc12 -- rm /usr/share/nginx/html/ready

# Watch the pod become unready after 3 failures (30 seconds)
kubectl get pods --watch
# The READY column will flip to 0/1

Pro tip: Always pair readiness probes with minReadySeconds in your Deployment spec to ensure new pods are ready before old ones are scaled down. This gives you a zero-downtime deployment.

Compare options / when to choose what

Probe Type When to Use Example Notes
HTTP GET Web apps, APIs, services serving HTTP path: /healthz Requires HTTP server; most common
TCP Socket Databases, caches, non-HTTP services tcpSocket: port: 5432 Checks only connection, not app logic
Exec Command Custom startup logic, legacy apps command: ["cat", "/tmp/ready"] Flexible but heavier (runs inside container)

Best practices: - HTTP probes are preferred for web services because they can validate actual application response (e.g., 200 OK means ready, 503 means not). - TCP probes are simpler but limited — they only confirm the port is open, not that the app is ready to serve. - Exec probes are useful when you need to run a script that checks multiple conditions.

Troubleshooting & edge cases

Common errors and fixes

  1. Pod never becomes ready — Check the probe path, port, and container logs: bash kubectl describe pod <pod-name> kubectl logs <pod-name>
  2. Probe timeout — Your app may be slow to respond. Increase timeoutSeconds or initialDelaySeconds.
  3. Pod flips between ready/unready — Either your app has intermittent failures (misconfigured) or the probe is too aggressive. Lower periodSeconds or raise failureThreshold.
  4. Service sends traffic to unready pods — Verify the Service's selector matches the pod labels. Use kubectl get endpoints to see which pods are active.

Edge case: startup delay for slow apps

If your app takes 30+ seconds to start, use initialDelaySeconds: 45 and periodSeconds: 15. For extremely slow apps, consider a startup probe (Kubernetes 1.16+) which delays all other probes until the startup passes.

What you learned & what's next

You now understand that readiness probes are your tool for controlling traffic flow to pods — ensuring users never hit an uninitialized application. You've learned:

  • The pain readiness probes solve: traffic hitting unready pods
  • The mental model of a gatekeeper that opens/closes based on app health
  • How to configure HTTP, TCP, and Exec probes step-by-step
  • How to test and simulate readiness changes
  • How to choose between probe types and troubleshoot failures

Next up: In the following lesson, you'll explore liveness probes — which detect and restart hung or crashed containers. Together, readiness and liveness probes give you full control over pod health and traffic management.

Remember: readiness = traffic gating, liveness = crash recovery. Use both, but don't confuse them.

Practice recap

Now try this: Create a Deployment with a readiness probe that checks an HTTP endpoint /api/ready that returns 200 only after 15 seconds. Use kubectl get endpoints to watch the pod appear/disappear. Then modify the probe to use a TCP socket on port 8080 and observe the same behavior.

Common mistakes

  • Confusing readiness probes with liveness probes — readiness gates traffic, liveness restarts pods.
  • Setting initialDelaySeconds too low — your app may not be ready and the probe fails immediately.
  • Using a path that doesn't exist (e.g., /healthz without implementing the endpoint).
  • Forgetting to update the Service selector when pod labels change — new pods never receive traffic.

Variations

  1. Use tcpSocket instead of httpGet for non-HTTP services like PostgreSQL or Redis.
  2. Combine readiness with a startup probe for containers that take >60s to initialize.
  3. Use an exec probe with a custom script for complex readiness checks (e.g., verifying database migration completion).

Real-world use cases

  • A Rails API server that runs database migrations on startup — readiness probe waits for a /healthz endpoint to return 200 after migrations.
  • A Cassandra node that must join the ring before accepting client queries — TCP probe on port 9042, startup probe for ring join.
  • A custom Java application that loads ML models into memory — exec probe checks for a specific file in /tmp/models-loaded.

Key takeaways

  • Readiness probes control traffic to pods — they prevent requests hitting uninitialized containers.
  • Three probe types exist: HTTP GET (most common), TCP socket, and exec command — choose based on your app.
  • Use initialDelaySeconds and failureThreshold to accommodate slow-starting applications.
  • Pair readiness probes with minReadySeconds in Deployments for zero-downtime rollouts.
  • Readiness != liveness: one gates traffic, one restarts crashed containers — use both together.
  • Debug readiness failures with kubectl describe pod and kubectl logs to see probe output.

Sponsored

Sponsored

Discussion

Questions, corrections, and tips help everyone reading this page.

0 comments

Add a comment

Shown publicly with your comment.

Be constructive · max 4,000 characters

No comments yet — start the thread.

Related tutorials, quizzes, and articles for this topic.