Application failures

The usual ways an app breaks on the exam, each as symptom, cause and fix, and four broken scenarios to practice the method on.

45 min 4 hands-on tasksTroubleshooting · 30% of the exam

Key ideas in this lesson · tap one for a simple explanation

What you will be able to do

  • Name the cause of a Pod failure from its STATUS and one describe, without guessing.
  • Fix image, command, environment, probe, scheduling and volume problems with one kubectl command each.
  • Tell when a Pod must be recreated, and do it in one step with replace --force.

Most troubleshooting tasks on the exam are app failures: one setting in a is wrong, and the Pod shows it. There are only about ten patterns. For each one, this lesson gives the symptom, the cause and the fastest fix. You find them with the loop from the method lesson. The tasks at the end each break one thing, like the exam.

How each pattern reads

You see

ImagePullBackOff

The event says

nginx:1.72: not found

You fix it

kubectl set image …

Every pattern in this lesson has the same three parts: what you see, the line that names the cause, and one command that fixes it.

It also helps to know the order in which a Pod starts. The status tells you which step broke, and so where to look:

Where a Pod's start can fail

Find a node

the scheduler's job

Pending

Prepare

pull the image, mount volumes

ImagePullBackOff

Run

your process starts

CrashLoopBackOff

Ready

the readiness probe passes

READY 0/​1

A Pod starts in four steps. The code in each box is the status you see when that step fails.

Image problems

  • Symptom: ErrImagePull, then ImagePullBackOff, as the waits longer between tries. Or ContainerCreating with a Pulling image event that never ends.
  • Cause: read the Failed event. It quotes the full image name and the registry's answer, as in the table below.
  • Fix: correct the image in the , not in a Pod.
The registry saysThe cause
not found, unknownA wrong image name or tag
unauthorized, pull access deniedA private registry, and the Pod has no login for it
no such host, i/o timeoutThe cannot reach that registry name
Fix a wrong tag
# Wrong tag: change the template, the rollout replaces the Pods
kubectl -n $ns set image deploy/web nginx=nginx:1.27

For a private registry, the Pod needs a login listed under imagePullSecrets. ConfigMaps and Secrets shows how to create one.

CrashLoopBackOff

  • Symptom: RESTARTS keeps climbing. STATUS switches between Running, Error and CrashLoopBackOff, with longer pauses each time.
  • Cause: the process exits. Read kubectl logs first. Then read the Exit Code under Last State in describe; the table below decodes it.
  • Common reasons: a misspelled command or argument, a missing environment variable or config file, or a service the app cannot reach. Or the command simply finishes: it exits 0, and the kubelet restarts it forever.
Exit codeMeaningLook at
0The process finished normally. With restartPolicy Always, it is restarted anywaythe command: does it run a server, or a one-off job?
1The app reported an errorthe logs
127Command not foundthe command's spelling, and whether the image has that program
137Killed by force (SIGKILL): OOMKilled, or a process that did not stop in time after a failed describe → Last State Reason, and the probe events
143Asked to stop (SIGTERM): a normal stop, a liveness restart, or an evictionthe events: Killing, and the probe
Reading a crash
kubectl -n $ns get pod worker                          # RESTARTS 5 (2m ago)
kubectl -n $ns logs worker                             # e.g. sh: sleeep: not found
kubectl -n $ns logs worker --previous                  # when the container is Running again
kubectl -n $ns describe pod worker | grep -A6 'Last State'
kubectl -n $ns get pod worker -o jsonpath='{.spec.containers[0].command} {.spec.containers[0].args}'

Fix: correct the command, args or env. For a Deployment, change the template and the recreates the Pods. A bare Pod must be recreated; see Bare Pods are mostly immutable below. If describe shows StartError with executable file not found in $PATH, the command could not even start. The fix is the same.

Pending

  • Symptom: Pending, with NODE <none>.
  • Cause: the found no node that fits. The FailedScheduling event says why each node was rejected. Four phrases cover the exam:
The event saysWhat it meansThe fix
didn't match Pod's /The nodeSelector or affinity asks for a that no node hasCorrect the selector. Label a node only if the question asks you to
Insufficient cpu, Insufficient memoryThe Pod asks for more than any node has freeLower the request with kubectl set resources, unless the question gives the number
had untolerated (s)A node has a taint the Pod does not accept. Normal for the A problem only if it hits every node. Then add a or remove the taint, as the question asks
unbound immediate The Pod's PVC is not BoundFix the claim, or create a PV for it

A PVC in a WaitForFirstConsumer is not a failure: it waits for the Pod to be scheduled, then binds. And Pending with no event at all means nothing has looked at the Pod: the scheduler is down. Control plane failures covers that.

ContainerCreating that never ends

  • Symptom: the Pod has a node, but stays in ContainerCreating.
  • Cause: a FailedMount event. A or Secret volume points to an object that does not exist (secret "db-creds" not found), or a PVC is not Bound.
  • Fix: create the missing object. Or mark the volume optional: true, if the question says the app can run without it.

After the fix, the Pod can take up to two minutes to start, because the kubelet retries the mount with a growing delay. If you are in a hurry, recreate the Pod.

OOMKilled

  • Symptom: restarts with exit code 137, and Reason: OOMKilled under Last State.
  • Cause: the used more memory than its limit, resources.limits.memory.
  • Fix: raise the limit; the question usually gives the number. On a Deployment, run kubectl set resources deploy/x -c name --limits=memory=512Mi. Recreate a bare Pod with the new limit.

Liveness probes that kill healthy containers

  • Symptom: the app works, yet RESTARTS climbs. The events say Liveness probe failed: … connection refused or HTTP probe failed with statuscode: 404. Then: Container nginx failed liveness probe, will be restarted.
  • Cause: the probe checks the wrong port or path. Or it starts checking before the app is up, because initialDelaySeconds is too short.
  • Fix: fix the probe, not the app.
See the probe, fix the probe
kubectl -n $ns get deploy api -o jsonpath='{.spec.template.spec.containers[0].livenessProbe}'; echo
kubectl -n $ns get deploy api -o jsonpath='{.spec.template.spec.containers[0].ports}'; echo
kubectl -n $ns patch deploy api --type=json \
  -p='[{"op":"replace","path":"/spec/template/spec/containers/0/livenessProbe/httpGet/port","value":80}]'
kubectl -n $ns rollout status deploy/api --timeout=120s

Do not mix it up with a readiness probe. A failing readiness probe never restarts anything: the Pod shows READY 0/1 and gets no traffic. Probes, restart policies and disruption budgets explains the probe types.

Three more patterns, in short

  • Pods Running and Ready, but the Service does not answer. That is a Service problem, not a Pod problem. Service and DNS failures covers it.
  • Init:Error or Init:CrashLoopBackOff. An fails, so the app never starts. Read its logs with kubectl logs <pod> -c <init-name>. Pods, init containers and sidecars teaches init containers.
  • A wrong ConfigMap key or Secret name. The Pod shows CreateContainerConfigError, and the event names the key. The second task of the method lesson is this case.

A typo in a variable name is sneakier. It gives no error at all: the app starts and misbehaves. kubectl exec <pod> -- env shows which variables the container really has.

The catalog on one screen

You seeFirst commandUsual fix
ImagePullBackOffdescribe pod | tailset image, or add imagePullSecrets
CrashLoopBackOfflogs, then logs --previousfix the command, args or env; recreate the Pod or roll out the Deployment
Pending, NODE <none>describe pod | taillower the requests, fix the nodeSelector or affinity, add a toleration, or bind the PVC
ContainerCreating, FailedMountdescribe pod | tailcreate the ConfigMap, Secret or PVC it names
CreateContainerConfigErrordescribe pod | tail, then get cm or get secretmatch the key name; recreate the Pod
OOMKilled, exit 137describe pod | grep -A6 'Last State'raise limits.memory
Restarts with probe eventsget deploy -o jsonpath=…livenessProbefix the port, path or initialDelaySeconds
Running, READY 0/1describe pod | tailfix the readiness probe
Init:Errorlogs <pod> -c <init>fix the init command, or create what it waits for

In the official docs· open on exam day too

Hands-on task 1 of 4ts-app-1
~6 min5% weightTroubleshooting

A Deployment that stays Pending

The Deployment frontend in namespace ts-app shows 0 of 2 Pods ready. It is required to run on the node cka-worker. Correct the Deployment's node selector so that both Pods are Running on that node. Do not add, change or remove labels on any node.

Cluster:kubectl config use-context kind-cka

  1. 1

    Set up the scenario

    curl -fsSL https://codewithmuh.com/labs/cka/t/ts-app-1/setup | bash
  2. 2

    Solve it in your terminal

    Use kubectl and the Kubernetes docs, like on exam day. Save any answer files under /tmp/cka/.

  3. 3

    Check your work

    curl -fsSL https://codewithmuh.com/labs/cka/t/ts-app-1/verify | bash
    Got FAIL? Read which check failed, fix it, run it again.
  4. 4

    Clean up (optional)

    curl -fsSL https://codewithmuh.com/labs/cka/t/ts-app-1/cleanup | bash
Hands-on task 2 of 4ts-app-2
~6 min4% weightTroubleshooting

A Pod that restarts forever

The Pod queue-worker in namespace ts-app restarts over and over and never becomes Ready. Fix it so that it runs continuously. Keep the same name, namespace and image. When you are done the Pod must be Running and Ready with no restarts since your fix.

Cluster:kubectl config use-context kind-cka

  1. 1

    Set up the scenario

    curl -fsSL https://codewithmuh.com/labs/cka/t/ts-app-2/setup | bash
  2. 2

    Solve it in your terminal

    Use kubectl and the Kubernetes docs, like on exam day. Save any answer files under /tmp/cka/.

  3. 3

    Check your work

    curl -fsSL https://codewithmuh.com/labs/cka/t/ts-app-2/verify | bash
    Got FAIL? Read which check failed, fix it, run it again.
  4. 4

    Clean up (optional)

    curl -fsSL https://codewithmuh.com/labs/cka/t/ts-app-2/cleanup | bash
Hands-on task 3 of 4ts-app-3
~6 min5% weightTroubleshooting

A Deployment whose healthy Pods keep restarting

The Pods of Deployment api in namespace ts-app restart again and again even though the web server inside them answers requests. Fix the Deployment so its Pods stop restarting. The health check must stay in place. When you are done, both replicas must be Running and Ready with a restart count of 0.

Cluster:kubectl config use-context kind-cka

  1. 1

    Set up the scenario

    curl -fsSL https://codewithmuh.com/labs/cka/t/ts-app-3/setup | bash
  2. 2

    Solve it in your terminal

    Use kubectl and the Kubernetes docs, like on exam day. Save any answer files under /tmp/cka/.

  3. 3

    Check your work

    curl -fsSL https://codewithmuh.com/labs/cka/t/ts-app-3/verify | bash
    Got FAIL? Read which check failed, fix it, run it again.
  4. 4

    Clean up (optional)

    curl -fsSL https://codewithmuh.com/labs/cka/t/ts-app-3/cleanup | bash
Hands-on task 4 of 4ts-app-4
~5 min4% weightTroubleshooting

A Pod stuck in ContainerCreating

The Pod db-client in namespace ts-app never leaves ContainerCreating. The developers say it reads its database password from a Secret that the platform team was supposed to create, with the key password and the value s3cr3t. Make the Pod Running and Ready. The Pod's specification must stay as it is.

Cluster:kubectl config use-context kind-cka

  1. 1

    Set up the scenario

    curl -fsSL https://codewithmuh.com/labs/cka/t/ts-app-4/setup | bash
  2. 2

    Solve it in your terminal

    Use kubectl and the Kubernetes docs, like on exam day. Save any answer files under /tmp/cka/.

  3. 3

    Check your work

    curl -fsSL https://codewithmuh.com/labs/cka/t/ts-app-4/verify | bash
    Got FAIL? Read which check failed, fix it, run it again.
  4. 4

    Clean up (optional)

    curl -fsSL https://codewithmuh.com/labs/cka/t/ts-app-4/cleanup | bash

Finished this lesson?

0 of 4 tasks passed. Your readiness counts tasks, so run them before you move on.