Home › CKA practice tasks › Repair readiness and add self-healing probes
CKA · Workloads & Scheduling

Fix a Broken Readiness Probe and Add Liveness and Startup Probes

Deployment `web` in `health-check` should run two nginx replicas. Its readiness probe uses a nonexistent path, leaving the new pods unready. The application listens on port 80, named `http`, and serves a successful response at `/`. Liveness and startup probes are missing.

Live lab access

This scenario is included in Free Practice. Choose from 6 fixed labs with 5 shared sessions per week, automatic grading, hints, solutions, AI Lab Coach and saved progress.

Create an account for this free lab →

Explore the six free labs with AI Lab Coach →

Read the brief on any device. Use a desktop or laptop for the terminal lab. Nothing starts until you choose Start.

The task

Deployment web in health-check should run two nginx replicas. Its readiness probe uses a nonexistent path, leaving the new pods unready. The application listens on port 80, named http, and serves a successful response at /. Liveness and startup probes are missing.

Requirements
1. Correct readiness to HTTP GET / on the application port, checked every 5 seconds.
2. Add liveness using HTTP GET / on the application port, checked every 10 seconds.
3. Add a startup probe using HTTP GET /, checked every 2 seconds with failureThreshold 30.
4. Ensure both replicas become available. Keep image nginx:1.27.5, two replicas, and the existing application configuration.

Both the named port http and numeric port 80 are accepted. Probe the container itself; do not override the HTTP host.

Original Prepium guide · Written for Kubernetes v1.35 and checked against the official documentation on 6 October 2026. Use a disposable practice cluster.

Startup, readiness and liveness: one gate, one traffic switch, one restart trigger

The three probes answer different questions, and the kubelet reacts to each one differently. A failed startup or liveness probe gets the container killed and restarted under the Pod's restart policy. A failed readiness probe kills nothing; it only takes the Pod out of its Services' endpoints. Picking the wrong probe type turns a brief hiccup into a restart loop, which is why the exam expects you to know which is which.

container starts ──→ startupProbe (others paused until it passes, budget = failureThreshold × periodSeconds)
                       ├─→ readinessProbe  fail → removed from EndpointSlice, no restart
                       └─→ livenessProbe   fail → kubelet kills and restarts the container

1. Deploy a Pod whose readiness you control by hand

The example uses an unprivileged nginx build that listens on 8080, names that port web, and uses all three handler types: httpGet for startup, exec for readiness and tcpSocket for liveness. Readiness passes only while the file /tmp/ready exists. Save this as cka-probes-gate.yaml.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: gatekeeper
  namespace: prepium-tutorial
spec:
  replicas: 1
  selector:
    matchLabels:
      app: gatekeeper
  template:
    metadata:
      labels:
        app: gatekeeper
    spec:
      containers:
      - name: site
        image: nginxinc/nginx-unprivileged:1.27-alpine
        ports:
        - name: web
          containerPort: 8080
        startupProbe:            # gate: nothing else runs until this passes
          httpGet:
            path: /
            port: web
          periodSeconds: 3
          failureThreshold: 20   # 20 x 3s = up to 60s to start
        readinessProbe:          # traffic switch, never restarts anything
          exec:
            command: ["cat", "/tmp/ready"]
          periodSeconds: 4
        livenessProbe:           # restart trigger
          tcpSocket:
            port: web
          periodSeconds: 15
---
apiVersion: v1
kind: Service
metadata:
  name: gatekeeper
  namespace: prepium-tutorial
spec:
  selector:
    app: gatekeeper
  ports:
  - port: 9000
    targetPort: web
kubectl create namespace prepium-tutorial
kubectl apply -f cka-probes-gate.yaml
kubectl -n prepium-tutorial get pods -l app=gatekeeper
kubectl -n prepium-tutorial get endpointslices -l kubernetes.io/service-name=gatekeeper -o yaml | grep -A3 conditions

The Pod reaches Running but READY stays 0/1, and its endpoint shows ready: false. Nothing is broken: the startup gate passed, so readiness is now running and failing as designed. The named port works for the HTTP and TCP probes and for the Service's targetPort, so changing the number later means editing one line.

2. Flip the traffic switch

kubectl -n prepium-tutorial exec deploy/gatekeeper -- touch /tmp/ready
kubectl -n prepium-tutorial get pods -l app=gatekeeper -w     # Ctrl+C once READY is 1/1
kubectl -n prepium-tutorial exec deploy/gatekeeper -- rm /tmp/ready
kubectl -n prepium-tutorial get pods -l app=gatekeeper
kubectl -n prepium-tutorial exec deploy/gatekeeper -- touch /tmp/ready

Within one readiness period the Pod becomes ready and the endpoint turns ready: true; remove the file and it drops out again; the last command restores it. Watch the RESTARTS column: it stays at 0 throughout. That is readiness doing its job, pausing traffic without touching the process.

3. Break liveness and compare

kubectl -n prepium-tutorial patch deployment gatekeeper --type=json \
  -p='[{"op":"replace","path":"/spec/template/spec/containers/0/livenessProbe/tcpSocket/port","value":8081}]'
kubectl -n prepium-tutorial get pods -l app=gatekeeper -w

The new Pod starts, passes its startup probe, then fails three TCP checks 15 seconds apart (the default failureThreshold is 3) and is restarted; the RESTARTS count keeps rising and kubectl describe pod lists failed liveness probe events. Meanwhile the old Pod keeps serving: with one replica the default rolling update rounds maxUnavailable down to 0, and the new Pod (with no /tmp/ready) never becomes ready to replace it. Undo it with kubectl -n prepium-tutorial rollout undo deployment/gatekeeper.

4. Size the startup budget deliberately

The startup probe's worst-case allowance is failureThreshold × periodSeconds: here 20 × 3 seconds, so the app has up to a minute to answer before the kubelet kills it. A short period with a high threshold notices a fast start quickly while still tolerating a slow one. Liveness and readiness are held back until startup succeeds, so you do not need a long initialDelaySeconds on them.

Common mistakes

Example checkEvidence
Probe handler and target are rightkubectl get deploy -o yaml shows the path or command, the port (name or number) and periodSeconds per probe
Startup budget matches the appfailureThreshold × periodSeconds exceeds the real start time
Pods are servingREADY 1/1, EndpointSlice endpoints ready: true
No hidden restart loopRESTARTS stable over a few minutes

Cleanup: kubectl delete namespace prepium-tutorial. References: Configure liveness, readiness and startup probes, Pod lifecycle: container probes. Next, try a readiness probe on the wrong path or rollout recovery.

Difficulty
Medium · 8 minutes target
Domain
Workloads & Scheduling
Grading
Live checks · partial credit

Practice scope

This additional curriculum lab is available in single-task practice with the existing 12-minute limit. Its alternate scenario also appears in one of the two mixed curriculum mocks. The first three 17-task mocks keep their original task sets. Hints, an explained solution and requirement-by-requirement feedback are available in the lab.

Browse CKA practice tasks →