CKAD Practice Questions 2026: 25 Free Sample Tasks + Pass-on-First-Try Tips
25 realistic CKAD tasks with kubectl solutions, grouped by domain — plus the 10 tips that separate killer.sh top scorers from candidates who run out of time.

Table of Contents
The CKAD is graded by what you produce, not what you know. You can recite every field of pod.spec from memory and still fail because you spent 14 minutes on a 6-minute task. The fix: solve tasks against the clock until each common pattern is automatic. This article gives you 25 of them, modelled on real CKAD scenarios and grouped by domain weight.
Tip: Spin up a local kind or minikube cluster before starting. Reading these tasks without typing the answers will not build the muscle memory you need on exam day. Type every command.
Why Practice Tasks Beat Memorization
The CKAD is the most performance-based major IT certification on the market. You will not be asked “which of the following is a Service type”; you will be told “create a Service of type NodePort that exposes the existing deployment web on port 80, target port 8080”, and you will have about six minutes to do it.
This format rewards two things memorization cannot give you: speed and recovery. Speed comes from having typed each common command hundreds of times. Recovery comes from knowing how to debug your own typo (you forgot the namespace, the readiness probe path is wrong, the NetworkPolicy blocks DNS) under time pressure, without panic.
The right way to use this list: solve each task from scratch in a fresh cluster, time yourself, and write down which ones took more than 8 minutes. Those are the tasks you drill again until they take less than 5.
10 Tips Before You Start
Set these up in every terminal you practice in — they are also the first things you set up in the exam.
- Alias kubectl.
alias k=kubectl && complete -F __start_kubectl k. Saves 6 characters per command times ~200 commands = 20 minutes back across the exam. - Export the dry-run trick.
export do="--dry-run=client -o yaml". Thenk run nginx --image=nginx $do > pod.yamlgenerates valid YAML in two seconds. - Export the force-delete shortcut.
export now="--force --grace-period=0". Skip the 30-second graceful shutdown when you need to recreate a pod. - Master
kubectl explain.k explain pod.spec.containerstells you every field offline — faster than the web docs. - Tab completion is your friend. Type
k get po+ TAB to autocomplete resource names. Cuts typo rate by ~80%. - Vim with line numbers. Add
set number pasteto~/.vimrc. Indentation errors become obvious. - Bookmark the docs. Pre-bookmark NetworkPolicy examples, SecurityContext reference, Pod multi-container examples, Helm CLI — these transfer into your exam browser.
- Always set context first. Tasks live in different clusters.
kubectl config use-context <ctx>is line 1 of every task. - Read the entire question before typing. Buried in line 4 of the task is often a constraint (specific labels, a namespace, a service account) that changes your answer.
- Verify before moving on. Always run
k get <resource> -n <ns>and confirm Running / Available before flagging the task as done.
5 Application Design Tasks
Task 1. Create a Pod with two containers sharing a volume
Pod shared in namespace ckad. Container writer (busybox) writes the date to /data/now every 5 seconds. Container reader (busybox) tails that file. Both mount an emptyDir at /data.
Solution: Generate base with k run shared --image=busybox -n ckad $do > p.yaml, then edit to add the second container and the emptyDir volume. Use command: ["sh","-c","while true; do date > /data/now; sleep 5; done"] on the writer.
Why: Multi-container pods always share network and any defined volumes — this is the sidecar pattern in its simplest form.
Task 2. Add an init container that waits for a Service
Pod web must not start its main nginx container until a Service named db resolves via DNS. Add an init container that loops nslookup db until it succeeds.
Solution: initContainers: [{name: wait-db, image: busybox, command: ['sh','-c','until nslookup db; do sleep 2; done']}]
Why: Init containers run sequentially before app containers. Common pattern for ordering pod startup against external dependencies.
Task 3. Create a Job that runs a calculation to completion
Job pi that runs the perl image with command perl -Mbignum=bpi -wle 'print bpi(2000)' and completes after 1 successful run.
Solution: k create job pi --image=perl -- perl -Mbignum=bpi -wle 'print bpi(2000)'. Verify with k get jobs and k logs job/pi.
Why: Jobs are run-to-completion workloads. Tracked by completions (default 1) and parallelism.
Task 4. Schedule a CronJob to run every minute
CronJob hello in namespace ckad that runs busybox every minute and echoes “Hello from CronJob”.
Solution: k create cronjob hello -n ckad --image=busybox --schedule="*/1 * * * *" -- echo "Hello from CronJob". Watch with k get jobs -n ckad -w.
Why: CronJobs wrap Jobs with a cron-style schedule. Each schedule firing creates a new Job which creates pods.
Task 5. Create a PVC and mount it in a Pod
Create a PVC data-pvc requesting 1Gi, ReadWriteOnce, default StorageClass. Create a Pod that mounts it at /data.
Solution: Write the PVC manifest by hand (no imperative shortcut), then add volumes: [{name: d, persistentVolumeClaim: {claimName: data-pvc}}] and volumeMounts: [{name: d, mountPath: /data}].
Why: PVCs claim storage abstractly; the cluster’s StorageClass binds them to a PV. Common exam pattern.
5 Application Deployment Tasks
Task 6. Create a Deployment with 4 replicas
Deployment web in default, image nginx:1.25, 4 replicas, container port 80.
Solution: k create deployment web --image=nginx:1.25 --replicas=4 --port=80. Verify with k get deploy web -o wide.
Why: Deployments are the standard wrapper for stateless workloads. Always know the imperative form.
Task 7. Roll out an image update and observe progress
Update the web deployment to use nginx:1.26. Watch the rollout. Record the change with a meaningful message.
Solution: k set image deployment/web nginx=nginx:1.26 --record, then k rollout status deployment/web.
Why: kubectl set image is faster than editing the deployment YAML. The --record flag annotates the revision for later rollback.
Task 8. Roll back to the previous revision
The 1.26 image is broken. Roll the web deployment back to the previous revision.
Solution: k rollout history deployment/web to see revisions, then k rollout undo deployment/web. Verify with k rollout status.
Why: Rollouts produce ReplicaSets keyed by revision. Undo points the deployment selector at the previous RS.
Task 9. Install a Helm chart and upgrade it
Install Bitnami nginx with release name my-web in namespace helm-test. Upgrade to set service.type=ClusterIP.
Solution: helm repo add bitnami https://charts.bitnami.com/bitnami, then helm install my-web bitnami/nginx -n helm-test --create-namespace. Upgrade with helm upgrade my-web bitnami/nginx -n helm-test --set service.type=ClusterIP.
Why: Helm packages YAML into versioned charts with templated values. CKAD tests basic install/upgrade/rollback only.
Task 10. Create a Kustomize overlay
Given a base Deployment manifest, create a kustomization that overrides the replica count to 3 and the image tag to v2.
Solution: In an overlay dir, create kustomization.yaml with resources: [../base], replicas: [{name: web, count: 3}], images: [{name: nginx, newTag: v2}]. Apply with k apply -k ..
Why: Kustomize is built into kubectl. Useful for environment-specific tweaks without templating.
4 Observability Tasks
Task 11. Add liveness and readiness probes
Deployment web uses nginx. Add a liveness probe (HTTP GET / on port 80, every 10s) and a readiness probe (same, every 5s with initial delay 3s).
Solution: k edit deploy web, add livenessProbe: {httpGet: {path: /, port: 80}, periodSeconds: 10} and readinessProbe: {httpGet: {path: /, port: 80}, periodSeconds: 5, initialDelaySeconds: 3}.
Why: Liveness restarts failing containers; readiness controls Service endpoint membership. Different roles — never conflate them.
Task 12. Get logs from a crashed container
Pod app has CrashLoopBackOff. Retrieve the logs from the previous container instance.
Solution: k logs app --previous. If the pod has multiple containers: k logs app -c <container> --previous.
Why: Current container is restarting and may have no logs yet. --previous reads the last terminated container’s log buffer.
Task 13. Use kubectl top to find the highest-memory pod
Across all namespaces, find the pod consuming the most memory.
Solution: k top pod -A --sort-by=memory | head. Requires metrics-server installed in the cluster.
Why: kubectl top reads from the metrics API. Standard observability check during triage.
Task 14. Debug a Pod with an ephemeral container
Pod buggy is running a distroless image with no shell. Attach a busybox ephemeral container to inspect.
Solution: k debug buggy -it --image=busybox --target=<container>. Shares the target’s process namespace.
Why: Ephemeral containers solve the “no shell in the image” problem for production debugging without rebuilding the image.
6 Configuration & Security Tasks
Task 15. Create a ConfigMap from literals and mount as env
ConfigMap app-cfg with LOG_LEVEL=info and FEATURE_FLAG=true. Mount both as environment variables in pod app.
Solution: k create configmap app-cfg --from-literal=LOG_LEVEL=info --from-literal=FEATURE_FLAG=true. In the pod: envFrom: [{configMapRef: {name: app-cfg}}].
Why: envFrom injects every key as an env var — faster than listing each one.
Task 16. Mount a Secret as a file
Create a Secret db-creds with key password=s3cret. Mount it as a file at /etc/db/password in pod app.
Solution: k create secret generic db-creds --from-literal=password=s3cret. In the pod: volumes: [{name: s, secret: {secretName: db-creds}}] and volumeMounts: [{name: s, mountPath: /etc/db, readOnly: true}].
Why: Files reflect Secret updates without pod restart; env vars do not. Pick the right pattern per use case.
Task 17. Enforce runAsNonRoot
Configure pod web to refuse to start if its image runs as root. Verify by deploying first the nginx image (root-by-default), then nginxinc/nginx-unprivileged.
Solution: securityContext: {runAsNonRoot: true} at the pod or container level. nginx pod fails to start; unprivileged variant succeeds.
Why: Security boundary enforced at admission. Common Pod Security Standard requirement.
Task 18. Create a ServiceAccount and grant it list-pod permission
ServiceAccount reader in ckad. Role allowing get/list on pods. RoleBinding to the SA. Pod that uses the SA.
Solution: k create sa reader -n ckad, k create role pod-reader -n ckad --verb=get,list --resource=pods, k create rolebinding rb -n ckad --role=pod-reader --serviceaccount=ckad:reader. Pod uses serviceAccountName: reader.
Why: Default SA has minimal permissions. Custom SAs scope what each app can do via RBAC.
Task 19. Set CPU and memory requests/limits
Pod app should request 100m CPU and 128Mi memory, with limits of 500m CPU and 256Mi memory.
Solution: resources: {requests: {cpu: 100m, memory: 128Mi}, limits: {cpu: 500m, memory: 256Mi}} on the container.
Why: Requests drive scheduling and QoS class; limits enforce a hard ceiling and trigger OOM kills.
Task 20. Apply Pod Security Standard “restricted” to a namespace
Namespace secure should enforce the restricted Pod Security Standard.
Solution: Label the namespace: k label ns secure pod-security.kubernetes.io/enforce=restricted. Pods violating the standard will be rejected.
Why: Pod Security Admission replaces the removed PodSecurityPolicy. Three modes: enforce, audit, warn.
5 Services & Networking Tasks
Task 21. Expose a Deployment as a ClusterIP Service
Expose the web deployment (port 80, target 8080) as a ClusterIP service named web-svc.
Solution: k expose deployment web --name=web-svc --port=80 --target-port=8080. Verify with k get svc web-svc and k get endpoints web-svc.
Why: ClusterIP is the default Service type. Always check endpoints; an empty endpoint list means the selector does not match any pods.
Task 22. Create an Ingress with two paths
Ingress app-ingress on host app.example.com. Path /api routes to service api:8080; path / routes to service web:80.
Solution: k create ingress app-ingress --rule="app.example.com/api=api:8080" --rule="app.example.com/*=web:80".
Why: Ingress provides HTTP/HTTPS routing. Requires an Ingress controller (nginx, traefik) installed in the cluster.
Task 23. Default-deny NetworkPolicy
In namespace locked, deny all ingress to all pods.
Solution: NetworkPolicy with podSelector: {} and policyTypes: [Ingress] — no ingress rules means deny all.
Why: Empty podSelector matches every pod in the namespace. Empty policyTypes ingress with no rules = deny all ingress.
Task 24. Allow ingress from a specific label
In locked, allow ingress to pods with label app=db only from pods with label role=api on port 5432.
Solution: NetworkPolicy with podSelector: {matchLabels: {app: db}}, ingress from: [{podSelector: {matchLabels: {role: api}}}], ports [{port: 5432}].
Why: Label-based source matching is the most common NetworkPolicy pattern.
Task 25. Resolve a Service by DNS from inside a pod
From a pod in namespace app, resolve service web-svc in namespace web by full DNS name.
Solution: k exec -it <pod> -n app -- nslookup web-svc.web.svc.cluster.local.
Why: Cross-namespace service resolution requires the full FQDN. Same-namespace can use the short name.
How to Speed-Run Tasks Like a Killer.sh Top Scorer
Top scorers on killer.sh share three habits.
First, they touch the keyboard within 10 seconds of reading a task. There is no “think about it first” phase — reading and typing happen in parallel. Open the file, set the context, then re-read the task while the editor is loading. The first line of every task script: k config use-context <ctx>; k config set-context --current --namespace=<ns>.
Second, they imperative-first, edit-second. They never hand-write a manifest from scratch when an imperative command can scaffold one. k create <resource> ... $do > file.yaml && vim file.yaml && k apply -f file.yaml is the universal pattern.
Third, they batch-verify. Rather than typing k get pods after every change, they queue up the task, apply it, and run a single k get pod,svc,deploy -n <ns> check at the end. This drops verification time from ~10 commands to one.
One bonus trick: use watch -n 2 'kubectl get pods -n <ns>' in a separate tmux pane during multi-step tasks. You see status changes in real time and skip the manual refresh.
After 25 Tasks: Where to Go Next
If you solved most of these in under 8 minutes, you are roughly where you need to be for the real exam. If you struggled, do another 25-50 tasks from killer.sh (2 free runs come with the $445 exam — do not waste them) or KodeKloud’s free tier labs.
For the most realistic timed practice, the ExamCert CKAD question sets include 3 free sets covering all 5 domains. Pair them with our CKAD 8-week study guide for full prep coverage.
Practice CKAD with Free AI Questions
Three free question sets covering all 5 CKAD domains. Start instantly, no signup required.
Try CKAD Practice ExamFrequently Asked Questions
How many CKAD practice questions should I do?
Aim for 80-100 tasks across all domains before booking. Quality > quantity — solve each in under 8 minutes.
Where can I find free CKAD practice tasks?
ExamCert (3 free question sets), killer.sh (free official exam includes 2 simulator runs), KodeKloud (free tier), and the official Kubernetes documentation tutorials.
Should I memorize kubectl commands for CKAD?
Yes, but focus on the imperative shortcuts (kubectl run/create/expose with --dry-run -o yaml) and kubectl explain. The docs are allowed, but lookup costs 30-60 seconds per task.
What’s the difference between CKAD and CKA practice?
CKAD focuses on application-level objects (Pods, Deployments, Services, ConfigMaps). CKA focuses on cluster-level admin (etcd, kubeadm, RBAC, troubleshooting nodes). The kubectl skills overlap heavily.
How long should I practice each task?
6-8 minutes each. If you are regularly above 10 minutes, you will run out of time on the real exam.
Plan Your CKAD Prep
Free tools to estimate study time and map your Kubernetes certification path.
