Home / devops-containers / Certified Kubernetes Application Developer (CKAD) / Cheat Sheet
Certified Kubernetes Application Developer (CKAD)

CKAD Cheat Sheet

CKAD Tests Shipping Working Workloads Fast in a Terminal — Not Architecture Knowledge

CKAD is a two-hour, 15–20 task lab on Kubernetes v1.37 for developers. Speed with kubectl generators, exact names and fixing the owning template rather than the Pod is what separates a pass from a near miss.

Check Your Readiness →
Among the harder certs
Avg: Not published by CNCF / The Linux Foundation
Pass: 750 / 1000
Most candidates understand Certified Kubernetes Application Developer (CKAD) concepts — and still fail. This exam tests how you apply knowledge under pressure.

CKAD Curriculum Domain Map (v1.37)

Every task names a context and namespace, and grading reads live objects or answer files at exact paths. Most items combine objects, such as a ConfigMap, Secret and securityContext inside one Deployment, so a single wrong key name loses the whole task.

  1. 01
    Application Environment, Configuration and Security (25%) — ConfigMaps, Secrets, ServiceAccounts, quotas, LimitRanges, securityContext, CRDs
  2. 02
    Application Design and Build (20%) — images, Jobs and CronJobs, init and native sidecar containers, PVC binding
  3. 03
    Application Deployment (20%) — rolling update tuning, rollback to a revision, blue/green, canary, Helm, Kustomize
  4. 04
    Services and Networking (20%) — selectors, port vs. targetPort, endpoints, cross-namespace DNS, NetworkPolicy labels, Ingress paths
  5. 05
    Application Observability and Maintenance (15%) — probe choice and timing, logs --previous, top, debug, deprecated APIs

Wrong instinct vs correct approach

A log helper in Pod encoder must start before the app and run for the Pod's lifetime
✕ Wrong instinct

Add the helper as a second entry under containers

✓ Correct approach

Declare it under initContainers with restartPolicy: Always, a native sidecar that starts first and keeps running. Share an emptyDir mounted in both containers, then export, delete and recreate the bare Pod because those fields are immutable.

Deployment catalog needs up to 120 seconds to load, and liveness keeps killing it during startup
✕ Wrong instinct

Raise initialDelaySeconds on the liveness probe to 120

✓ Correct approach

Add a startupProbe, for example periodSeconds 10 with failureThreshold 12, so liveness and readiness wait until it succeeds. The existing fast liveness check then protects the running app without delaying recovery.

A canary Deployment v2 sits beside v1, but no requests ever reach the canary Pods
✕ Wrong instinct

Increase the canary replica count until traffic appears

✓ Correct approach

The Service selector still includes version=v1, so v2 Pods never match. Select only a shared label such as app=api; traffic then splits roughly by replica ratio across both Deployments.

A CronJob must skip a run if the previous one is still active
✕ Wrong instinct

Set only the schedule and the job template

✓ Correct approach

concurrencyPolicy defaults to Allow, so overlapping runs stack up. Set concurrencyPolicy: Forbid to skip, or Replace to stop the old run. Retries are backoffLimit; completions counts required successes.

Know these cold

  • ▸ Generate skeletons — ubectl create deploy|job|cronjob ... --dry-run=client -o yaml > file.yaml
  • ▸ Pod command replaces ENTRYPOINT; Pod args replaces CMD
  • ▸ Save images with docker save -o file.tar name:tag; export only dumps a container filesystem
  • ▸ maxSurge and maxUnavailable default to 25%; both cannot be zero
  • ▸ Install charts with -n and --create-namespace; check helm show values before using --set
  • ▸ Apply kustomizations with kubectl apply -k; configMapGenerator adds a hash suffix to names
  • ▸ valueFrom renames one key; envFrom keeps key names; env vars never refresh without restart
  • ▸ storageClassName — " binds a prepared PV; omitting it uses the default StorageClass
  • ▸ Crash loops — ubectl logs --previous -c container; exit code 137 with OOMKilled means memory limit
  • ▸ Other-namespace Services resolve as name.namespace; Ingress backends use the Service port

Can you answer these without checking your notes?

In this scenario: "A log helper in Pod encoder must start before the app and run for the Pod's lifetime" — what should you do first?
Declare it under initContainers with restartPolicy: Always, a native sidecar that starts first and keeps running. Share an emptyDir mounted in both containers, then export, delete and recreate the bare Pod because those fields are immutable.
In this scenario: "Deployment catalog needs up to 120 seconds to load, and liveness keeps killing it during startup" — what should you do first?
Add a startupProbe, for example periodSeconds 10 with failureThreshold 12, so liveness and readiness wait until it succeeds. The existing fast liveness check then protects the running app without delaying recovery.
In this scenario: "A canary Deployment v2 sits beside v1, but no requests ever reach the canary Pods" — what should you do first?
The Service selector still includes version=v1, so v2 Pods never match. Select only a shared label such as app=api; traffic then splits roughly by replica ratio across both Deployments.

Common Exam Mistakes — What candidates get wrong

Adding a liveness probe when the task only wants traffic stopped

Readiness failure pulls the Pod from Service endpoints without restarting it; liveness failure restarts the container. For slow starters, add a startupProbe whose failureThreshold × periodSeconds covers boot time instead of inflating initialDelaySeconds on liveness.

Putting capabilities in the Pod-level securityContext

capabilities exists only on the container securityContext, and names drop the CAP_ prefix: add ["NET_BIND_SERVICE"]. runAsUser and runAsNonRoot can sit at either level; allowPrivilegeEscalation is container-level only.

Hunting for a failing Pod after a ResourceQuota rejection

Pods refused at admission are never created, so kubectl get pods shows nothing. The error lives in the ReplicaSet events. A compute quota in the namespace also means every container must declare requests and limits, or a LimitRange must supply defaults.

Running kubectl rollout undo once to reach a named older revision

undo returns only to the previous revision. Check kubectl rollout history, then use --to-revision=2. Scaling never creates revisions, and Helm releases use their own numbers through helm history and helm rollback.

Labelling a running Pod so an existing NetworkPolicy admits it

The ReplicaSet replaces that Pod from the template without the label. Patch the Deployment's Pod template labels instead, and leave the policies untouched when the task says not to modify them.

Resources to help you pass Certified Kubernetes Application Developer on your first attempt

CKAD rewards exact, fast kubectl work. See which task types still slow you down.