CKAD theory
CKAD20% of the exam

Application Design and Build

Package code into containers and run it with the right workload, multi-container, batch, and storage patterns.

The full loop: understand → drill the commands → prove it under the clock. Every objective below is taught here and practised in the drills.

1Understand it

Containers & images

A container packages your app with everything it needs, code, runtime, libraries, into one isolated, portable unit. A Dockerfile builds an image; a running copy of that image is a container.

An image is a recipe; a container is the cooked dish. The same recipe makes the identical dish in any kitchen (machine).
  • Dockerfile → image (build once) → container (run many).
  • Images are layered and immutable; tag with versions, not just :latest.
  • Multi-stage builds keep final images small by discarding build tools.
Exam tip: You won't build images much in CKAD, but know how a Pod references one: spec.containers[].image.
Choosing the right workload

Kubernetes has a controller for each kind of app. A Deployment runs stateless apps; a StatefulSet runs apps that need stable names and their own storage (databases); a DaemonSet runs one Pod on every node (agents); a Job/CronJob runs batch work once or on a schedule.

Pick the right vehicle for the trip: Deployment is a fleet of identical taxis, StatefulSet is numbered reserved cars, DaemonSet is "one on every street", Job is a single delivery run.
  • Deployment: stateless, interchangeable replicas.
  • StatefulSet: stable network IDs + per-Pod persistent storage.
  • DaemonSet: exactly one Pod per (matching) node.
  • Job / CronJob: run-to-completion / scheduled batch work.
Exam tip: If the task says "one per node" → DaemonSet; "stable identity / storage" → StatefulSet; "run once" → Job.
Pods, the smallest unit

A Pod is the smallest thing Kubernetes runs. It wraps one or more containers that share the same network address and can share storage. Most Pods hold a single container; in production a controller like a Deployment manages them for you.

A Pod is like an apartment: the containers inside are roommates who share one address (IP) and some shared rooms (volumes).
  • Containers in a Pod share the Pod's IP and localhost.
  • A Pod is ephemeral, if it dies it is replaced, not resurrected.
  • kubectl run / create generate Pods or higher-level objects.
Exam tip: Generate fast: kubectl run nginx --image=nginx --dry-run=client -o yaml > pod.yaml
Multi-container patterns

Sometimes a Pod runs a helper beside the main app. An init container runs to completion before the app starts (setup); a sidecar runs alongside the app for its whole life (logging, proxying). They compose behaviour without changing the main app.

Init container = the person who unlocks and preps the shop before opening. Sidecar = the assistant working beside you all day.
  • initContainers run sequentially to completion before app containers start.
  • Sidecars (log shipper, Istio proxy) share the Pod lifecycle and volumes.
  • Patterns: sidecar, ambassador (proxy outbound), adapter (reshape output).

Init container that waits for a dependency

spec:
  initContainers:
  - name: wait-db
    image: busybox:1.36
    command: ['sh','-c','until nc -z db 5432; do sleep 2; done']
  containers:
  - name: app
    image: myapp:1.0
Exam tip: initContainers is a separate list from containers, don't put them in the same array.
Jobs & CronJobs

A Job runs a Pod until a task completes successfully, then stops, ideal for batch work like a migration. A CronJob runs Jobs on a schedule, like cron on Linux.

A Job is a one-off errand you mark "done". A CronJob is a recurring calendar reminder that kicks off that errand automatically.
  • Job: completions and parallelism control how many Pods run/succeed.
  • backoffLimit caps retries on failure.
  • CronJob uses standard cron syntax in spec.schedule.
Exam tip: kubectl create job db-migrate --image=migrate -- ./run.sh · kubectl create cronjob nightly --image=busybox --schedule="0 2 * * *" -- echo hi
Volumes, ephemeral & persistent

Containers lose their files when they restart, so Pods use Volumes for storage. An emptyDir lasts as long as the Pod and is shared between its containers (scratch space). For storage that survives the Pod, a PersistentVolumeClaim (PVC) requests durable storage, which Kubernetes binds to a PersistentVolume (PV).

emptyDir is a shared scratchpad the roommates use while they live there. A PVC is renting a storage unit that keeps your stuff even after you move out.
  • emptyDir: Pod-lifetime, shared across the Pod's containers.
  • PVC requests storage; a PV (often auto-provisioned via a StorageClass) fulfils it.
  • Always two halves: spec.volumes (define) + container.volumeMounts (use).
  • Access modes: RWO (one node), ROX (many read), RWX (many read/write).

Mount a PVC for durable storage (swap for emptyDir = scratch)

spec:
  containers:
  - name: app
    image: nginx
    volumeMounts:
    - name: data
      mountPath: /usr/share/nginx/html
  volumes:
  - name: data
    persistentVolumeClaim:
      claimName: web-pvc
    # emptyDir: {}   # <- use this instead for pod-lifetime scratch
Exam tip: You can't generate PVCs imperatively, write the YAML. Forgetting either volumes OR volumeMounts is the classic mistake.

2 Drill the commands & prove it

Mastery, 0/6 objectives

An objective turns green only when you've solved every drill in it, not just one.

  • Create Pods imperatively with kubectl run: images, env vars, commands/args, labels, and restart policy0/7
  • Generate YAML manifests with --dry-run=client -o yaml and redirect to file for editing0/3
  • Create and manage Deployments: image, replicas, scale, and expose as a Service0/5
  • Create Jobs and CronJobs, including --from=cronjob, schedules, and correct restartPolicy0/5
  • Inspect Pod volume and multi-container fields via kubectl explain (emptyDir, hostPath, shared volumes)0/2
  • Manage labels on running objects with kubectl label, including overwrite semantics0/2
Drill · 1 / 240 solved
Command

Create a single Pod named web running image nginx:1.27 (a bare Pod, not a Deployment).

$

Drills check the command pattern deterministically, there is often more than one correct form. For full fidelity, pair this with real-cluster reps (the killer.sh simulator is included free with your exam registration).