Containerization Lesson 111 of 113

Kubernetes Interview & Certification Prep: KCNA / CKAD / CKA / CKS Roadmap

You have worked through the course, deployed apps to a local cluster, broken things, and fixed them. Now you want two outcomes: pass a Kubernetes interview without freezing on the “a pod is stuck, what do you do?” question, and turn that knowledge into a certification that hiring managers actually recognise. This lesson is the bridge. It maps the four CNCF certifications to where you are, points each exam topic back to a lesson you have already done, and then drills the questions interviewers really ask — with model answers you can say out loud.

The most important thing to internalise up front: the CKAD, CKA, and CKS are hands-on, terminal exams. There are no multiple-choice questions. You are dropped into a live cluster and told to make something work, fast. So is a good technical interview, really — the strongest answers describe a procedure, not a definition. We will practise both.

In a nutshell

A Kubernetes interview is not a vocabulary test. Interviewers already assume you can recite that “a Pod is the smallest deployable unit” — reciting it back proves nothing. What they are actually probing is whether you can reason about a running system: given a symptom, do you know where to look, in what order, and why? Think of it like a car-mechanic interview. Nobody asks a mechanic to define “engine.” They pop the hood on a car that won’t start and watch how you narrow it down — battery, fuel, spark — without panicking. Kubernetes interviews pop the hood on a broken cluster.

There are four big areas interviewers circle back to, and it helps to picture them as layers you can move between:

Structure every answer the same way and you will sound senior even when you are nervous: (1) restate the situation in one sentence to show you understood it, (2) name the mental model (“a Service is just a label query”), (3) walk the procedure or trade-off out loud, (4) end with the fix and how you’d verify it. That four-beat shape — situation, model, procedure, verify — is the through-line of this whole lesson. The rest is practice.

Level: Advanced (capstone) · Time: ~35 min

Learning objectives

By the end of this lesson you will be able to:

Prerequisites & where this fits

This is the final lesson of the Kubernetes Zero-to-Hero course. It assumes you have done the fundamentals — containers and images, the control-plane/node architecture, the core objects (Pods, Deployments, Services), and the kubectl apply workflow — and ideally the capstone, where you shipped a small multi-service app with autoscaling, network policy, and GitOps. You do not need to memorise anything new here. The goal is to consolidate what you know into interview- and exam-ready form. Everything in the labs uses free, local tooling: Docker (or Podman) plus a local cluster with kind, minikube, or k3d. Nothing to pay for.

The CNCF certification ladder

The Cloud Native Computing Foundation (CNCF) and the Linux Foundation run a coherent ladder of Kubernetes certifications. Think of it as one entry-level knowledge check, two role-based practical exams, and one advanced security specialisation.

The Kubernetes certification path: KCNA entry, then CKAD/CKA, then CKS

The diagram above shows the progression and the gating: KCNA is the optional on-ramp, CKAD and CKA are the two parallel role-based exams most people target, and CKS sits on top — and crucially, you must hold a current CKA before you are allowed to sit the CKS.

Cert Full name Format Length Passing Who it’s for
KCNA Kubernetes and Cloud Native Associate Multiple choice (proctored, online) 90 min ~75% Newcomers, managers, career-switchers wanting a credible foundation
CKAD Certified Kubernetes Application Developer Hands-on, live cluster terminal 2 hours 66% Developers who deploy to and run on Kubernetes
CKA Certified Kubernetes Administrator Hands-on, live cluster terminal 2 hours 66% Operators / platform / SRE who run clusters
CKS Certified Kubernetes Security Specialist Hands-on, live cluster terminal 2 hours 67% Security-focused engineers hardening clusters (requires active CKA)

A few details that matter for planning:

Which one should you take first?

For most engineers coming out of this course, the honest answer is: CKAD or CKA — skip straight to a hands-on exam, because that is what proves you can do the job and it is what this course trained you for. KCNA is worthwhile if you want a low-stakes confidence builder, you are non-technical-but-adjacent (a manager or PM), or your employer reimburses it. Pick CKAD if you spend your day writing app manifests, Helm charts, and debugging your own workloads; pick CKA if you operate clusters — nodes, etcd, upgrades, RBAC, networking. Then, if security is your path, do CKS last.

Topic-to-lesson map

Here is the payoff for finishing the course: nearly every exam domain is something you have already practised. Use this table to find your weak spots and re-read the matching lesson before exam day.

Exam domain Certs Where you learned it in this course
Containers, images, layers, registries KCNA, CKAD Containers & Docker Basics
Control plane, nodes, etcd, kubelet, the reconciliation loop KCNA, CKA What Is Kubernetes? Architecture
Pods, ReplicaSets, Deployments, rolling updates & rollback KCNA, CKAD, CKA Pods, Deployments & Services
Services, ClusterIP/NodePort/LoadBalancer, label selectors CKAD, CKA Pods, Deployments & Services
ConfigMaps, Secrets, namespaces CKAD, CKA Pods, Deployments & Services
kubectl, kubeconfig/contexts, imperative vs declarative, logs/exec/port-forward CKAD, CKA kubectl First Steps
Health probes, resource requests/limits, autoscaling (HPA) CKAD, CKA Capstone + Autoscaling: HPA, KEDA, Karpenter
Ingress / Gateway API, traffic routing CKAD, CKA Gateway API: HTTPRoute & traffic splitting
RBAC, least privilege, ServiceAccounts CKA, CKS Least-Privilege RBAC design
NetworkPolicy, default-deny, zero-trust pod networking CKS Default-Deny NetworkPolicies & Cilium
Pod Security Admission, supply-chain, image signing, policy-as-code CKS Kyverno policy-as-code + Pod Security Admission
GitOps deployment workflow (job skill) GitOps with Argo CD

The two CKA-only gaps the course touches only lightly are cluster lifecycle (kubeadm upgrades, etcd backup/restore) and node troubleshooting (a down kubelet, full disk). Those are pure exam-prep topics — practise them directly against the official docs, because they rarely come up day-to-day on a managed cluster like AKS or EKS.

How to think in a Kubernetes interview

Before the question bank, internalise the meta-skill. Almost every Kubernetes troubleshooting question — in an interview and on the exam — yields to the same loop:

  1. Describe the object, top-down: kubectl get to see status, then kubectl describe to read the Events at the bottom. Events are where Kubernetes tells you, in plain English, why it is unhappy.
  2. Read the logs if the container actually started: kubectl logs <pod>, and kubectl logs <pod> --previous for the crashed instance.
  3. Follow the chain of ownership: Deployment → ReplicaSet → Pod → Node, and Service → Endpoints → Pod. Most “it doesn’t work” problems are a broken link in one of those chains.

Say that loop out loud in interviews. Interviewers are not grading whether you memorised a flag — they are grading whether you have a method that does not panic. “First I’d describe the pod and read the events, then check logs with --previous…” beats any amount of trivia.

Interview questions (with model answers)

These five scenarios cover the overwhelming majority of “debug this” interview rounds and CKA/CKAD troubleshooting tasks. For each: the symptom, how to diagnose, and the likely fixes.

1. “A pod keeps restarting — CrashLoopBackOff. Walk me through it.”

Model answer. CrashLoopBackOff means the container starts, exits, and Kubernetes keeps restarting it with an increasing back-off delay — so the problem is the container process, not scheduling. My procedure:

kubectl describe pod <pod>          # check Events + Last State + exit code
kubectl logs <pod> --previous       # logs from the crashed instance, not the restarting one

I read the exit code first. Exit Code 1 (or any non-zero app error) means the application itself crashed — bad config, a missing env var or Secret, a database it can’t reach, an unhandled exception on startup; the logs will say which. Exit Code 137 means it was OOM-killed (SIGKILL after exceeding its memory limit) — I’d raise the memory limit or fix the leak. Exit Code 127 means “command not found” — a bad command/args or an entrypoint that isn’t in the image. A subtle one: if a liveness probe is failing, the kubelet kills and restarts the container even though the app is fine — so I always check whether the probe’s path/port/initialDelaySeconds are realistic. Fix follows the cause: correct the config/Secret, fix the image entrypoint, bump memory, or loosen the probe.

Going one level deeper for a senior answer: the back-off is exponential — roughly 10s, 20s, 40s, doubling to a cap of 5 minutes — so a pod that has been crashing a while retries slowly; you don’t wait it out, you just read --previous logs immediately. Decode the exit codes precisely: 137 is 128 + 9 (SIGKILL — usually the OOM killer or a failed liveness probe), 143 is 128 + 15 (SIGTERM — a graceful shutdown the app mishandled or ignored during termination), and 1/2 are the app’s own errors. Watch for an init container failing: the pod shows Init:CrashLoopBackOff and the main containers never start, so you read kubectl logs <pod> -c <init-container>. And always separate the two root causes that look identical from the outside: a genuinely broken app versus a healthy app being killed by an over-aggressive liveness probe. The tell is in describe — repeated Liveness probe failed events paired with a Killing/Started cycle mean the probe, not the app; the fix there is a longer initialDelaySeconds/failureThreshold, or a startupProbe for a slow boot.

2. “I created a Service but nothing reaches it. The Service has no endpoints.”

Model answer. “No endpoints” almost always means the Service’s selector doesn’t match any running, ready pods. The Service is just a label query; if the query returns nothing, there is nowhere to route. I check the chain:

kubectl get endpoints <svc>                 # empty (or <none>) confirms it
kubectl describe svc <svc>                   # note the Selector
kubectl get pods --show-labels               # do any pod labels match that selector?

The usual causes, in order of frequency: (1) selector/label mismatch — e.g. the Service selects app=web but the Deployment’s pod template labels them app=frontend; (2) the pods exist but are not Ready, because a readiness probe is failing — an unready pod is deliberately removed from endpoints, which is the system working as designed; (3) targetPort mismatch — the Service forwards to a container port the app isn’t actually listening on, so endpoints populate but connections still fail. Fix: align the labels (or the selector), get the readiness probe passing, and confirm targetPort equals the real containerPort.

The modern detail that impresses: since Kubernetes 1.21+ the source of truth is EndpointSlices, not the older monolithic Endpoints object — kubectl get endpointslices -l kubernetes.io/service-name=<svc> shows them, and kubectl get endpoints is now a compatibility view over the slices. Two more traps worth naming: if targetPort is a named port (e.g. targetPort: http), the container must declare ports: [{name: http}] or the slice never populates; and a headless Service (clusterIP: None) has endpoints but no virtual IP, so “I can’t connect via the ClusterIP” there is by design — you resolve individual pod DNS instead. I’d close by pointing out the readiness angle is a feature, not a bug: pulling unready pods out of rotation is exactly the mechanism that makes zero-downtime rollouts safe.

3. “A pod is stuck in Pending and never schedules.”

Model answer. Pending means the scheduler hasn’t been able to place it on a node, so this is a scheduling problem, not an application one. The events tell you exactly why:

kubectl describe pod <pod>     # the Events line says e.g. "0/3 nodes are available: ..."

The common reasons the scheduler reports: (1) insufficient resources — “Insufficient cpu/memory”; the pod’s requests exceed what any node has free, so I’d lower the requests or add/scale nodes; (2) taints with no matching toleration — “node(s) had untolerated taint”; add the right toleration or target a different node pool; (3) node affinity / nodeSelector matches nothing — the constraint is too strict; (4) an unbound PersistentVolumeClaim — the pod is waiting on storage that can’t be provisioned (no matching PV or StorageClass); (5) all nodes cordoned/unschedulable. The fix is dictated by the message — and the headline lesson for the interviewer is that you let describe tell you, rather than guessing.

For a senior framing, I’d add two things. First, the fast one-liner when the pod is long-gone or you want the raw scheduler verdict: kubectl get events --sort-by=.lastTimestamp surfaces the FailedScheduling message directly. Second, the subtler modern causes juniors miss: topology spread constraints (whenUnsatisfiable: DoNotSchedule) or strict pod anti-affinity can make a pod unschedulable even when nodes have plenty of capacity, because it’s the placement rule — not resources — that’s unsatisfiable; and with PriorityClass in play, a low-priority pod can sit Pending while a higher-priority one preempts to get scheduled. The interviewer wants to see that you don’t reflexively blame CPU — you read the exact describe line and match it to the right lever.

4. “A user (or a CI pipeline) gets Error from server (Forbidden). Diagnose the RBAC.”

Model answer. RBAC in Kubernetes is purely additive with no deny rules, so Forbidden simply means no RoleBinding or ClusterRoleBinding grants this subject that verb on that resource in that namespace. I don’t guess — I ask the API server with kubectl auth can-i:

kubectl auth can-i create deployments -n team-payments \
  --as system:serviceaccount:team-payments:ci-deployer

That impersonation (--as, and --as-group for groups) reproduces the exact decision. Then I locate the gap: confirm which Role/ClusterRole grants the missing apiGroup/resource/verb, and check that a binding actually ties it to this subject in the right namespace — a frequent bug is a Role and RoleBinding created in default when the workload runs in another namespace. The fix is least-privilege: add the specific verb to a scoped Role and bind it with a RoleBinding, rather than reaching for cluster-admin. (I’d reference the Least-Privilege RBAC approach here.) The trap to call out: a RoleBinding referencing a ClusterRole grants those permissions only in the binding’s namespace, which surprises people.

Two power moves round this out. kubectl auth can-i --list --as system:serviceaccount:<ns>:<sa> dumps everything that subject can do — far faster than probing verbs one at a time when you’re mapping a gap or auditing over-permission. And know the two binding shapes cold: a RoleBinding (namespaced) grants a Role or a ClusterRole’s rules but only inside that one namespace; a ClusterRoleBinding grants cluster-wide. The classic production bug is a ClusterRole that exists but was never bound, or was bound with a RoleBinding in the wrong namespace. On the API-group detail: Forbidden messages name the exact group and resource (“cannot create resource "deployments" in API group "apps"”), so you copy that string straight into the Role’s rules — no guessing which apiGroups value to use.

5. “A Deployment rollout is stuck — kubectl rollout status never completes.”

Model answer. A stuck rollout means the new ReplicaSet’s pods aren’t becoming Ready, so the Deployment won’t finish swapping the old ones out. I look at it from both ends:

kubectl rollout status deployment/<name>     # confirms it's wedged
kubectl get rs -l app=<name>                  # old vs new ReplicaSet, desired/current/ready
kubectl describe deployment <name>            # conditions: Progressing / Available
kubectl get pods -l app=<name>                # what state are the NEW pods in?

The new pods being stuck points at the real failure, which is usually one of the scenarios above: a bad image tag (ImagePullBackOff), a crash on startup (CrashLoopBackOff), a failing readiness probe (pods never go Ready so the rollout waits forever), or Pending due to resources. There’s also a quota angle: with the default RollingUpdate strategy and maxSurge, the new pods need headroom — if a ResourceQuota or node capacity blocks the surge, the rollout stalls. I diagnose the new pods, fix the underlying cause, and if I need to stop the bleeding immediately I roll back: kubectl rollout undo deployment/<name>. Mentioning kubectl rollout undo unprompted signals you’ve operated this in anger.

The detail that signals real operating experience: a Deployment doesn’t hang forever by default — progressDeadlineSeconds (default 600s) flips the Progressing condition to False with reason ProgressDeadlineExceeded, so kubectl describe deployment will literally tell you it gave up trying. Two configuration traps to name: maxUnavailable: 0 combined with maxSurge: 0 is a deadlock (nothing is allowed to move); and if someone ran kubectl rollout pause, the rollout is intentionally frozen — kubectl rollout resume un-sticks it, and there’s nothing to “fix.” Rollback is the emergency brake, but kubectl rollout history deployment/<name> (and --revision=N for the detail) first shows you what you’d be rolling back to, so you don’t undo blindly.

A sixth question shows up constantly: “imperative vs declarative — which and why?” Strong answer: declarative (kubectl apply -f against version-controlled YAML, ideally via GitOps) is the production default because it’s reproducible, reviewable, and self-documenting. Imperative kubectl create/run/expose is for speed — scaffolding, quick debugging, and especially the exam, where you generate YAML fast with --dry-run=client -o yaml and then edit it.

Going deeper

Senior and staff interviews move past “what’s broken” to “what would you build, and what did you trade away to get there.” These questions have no single right answer — the interviewer is grading the shape of your thinking: do you ask about constraints, name trade-offs, and know where the sharp edges are? Here are the archetypes and how to attack them.

“Design a multi-tenant cluster for 30 teams.”

Start by refusing to answer until you’ve scoped it — that refusal is itself the signal they want. Ask: hard multi-tenancy (hostile tenants, e.g. a SaaS running untrusted customer code) or soft (trusted internal teams sharing infra)? The answer changes everything that follows.

For soft multi-tenancy, one cluster with strong guardrails is the pragmatic default: a namespace per team as the isolation unit; ResourceQuota + LimitRange per namespace so no team can starve the others of CPU/memory; RBAC scoped so a team admins only its own namespace; a default-deny NetworkPolicy per namespace so tenants can’t reach each other unless explicitly allowed; and policy-as-code (Kyverno/Gatekeeper) enforcing house rules — every pod has limits, no :latest, nothing privileged. The crucial caveat to say out loud: namespaces are not a security boundary on their own — every pod shares the node kernel — so for anything approaching hostile workloads you escalate to virtual clusters (vCluster), hierarchical namespaces, or a cluster per tenant, trading operational cost for real isolation. That whole spectrum is the subject of the multi-tenancy lesson.

The trade-off sentence that lands: “One big cluster is cheaper and simpler to operate but shares a blast radius and a control plane; cluster-per-tenant is the strongest isolation but multiplies upgrade, cost, and operational overhead. I’d start with namespaces + quotas + policy and only split out the tenants that genuinely need the harder boundary.”

“Debug this CrashLoopBackOff live — share your screen.”

This is the live version of question 1, and now they’re watching your hands, not just your words. Narrate every step so a silent terminal never leaves them guessing what you’re thinking:

kubectl get pod <pod> -o wide            # confirm the state + which node it's on
kubectl describe pod <pod>               # Events, Last State, exit code, probe results
kubectl logs <pod> --previous            # the crashed instance's own words
kubectl get events --sort-by=.lastTimestamp | tail -20

What they’re really watching for: (1) do you read Events and the exit code before you touch logs? (2) do you reach for --previous without being told? (3) when you find the cause, do you fix the manifest and re-apply rather than hot-patching the live pod (which the controller will revert)? (4) do you verifykubectl get pod -w until Running, then kubectl rollout status? A candidate who kubectl edits the running pod to “make it green” and calls it done fails the hidden test: the Deployment owns that pod and will recreate it from the old spec the moment it’s rescheduled. If you want the fuller, systematic version of this loop across pods, nodes, networking, storage and RBAC, that’s the troubleshooting methodology lesson.

“Requests vs limits — how do you set them, and what breaks if you get it wrong?”

A pure trade-off question. A strong answer distinguishes the two precisely first: requests drive scheduling (the scheduler reserves that much and uses it to bin-pack nodes) and determine the pod’s QoS class; limits drive enforcement (CPU is throttled at the limit, memory over the limit gets the container OOM-killed). Then the trade-offs, which is what they’re actually after:

The senior close names the asymmetry juniors miss: “I set memory requests ≈ limits, because memory is incompressible — headroom there is dangerous, not helpful; I give latency-sensitive services a CPU request but a generous-or-absent CPU limit to avoid throttling; and I let a VPA recommend values from real usage rather than guessing.” Compressible (CPU, throttled) versus incompressible (memory, OOM-killed) is the distinction that marks the answer as senior.

“A node goes NotReady. What happens to its pods, and when?”

This tests whether you know the control loop’s timers, not just the concept. The node controller marks a node NotReady after it misses heartbeats past the node-monitor-grace-period (default 40s). Pods aren’t evicted instantly — the node gets a node.kubernetes.io/not-ready taint, and the tolerationSeconds (default 300s) on the toleration Kubernetes auto-adds to every pod is the grace window before eviction. So there’s roughly a five-minute gap where pods on a dead node still show Running but are unreachable. A Deployment’s ReplicaSet then notices the shortfall and schedules replacements elsewhere; a StatefulSet will not force-delete and reschedule its pod automatically — it protects identity and storage, so a stuck StatefulSet pod on a genuinely dead node sometimes needs a manual kubectl delete pod <pod> --force --grace-period=0. Naming that StatefulSet caveat, and the ~5-minute window, is a strong senior signal — it shows you’ve thought about what “highly available” actually costs in seconds.

Exam-day tips

The CKAD/CKA/CKS are won on speed and accuracy under time pressure. The knowledge is necessary but not sufficient — these mechanics are what separate a pass from a near-miss.

Set up your aliases in the first 60 seconds. Every cluster gives you a fresh shell. Type this once and save minutes across 17 questions:

alias k=kubectl
export do="--dry-run=client -o yaml"   # "do" = dry-run output
export now="--force --grace-period=0"  # delete pods instantly
source <(kubectl completion bash)      # tab-completion
complete -o default -F __start_kubectl k

Generate, don’t type, YAML. Hand-writing manifests is slow and typo-prone. Scaffold with the imperative generators plus $do, then edit:

k run nginx --image=nginx $do > pod.yaml
k create deployment web --image=nginx --replicas=3 $do > deploy.yaml
k create svc clusterip web --tcp=80:8080 $do > svc.yaml
k create cronjob hello --image=busybox --schedule="*/1 * * * *" $do -- echo hi > cj.yaml

Use kubectl explain instead of guessing field names. It works offline, inside the exam: k explain pod.spec.containers.resources or k explain deployment.spec.strategy --recursive gives you the exact schema. This is faster than hunting through the docs tab.

Manage time ruthlessly. There are ~15–20 weighted tasks in 2 hours — roughly 6–7 minutes each, but the weights differ. Read the weight on each question. Triage: skip anything you can’t crack in ~2 minutes and flag it; bank the easy points first. A 2% question and a 13% question both cost you time — do the 13% ones. Always run kubectl config use-context <ctx> from the question prompt before you touch anything, and after a change, verify it (k get, k rollout status) — a task that “looks done” but didn’t apply earns zero.

Bookmark the docs you’ll actually open: the YAML examples for Pods, Deployments, Services, Ingress, PV/PVC, NetworkPolicy, and (for CKS) Pod Security and the Trivy/Falco pages. In the exam you copy-paste-and-edit from these constantly. Knowing where a snippet lives is a graded skill in disguise.

Common mistakes & troubleshooting

These trip people up both in interviews and on the exam itself.

Symptom / mistake Cause Fix
Edited a manifest but nothing changed Forgot to kubectl apply it, or applied in the wrong context Re-apply; run kubectl config current-context first, every time
“Why no endpoints?” panic Reading the Service in isolation Always check kubectl get endpoints + pod labels + readiness together
Burned 15 min hand-typing YAML Not using generators <cmd> --dry-run=client -o yaml > f.yaml, then edit
logs shows nothing useful on a crash Reading the current (restarting) container Use kubectl logs <pod> --previous
Widened RBAC to cluster-admin to “make it work” Treating Forbidden as a blocker, not a diagnosis kubectl auth can-i ... --as ..., then grant the specific verb
Rollout “stuck” but you only looked at the Deployment The new pods are the real problem kubectl get pods -l app=<name> and diagnose those

Common beginner mistakes

These are interview-specific traps — not cluster bugs, but the ways smart, well-prepared people talk themselves out of an offer.

Practice challenges

Six graded interview questions, escalating from conceptual warm-up to senior design and security. Try to answer each out loud first — using the four-beat structure from the nutshell — then open the model answer. The italic line under each tells you what the interviewer is actually grading, which is rarely the surface question.

Challenge 1 — Readiness vs liveness (conceptual, warm-up)

Explain the difference between a readiness probe and a liveness probe, and give one concrete scenario where confusing them causes an outage.

<details> <summary>Model answer</summary>

A readiness probe controls traffic: while it fails, the pod is pulled from Service endpoints but left running. A liveness probe controls lifecycle: while it fails past its failureThreshold, the kubelet restarts the container. The classic self-inflicted outage from confusing them is putting a deep dependency check — “can I reach the database?” — into the liveness probe. When the database blips, every replica fails liveness at once, the kubelet restarts them all simultaneously, and a two-second dependency hiccup becomes a full CrashLoopBackOff outage. The same check in a readiness probe would simply have drained traffic until the DB recovered, then let it back in — no restarts. Rule of thumb: liveness = “am I wedged/deadlocked and need a kick?” (cheap, local, self-referential); readiness = “should I receive traffic right now?” (may legitimately include dependencies). Add a startupProbe for slow-booting apps so liveness doesn’t kill them mid-boot.

</details>

What the interviewer is really testing: whether you grasp that the two probes have completely different blast radii — and that a dependency check in the wrong one turns a blip into an outage.

Challenge 2 — StatefulSet vs Deployment (conceptual, trade-off)

When would you reach for a StatefulSet instead of a Deployment? Name two things a StatefulSet gives you and one real cost.

<details> <summary>Model answer</summary>

Reach for a StatefulSet when pods need stable identity and stable per-pod storage — databases, message brokers, anything where “pod-0” must always be pod-0 with its own volume. Two things it gives you: (1) stable network identity — predictable pod names plus a per-pod DNS record via a headless Service (pod-0.svc, pod-1.svc), so peers can find each other to form a cluster/quorum; (2) stable, per-pod persistent storage — each replica gets its own PVC from volumeClaimTemplates, which survives reschedules and is re-attached to the same ordinal. It also gives ordered, sequential rollout and scaling (0,1,2… up; reverse order down). The cost: it’s slower and more fragile to operate — an ordered rollout means one stuck pod blocks the rest, scaling is deliberate, and node failure doesn’t self-heal (Kubernetes won’t force-delete a StatefulSet pod, to protect identity and data). If the workload is stateless, a Deployment is simpler and self-healing. The trap: don’t reach for a StatefulSet just because the app talks to a database — you need one only when the app is the stateful thing.

</details>

What the interviewer is really testing: whether you pick StatefulSet for the right reason (identity + storage) rather than cargo-culting it, and whether you can name its operational cost.

Challenge 3 — ImagePullBackOff (hands-on scenario)

kubectl get pods shows a pod in ImagePullBackOff. Walk through diagnosing it, and name the three most common root causes.

<details> <summary>Model answer</summary>

ImagePullBackOff (preceded by ErrImagePull) means the kubelet can’t pull the image — this happens before the container ever runs, so it’s never an app bug and logs are useless. Diagnose:

kubectl describe pod <pod>   # the Events line gives the exact pull error

The three usual root causes, all disambiguated verbatim by that Events line: (1) wrong image name or tag — a typo or a tag that doesn’t exist in the registry (“manifest unknown”); (2) private registry without credentials — the pod needs an imagePullSecret and it’s missing or wrong (“unauthorized” / “pull access denied”); (3) registry unreachable or rate-limited — no network path to the registry, or Docker Hub’s anonymous pull limit (“toomanyrequests”). Fixes follow: correct the tag; attach a valid imagePullSecret and reference it on the pod spec or ServiceAccount; or fix networking / authenticate to lift the rate limit. On the exam, k describe and reading that one line is the whole answer.

</details>

What the interviewer is really testing: that you know pull failures are pre-runtime (so logs is the wrong tool) and that describe Events — not guessing — tells you which of the three it is.

Challenge 4 — HPA not scaling (hands-on scenario)

A teammate says “the HorizontalPodAutoscaler isn’t scaling even though the pods are clearly busy.” How do you debug it?

<details> <summary>Model answer</summary>

Walk the HPA’s inputs top-down:

kubectl describe hpa <name>   # conditions + current/target + recent events
kubectl top pods              # is usage actually above target? (needs metrics-server)

The usual causes: (1) no metricsmetrics-server isn’t installed, so the HPA shows <unknown> for current utilisation and has nothing to act on (the number-one cause on fresh clusters); (2) no resource requests set — a CPU-utilisation HPA is a percentage of requests, so with no requests.cpu the utilisation is undefined and it won’t scale; (3) already at maxReplicas — it’s “not scaling” because it’s capped; (4) stabilisation window / cooldown — recent scale events or downscale-stabilisation deliberately delay the next change; (5) the target is a custom/external metric the adapter isn’t actually serving. kubectl describe hpa spells out which — it shows the AbleToScale, ScalingActive, and ScalingLimited conditions plus events. Fix accordingly: install metrics-server, set requests, raise the ceiling, or wait out the window.

</details>

What the interviewer is really testing: whether you understand an HPA is a control loop with hard prerequisites (metrics + requests) and can explain why it silently does nothing, instead of assuming it’s “broken.”

Challenge 5 — Zero-downtime deploy with migrations (design / senior)

Design a zero-downtime deployment strategy for a stateless API that also needs to run a database schema migration. What are the moving parts?

<details> <summary>Model answer</summary>

Two problems stacked: rolling the app safely, and running a schema change without breaking either the old or the new version while both are live. The moving parts:

Senior close: the hard part isn’t the Kubernetes mechanics, it’s the schema discipline — expand/contract is what actually makes it zero-downtime; maxUnavailable: 0 just handles the pods.

</details>

What the interviewer is really testing: whether you know zero-downtime is a database/versioning problem as much as a rollout-strategy one — naming expand/contract is the tell.

Challenge 6 — Leaked ServiceAccount token (senior / security)

A pod’s ServiceAccount token has leaked. Walk through containment, then what you’d change so the next leak hurts far less.

<details> <summary>Model answer</summary>

Contain first, then shrink the blast radius. Containment:

Reduce future pain:

</details>

What the interviewer is really testing: whether you think in blast radius — the CKS mindset — containing the credential and designing so the next leak is a non-event.

Best practices

Security notes

The CKS deserves a specific mention because its mindset differs from CKA/CKAD: it assumes the cluster is already compromised and asks how you’d limit the blast radius. The recurring themes are least-privilege RBAC (no standing cluster-admin, scoped Roles, auth can-i audits), default-deny NetworkPolicies so a popped pod can’t talk laterally, Pod Security Admission at restricted to stop privileged/host-mounting pods, supply-chain controls (image signing, scanning with Trivy, admission policy with Kyverno/Gatekeeper), and runtime detection with Falco. If you’re heading for CKS, treat the security lessons in this course as core, not optional — start with default-deny networking and Kyverno policy-as-code.

Quick check

  1. Which Kubernetes certifications are hands-on terminal exams, and which is multiple choice?
  2. Your Service has no endpoints. What is the single most likely cause, and what one command confirms it?
  3. A pod is Pending. Which single kubectl command tells you why, and where in its output do you look?
  4. What does --dry-run=client -o yaml do, and why is it the most important flag on exam day?
  5. RBAC has no deny rules. Given that, what does an Error: Forbidden actually mean, and how do you reproduce the decision for a specific ServiceAccount?

Answers

  1. CKAD, CKA, and CKS are hands-on, live-cluster terminal exams. KCNA is multiple choice. (CKS additionally requires an active CKA before you may sit it.)
  2. The selector doesn’t match any ready pods (label mismatch, or pods not Ready). Confirm with kubectl get endpoints <svc> (empty), then compare kubectl describe svc <svc> Selector against kubectl get pods --show-labels.
  3. kubectl describe pod <pod> — read the Events section at the bottom; it states the scheduling reason verbatim (e.g. “Insufficient cpu”, “untolerated taint”, unbound PVC).
  4. It renders a manifest locally without contacting the API server and prints it as YAML — so you scaffold a correct object instantly (> file.yaml) and edit, instead of hand-typing. On the exam it’s the fastest path to nearly any “create an X” task.
  5. It means no binding grants that subject the verb/resource/namespace combination — access is purely additive, so the permission was simply never granted. Reproduce it with kubectl auth can-i <verb> <resource> -n <ns> --as system:serviceaccount:<ns>:<sa>.

Exercise

Mock troubleshooting drill (timed, free, local). Recreate the five interview scenarios on a local cluster and fix each one against the clock — this is the single best exam rehearsal.

  1. Create a local cluster (free / local):

    kind create cluster --name cka-drill
    kubectl config use-context kind-cka-drill
    
  2. Break things on purpose. Apply a small manifest that contains four planted faults: a Deployment whose container uses a non-existent image tag (nginx:doesnotexistImagePullBackOff); a Service whose selector is app=web while the pod template labels are app=frontend (→ no endpoints); a pod requesting cpu: "64" (→ Pending, insufficient resources); and a Deployment with a liveness probe pointing at the wrong port (→ CrashLoopBackOff-style restarts).

  3. Diagnose each, narrating the loop: kubectl getkubectl describe (read Events) → kubectl logs --previous. Write down the root cause for each before you touch the fix. Time yourself: aim for under 6 minutes per fault.

  4. Fix and verify: correct the image tag, align the Service selector to the pod labels, lower the CPU request, fix the probe port. Verify with kubectl get endpoints, kubectl rollout status, and kubectl get pods (all Running/Ready).

  5. Self-assess against this rubric:

    Criterion Target
    Found root cause from describe/logs (not by guessing) All 4
    Fixed each via an edited manifest, then re-applied All 4
    Verified Ready/endpoints after each fix All 4
    Whole drill completed Under 25 minutes
  6. Cleanup (so you pay nothing and leave no clusters running):

    kind delete cluster --name cka-drill
    

Cost note: free / local. kind runs the whole cluster in Docker on your laptop — no cloud account, no charges.

Certification mapping

This lesson is the meta-lesson for the whole certification ladder, so the mapping is the ladder itself:

Glossary

Next steps

You’ve finished the Kubernetes Zero-to-Hero course. To keep going beyond the certifications and into production-grade, real-world Kubernetes, read these next:

KubernetesCKACKADCKSInterview
Need this built for real?

Vinod is a Senior Cloud Architect (22+ yrs) — available for Azure / AWS / GCP architecture, landing zones, and migrations.

Work with me

Comments