Kubernetes June 1, 2026 16 min read

CKA Practice Questions 2026: 15 Realistic Scenarios + Answers

15 scenario-style CKA practice questions for 2026 — each with the exact kubectl commands and YAML you need to answer correctly under exam conditions.

CKA practice questions 2026 with realistic Kubernetes scenarios and kubectl answers

The CKA is a live-terminal exam. Every task hands you a broken or incomplete cluster and asks you to fix it — no multiple choice, no hints. The 15 questions below are written to mirror what real candidates encounter in 2026: weighted by domain, scenario-driven, and answered with the exact kubectl / YAML approach the grader expects.

Work through these sequentially, attempt each on a local cluster first, then check the answer. If you want unlimited auto-scored practice after finishing this set, the free CKA practice exam on ExamCert generates fresh scenario questions on demand. For the full study plan behind these questions, see the CKA Study Guide 2026.

Setup before you start: In your terminal run alias k=kubectl, complete -F __start_kubectl k, and export do='--dry-run=client -o yaml'. Every answer below assumes these aliases are active — exactly as you should set them in the first 30 seconds of the real exam.

How CKA Questions Are Scored

The CKA is graded automatically after you submit. Each task carries a published weight — shown in the task pane — typically between 4% and 13%. The pass mark is 66% out of 100%. Linux Foundation does not share a per-task breakdown after the exam; you receive only a total percentage.

Two practical consequences: first, never spend more than 10 minutes on a single low-weight task. Second, always verify your work before moving on — run k get or k describe to confirm the resource exists in the correct namespace with the correct spec. Silent mistakes cost more points than unanswered questions.

The five domains and their 2026 weights are: Cluster Architecture 25%, Workloads & Scheduling 15%, Services & Networking 20%, Storage 10%, Troubleshooting 30%. The questions below are grouped accordingly. For deeper context on each domain and the full 6-week preparation timeline, visit the CKA Complete Guide.

Domain 1: Cluster Architecture, Installation & Configuration (25%)

Q1 — etcd Snapshot Backup (weight ~8%)

Scenario

The control-plane node is k8s-master. The etcd TLS assets are at /etc/kubernetes/pki/etcd/. Take a snapshot of the etcd database and save it to /opt/backup/etcd-snapshot.db.

Answer

SSH to the control-plane node, then run:

ETCDCTL_API=3 etcdctl snapshot save /opt/backup/etcd-snapshot.db \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key

Verify: ETCDCTL_API=3 etcdctl snapshot status /opt/backup/etcd-snapshot.db --write-out=table. The output must show a non-zero Revision. The three TLS flags (--cacert, --cert, --key) are mandatory — omitting any one produces a connection refused error that costs full task marks.

Q2 — etcd Snapshot Restore (weight ~8%)

Scenario

Restore the etcd snapshot at /opt/backup/etcd-snapshot.db to the directory /var/lib/etcd-restore. Then update the etcd static pod manifest to use the new data directory.

Answer

ETCDCTL_API=3 etcdctl snapshot restore /opt/backup/etcd-snapshot.db \
--data-dir=/var/lib/etcd-restore

Then edit /etc/kubernetes/manifests/etcd.yaml. Find the --data-dir flag under spec.containers[0].command and the hostPath volume mount, changing both from /var/lib/etcd to /var/lib/etcd-restore. The kubelet watches the manifests directory and will restart the etcd pod automatically. Confirm with k get pods -n kube-system once etcd is Running again.

Q3 — RBAC: Role + RoleBinding for a ServiceAccount (weight ~6%)

Scenario

In namespace dev, create a ServiceAccount named ci-runner. Create a Role named pod-reader that allows get, list, and watch on pods. Bind it to ci-runner via a RoleBinding named ci-runner-binding.

Answer

k create sa ci-runner -n dev
k create role pod-reader -n dev --verb=get,list,watch --resource=pods
k create rolebinding ci-runner-binding -n dev --role=pod-reader --serviceaccount=dev:ci-runner

Verify: k auth can-i list pods -n dev --as=system:serviceaccount:dev:ci-runner must print yes. The subject in the RoleBinding must use the namespace:serviceaccount-name form — the most common exam mistake is omitting the namespace prefix.

Q4 — Cluster Upgrade with kubeadm (weight ~6%)

Scenario

The cluster is running Kubernetes v1.29. Upgrade the control-plane node to v1.30 using kubeadm, then drain the control-plane, upgrade kubelet and kubectl, and uncordon the node.

Answer

On the control-plane node:

apt-mark unhold kubeadm && apt-get install -y kubeadm=1.30.0-00 && apt-mark hold kubeadm
kubeadm upgrade plan
kubeadm upgrade apply v1.30.0
kubectl drain k8s-master --ignore-daemonsets --delete-emptydir-data
apt-mark unhold kubelet kubectl && apt-get install -y kubelet=1.30.0-00 kubectl=1.30.0-00 && apt-mark hold kubelet kubectl
systemctl daemon-reload && systemctl restart kubelet
kubectl uncordon k8s-master

Verify: k get nodes should show v1.30.x for the control-plane. Only upgrade one minor version at a time — skipping versions is not supported.

Domain 2: Workloads & Scheduling (15%)

Q5 — Deployment with Taint Toleration (weight ~4%)

Scenario

Node node02 has the taint env=prod:NoSchedule. Create a Deployment named prod-web in namespace production running image nginx:1.25 with 2 replicas. The pods must schedule on node02.

Answer

k create deploy prod-web --image=nginx:1.25 --replicas=2 -n production $do > deploy.yaml

Add under spec.template.spec:

tolerations:
- key: "env"
operator: "Equal"
value: "prod"
effect: "NoSchedule"
nodeSelector:
kubernetes.io/hostname: node02

k apply -f deploy.yaml

Verify: k get po -n production -o wide — all pods should show node02 in the NODE column. Using operator: "Exists" instead of "Equal" with a value is a common YAML mistake that causes the toleration to silently fail.

Q6 — Rolling Update + Rollback (weight ~4%)

Scenario

Deployment frontend in namespace default is running nginx:1.24. Update it to nginx:1.25-broken (an image that will fail). After confirming the rollout is degraded, roll it back to the previous version.

Answer

k set image deploy/frontend nginx=nginx:1.25-broken
k rollout status deploy/frontend # watch for degraded message
k rollout undo deploy/frontend
k rollout status deploy/frontend # confirm "successfully rolled out"

Verify: k describe deploy frontend | grep Image must show nginx:1.24. If you need to roll back to a specific revision: k rollout undo deploy/frontend --to-revision=1 (check history first with k rollout history deploy/frontend).

Q7 — ConfigMap Injected as Environment Variable (weight ~4%)

Scenario

Create a ConfigMap named app-config in namespace default with key APP_ENV=production. Create a Pod named app-pod using image busybox:1.36 that runs sleep 3600 and exposes APP_ENV as an environment variable sourced from the ConfigMap.

Answer

k create cm app-config --from-literal=APP_ENV=production
k run app-pod --image=busybox:1.36 --command -- sleep 3600 $do > pod.yaml

Add to spec.containers[0] in pod.yaml:

env:
- name: APP_ENV
valueFrom:
configMapKeyRef:
name: app-config
key: APP_ENV

k apply -f pod.yaml

Verify: k exec app-pod -- env | grep APP_ENV must print APP_ENV=production.

Domain 3: Services & Networking (20%)

Q8 — Expose a Deployment via NodePort (weight ~5%)

Scenario

Deployment web in namespace default exposes port 80. Create a NodePort Service named web-svc that maps port 80 on the Service to port 80 on the pods and exposes it as NodePort 30080.

Answer

k expose deploy web --name=web-svc --port=80 --target-port=80 --type=NodePort $do > svc.yaml

In svc.yaml, under spec.ports[0] add nodePort: 30080, then:

k apply -f svc.yaml

Verify: k get svc web-svc must show 80:30080/TCP. Test with curl <node-ip>:30080 from outside the cluster. NodePort range is 30000-32767; specifying a port outside that range causes validation failure.

Q9 — NetworkPolicy Default Deny + Targeted Allow (weight ~7%)

Scenario

In namespace restricted, create a NetworkPolicy named default-deny-ingress that blocks all ingress traffic to every pod. Then create a second NetworkPolicy named allow-frontend that allows ingress to pods labelled app=backend only from pods labelled app=frontend on port 8080.

Answer

Create netpol.yaml:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
namespace: restricted
spec:
podSelector: {}
policyTypes: [Ingress]
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend
namespace: restricted
spec:
podSelector:
matchLabels:
app: backend
policyTypes: [Ingress]
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080

k apply -f netpol.yaml

Verify: k get netpol -n restricted should list both policies. An empty podSelector: {} selects all pods in the namespace — the correct syntax for a blanket deny. Putting from: [] (empty list) instead of omitting from entirely means "allow from nothing" but is not the canonical default-deny form; use the policyTypes-only pattern.

Q10 — Ingress Rule for Two Paths (weight ~6%)

Scenario

Services api-svc (port 8080) and web-svc (port 80) exist in namespace default. Create an Ingress named app-ingress that routes /api to api-svc:8080 and / to web-svc:80 using pathType: Prefix.

Answer

Create ingress.yaml:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress
spec:
rules:
- http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: api-svc
port:
number: 8080
- path: /
pathType: Prefix
backend:
service:
name: web-svc
port:
number: 80

k apply -f ingress.yaml

Verify: k describe ingress app-ingress must show both path rules and an ADDRESS assigned. If the nginx Ingress controller is not installed, the ADDRESS will remain empty — install it with k apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/cloud/deploy.yaml if permitted by the task.

Domain 4: Storage (10%)

Q11 — PersistentVolume + PersistentVolumeClaim (weight ~5%)

Scenario

Create a PersistentVolume named pv-logs with 500Mi capacity, accessModes: ReadWriteOnce, hostPath: /mnt/logs, and storageClassName: manual. Then create a PersistentVolumeClaim named pvc-logs in namespace default requesting 200Mi with the same storage class and access mode.

Answer

Create storage.yaml:

apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-logs
spec:
capacity:
storage: 500Mi
accessModes: [ReadWriteOnce]
storageClassName: manual
hostPath:
path: /mnt/logs
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-logs
namespace: default
spec:
accessModes: [ReadWriteOnce]
storageClassName: manual
resources:
requests:
storage: 200Mi

k apply -f storage.yaml

Verify: k get pv,pvc — PVC must show Bound status. If it stays Pending, the storageClassName or accessMode does not match the PV — the most common mistake.

Q12 — Pod Mounting a PVC (weight ~4%)

Scenario

Create a Pod named logger in namespace default using image busybox:1.36 that runs sleep 3600. Mount the PVC pvc-logs at /var/log/app inside the container.

Answer

Create logger-pod.yaml:

apiVersion: v1
kind: Pod
metadata:
name: logger
spec:
containers:
- name: logger
image: busybox:1.36
command: ["sleep","3600"]
volumeMounts:
- name: logs-vol
mountPath: /var/log/app
volumes:
- name: logs-vol
persistentVolumeClaim:
claimName: pvc-logs

k apply -f logger-pod.yaml

Verify: k exec logger -- df -h /var/log/app should show a mounted filesystem. The volumes[].name must exactly match volumeMounts[].name — a typo here causes the pod to stay Pending.

Domain 5: Troubleshooting (30%)

Q13 — CrashLoopBackOff Pod (weight ~7%)

Scenario

Pod broken-app in namespace staging is in CrashLoopBackOff. Identify why it is crashing and fix it. The pod should run image nginx:1.25 and remain Running.

Answer

Start with: k describe po broken-app -n staging — check State, Last State, and Events. Then: k logs broken-app -n staging --previous to see the exit message.

Common root causes and fixes:

  • Wrong image tag: edit the pod spec (k edit po broken-app -n staging) and correct the image. Note: you may need to delete and recreate if the pod is not managed by a Deployment.
  • Bad command / args: locate the command or args field causing the non-zero exit and correct it.
  • Missing ConfigMap / Secret: k describe po Events will say Error: configmap "x" not found. Create the missing resource.
  • Resource limits too low: OOMKilled exit code 137. Increase resources.limits.memory.

Verify: k get po broken-app -n staging must show Running with RESTARTS not incrementing.

Q14 — Node NotReady (weight ~8%)

Scenario

Node node03 shows NotReady in kubectl get nodes. SSH to node03 and restore it to Ready without rebooting the node.

Answer

On node03:

systemctl status kubelet # check if kubelet is running
journalctl -u kubelet -n 50 --no-pager # read recent errors
systemctl start kubelet # if stopped
systemctl enable kubelet # ensure it restarts on reboot

Common causes visible in journalctl:

  • kubeconfig path wrong: look for failed to load Kubelet config file. Check /var/lib/kubelet/config.yaml exists and is valid.
  • Container runtime down: systemctl status containerd. If stopped: systemctl start containerd.
  • CNI plugin missing: log shows network plugin not ready. Apply the correct CNI manifest.
  • Certificate expired: log shows x509: certificate has expired. Renew with kubeadm certs renew all on the control plane.

Verify from the control plane: k get nodes must show node03 Ready within ~60 seconds of fixing kubelet.

Q15 — Service Not Reachable (weight ~8%)

Scenario

Service payment-svc in namespace default is not routing traffic to its pods. The pods are Running. Diagnose and fix the connectivity issue.

Answer

Systematic diagnosis:

k get svc payment-svc -o yaml # check selector and port
k get po -l app=payment -o wide # check pod labels and IPs
k get endpoints payment-svc # if Endpoints is <none>, selector mismatch

If Endpoints shows <none>: the Service selector does not match the pod labels. Fix options:

  • Edit the Service selector: k edit svc payment-svc → update spec.selector to match the pod labels exactly.
  • Or add/correct the label on the pods: k label po <pod-name> app=payment.

If Endpoints is populated but traffic still fails:

k run test --rm -it --image=nicolaka/netshoot --restart=Never -- curl payment-svc:<port>

Check targetPort matches the container port. Check NetworkPolicy is not blocking the traffic. Use k exec -it <pod> -- netstat -tlnp to confirm the app is listening on the expected port.

Verify: k get endpoints payment-svc must show at least one IP:port pair. The test pod curl must return an HTTP response.

Common Mistakes to Avoid

These errors show up in post-exam debriefs more than any others:

  • Wrong cluster context — always run k config use-context <context> as the first line of every task. Working in the wrong cluster silently zeros the task.
  • Namespace omission — if the task specifies a namespace, every k apply, k create, and k get must include -n <namespace>. Objects land in default otherwise and the grader won't find them.
  • etcd flag typos--cacert not --ca-cert, snapshot save not snapshot backup. The exact flags matter; etcdctl exits non-zero on any typo.
  • RBAC subject namespace — in a RoleBinding, the subject for a ServiceAccount must be system:serviceaccount:<namespace>:<name>. Omitting --serviceaccount=ns:sa (and using --user instead) creates a binding that never matches.
  • PV/PVC accessMode or storageClassName mismatch — the PVC stays Pending forever. Always confirm both sides match exactly, including capitalisation (ReadWriteOnce not readwriteonce).
  • Forgetting to verify — a missing k get or k exec verification step means you submit quietly broken work. Budget 30 seconds per task to confirm.

For a full breakdown of exam-day tactics, see CKA Exam Day Tips 2026. If you are weighing CKA against CKAD, the CKA vs CKAD comparison covers which cert fits which career path.

How to Practice Effectively

The 15 questions above cover the most-tested concepts. To build the exam speed and muscle memory that actually passes the CKA, layer in these habits:

  • Work in a real cluster. Kind or minikube on your laptop is fine. The browser-based simulators are useful supplements, not replacements. Typing real commands against real pods builds the reflex the exam demands.
  • Set a timer. Each of the 15 questions above should take you under 8 minutes end-to-end including verification. If you exceed that, the topic needs more drilling. The real exam allows about 7 minutes per task on average.
  • Deliberately break things. Kill the kubelet, assign a wrong image, add a selector typo, drain a node without uncordoning it. Then fix it from scratch. The Troubleshooting domain (30%) is won by pattern recognition built from repeated breakage-and-repair cycles.
  • Use the ExamCert free practice exam. The CKA practice exam generates auto-scored scenario questions across all five domains and explains the correct approach. Run a timed session after finishing each study week.
  • Run two killer.sh attempts strategically. First attempt: 4-7 days before the exam to identify weak areas. Second attempt: 48 hours before to reheat muscle memory. Both are included free with exam registration.
  • Read peer post-mortems. The r/kubernetes and CNCF Slack #cka-exam channels surface real exam patterns. Post-mortems from candidates who failed and retook are the most useful signal.

For a structured path from beginner to CKA-ready including the 6-week weekly plan, recommended courses, and lab exercises, read the CKA Study Guide 2026. If you have already passed CKA and want the next challenge, the CKS Study Guide 2026 covers the security specialist path. If you are exploring the developer track instead, see How to Pass CKAD 2026.

For context on how difficult the exam really is and what the actual pass rate looks like, the CKA pass rate and difficulty breakdown gives data-backed perspective. For a broader view of all CNCF certifications, visit the Kubernetes Certifications Guide.

Try Free CKA Practice Exam

Auto-scored CKA scenario questions across all 5 domains — unlimited and free.

Try Free CKA Practice Exam

Frequently Asked Questions

Are CKA practice questions multiple choice?

No. The real CKA exam is 100% performance-based — you type kubectl commands and edit YAML in a live cluster. Good practice questions simulate this by giving you a scenario prompt and expecting a specific terminal outcome, not a letter choice.

How many questions are on the CKA exam in 2026?

Typically 15-20 tasks in 2 hours. Each task carries a published weight (usually 4-13%). The pass mark is 66%. Linux Foundation does not disclose the exact task count per sitting.

What is the hardest domain on the CKA?

Troubleshooting (30% weight) trips the most candidates because it requires diagnosing broken clusters under time pressure. Cluster Architecture (25%) is the second most common stumbling block due to etcd backup/restore syntax and RBAC chain complexity.

Can I use kubectl during the CKA exam?

Yes — kubectl is the primary tool. You also have access to etcdctl, crictl, systemctl, journalctl, and vim/nano. One browser tab to kubernetes.io/docs is allowed. No local notes, no second monitor.

How do I know if my CKA practice answers are correct?

Run the verification command after each task: kubectl get, kubectl describe, or a targeted curl/nslookup. The killer.sh simulator (included free with exam registration) auto-scores your work. ExamCert's free CKA practice exam at /exams/cka/ also provides instant feedback per question.

Plan Your Kubernetes Cert Journey

Free tools to plan study time and chart your CNCF certification roadmap.

EC

ExamCert Team

Helping Kubernetes engineers pass CNCF certs with free AI-generated practice questions and field-tested study guides.