Overview
This domain starts before Kubernetes sees anything. You edit a Dockerfile, build an image with docker or podman, tag it and sometimes export it to a tar archive at a path the task gives. Then you decide how the code should run: a Deployment for stateless replicas, a DaemonSet for one Pod per node, a StatefulSet for stable identity, a Job for work that finishes, or a CronJob for work on a schedule. Job fields such as completions, parallelism and backoffLimit, and CronJob fields such as concurrencyPolicy, are common details.
The second half is Pod design. Init containers prepare the Pod before the app starts, native sidecars run beside it for its whole life, and containers share data through emptyDir volumes. Storage tasks ask you to request a PersistentVolumeClaim, mount it at the right path and match access modes and storage classes.
How it's tested
Design and build tasks usually describe what an application needs in plain language and leave the object choice to you. A typical prompt names an image, a schedule or a shared path and asks for a working resource in a specific namespace. Grading checks the live objects and, for images, the saved archive or tag.
-
Image build and export
You fix or extend a Dockerfile, build it with a given name and tag, then save the image as an OCI or Docker archive at an exact file path.
-
Workload choice from behaviour
The text says the work runs nightly, must finish once, or needs one copy per node, and you choose CronJob, Job or DaemonSet with matching fields.
-
Pod with helpers
An existing single-container Pod gains an init container that waits or seeds files, or a sidecar that ships logs from a shared emptyDir.
A task says a report must run every 30 minutes, never overlap a previous run, and keep only two successful Job records. A CronJob with schedule */30 * * * *, concurrencyPolicy Forbid and successfulJobsHistoryLimit 2 meets every condition. A Deployment running a loop with sleep would keep a Pod alive between runs and gives you no history limits or overlap control.
Competencies 4
Official competencies from the CNCF / The Linux Foundation outline, in outline order.
1.1 Define, build and modify container imagesWriting Dockerfiles, building, tagging and exporting images.
- What it means
- Applications reach Kubernetes as OCI images. This competency covers editing a Dockerfile or Containerfile, building it with the tool on the task host, tagging it, and handling the result as a file or in a local image store.
- What to understand
- Know FROM, COPY, RUN, ENV, WORKDIR, EXPOSE, USER, ENTRYPOINT and CMD, and that CMD supplies default arguments to ENTRYPOINT. Build with docker build -t name:tag . or podman build -t name:tag . and export with docker save or podman save -o file.tar name:tag. Multi-stage builds copy artifacts from a builder stage to shrink the final image. In a Pod spec, command overrides ENTRYPOINT and args overrides CMD.
- How it shows up
- Expect to change one Dockerfile instruction, rebuild with an exact tag and save the archive to a given path.
- Common confusion
- Thinking command in a Pod spec maps to CMD; it replaces the image ENTRYPOINT.
1.2 Choose and use the right workload resource (Deployment, DaemonSet, CronJob, etc.)Matching Deployments, DaemonSets, StatefulSets, Jobs and CronJobs to the workload.
- What it means
- Kubernetes offers several controllers for running Pods, each built for a different lifecycle. Choosing correctly means the controller handles scaling, scheduling, completion and retries instead of your own scripts.
- What to understand
- Deployments manage interchangeable replicas through ReplicaSets. StatefulSets give ordered startup, stable names and per-Pod claims. DaemonSets place one Pod on each eligible node. Jobs run Pods to completion and use completions, parallelism, backoffLimit and activeDeadlineSeconds. CronJobs create Jobs from a cron schedule and add concurrencyPolicy, startingDeadlineSeconds, history limits and an optional timeZone. Job Pod templates need restartPolicy Never or OnFailure.
- How it shows up
- A task describes run frequency or placement, and you create the matching object with the exact field values given.
- Common confusion
- Leaving restartPolicy at Always in a Job template, which the API rejects.
1.3 Understand multi-container Pod design patterns (e.g. sidecar, init and others)Init containers, native sidecars, ambassadors and adapters.
- What it means
- A Pod can hold several containers that share a network namespace and can share volumes. Patterns describe the role each extra container plays: preparing the Pod, helping the main app continuously, proxying its connections, or reshaping its output.
- What to understand
- Init containers run one after another and each must exit successfully before app containers start. A native sidecar is an entry in initContainers with restartPolicy: Always; it starts before the app, keeps running, and does not block Job completion. Ambassador containers proxy outbound calls on localhost, and adapters transform logs or metrics into a standard format. Containers in a Pod reach each other on localhost and exchange files through a shared emptyDir.
- How it shows up
- You may add a log-shipping sidecar or a wait-for-service init container to an existing Pod and mount a shared volume.
- Common confusion
- Expecting a regular second container to start before the app; only init containers guarantee ordering.
1.4 Utilize persistent and ephemeral volumesemptyDir, projected and configMap volumes, PersistentVolumeClaims and StorageClasses.
- What it means
- Container filesystems disappear when a container restarts. Volumes give Pods storage that either lives as long as the Pod, such as emptyDir, or outlives it through a PersistentVolumeClaim bound to a PersistentVolume.
- What to understand
- Declare volumes under spec.volumes and mount them with volumeMounts in each container that needs them. emptyDir supports medium: Memory and sizeLimit. A PVC requests storage size, accessModes such as ReadWriteOnce, ReadWriteMany or ReadWriteOncePod, and a storageClassName; it binds only to a PV that satisfies all three, or a provisioner creates one. Generic ephemeral volumes create a per-Pod claim deleted with the Pod. Check binding with kubectl get pvc.
- How it shows up
- Expect to create a PVC matching an existing PV, mount it at a stated path and confirm it is Bound.
- Common confusion
- A PVC stays Pending when its storageClassName or access mode does not match the intended PV.
High-yield concepts
The terms, rules and formulas this domain turns into questions most often.
-
ENTRYPOINT and CMD
ENTRYPOINT sets the executable; CMD supplies default arguments.
- Remember
- Pod command replaces ENTRYPOINT and Pod args replaces CMD.
- Tested as
- Explains why a container runs the wrong process after a spec edit.
- Trap
- Putting a full command line in args and expecting the entrypoint to vanish.
-
docker save / podman save
Writes an image and its layers to a tar archive.
- Remember
- Use -o path and the full name:tag so the archive holds the right image.
- Tested as
- Image tasks are often graded by the file at a given path.
- Trap
- Running docker export, which saves a container filesystem, not an image.
-
Job completion fields
completions sets how many successful Pods are needed; parallelism caps concurrent Pods.
- Remember
- backoffLimit counts retries before the Job is marked failed.
- Tested as
- Common values to set in batch tasks.
- Trap
- Confusing activeDeadlineSeconds with a per-Pod timeout.
-
CronJob concurrencyPolicy
Allow, Forbid or Replace decides what happens when a run is still active at the next schedule.
- Remember
- Forbid skips the new run; Replace stops the old one.
- Tested as
- Tasks often say runs must not overlap.
- Trap
- Assuming the default prevents overlap; the default is Allow.
-
Native sidecar container
An init container with restartPolicy: Always that keeps running alongside the app.
- Remember
- It starts before app containers and does not block Pod or Job completion.
- Tested as
- The current recommended way to add sidecars.
- Trap
- Declaring it under containers and losing the startup ordering.
-
Init container ordering
Init containers run sequentially, each to successful exit.
- Remember
- A failing init container keeps the Pod in Init status.
- Tested as
- Wait-for-dependency and seeding tasks rely on it.
- Trap
- Using a long-running process as a plain init container, which blocks the Pod forever.
-
emptyDir
Scratch volume created when the Pod is scheduled and deleted with it.
- Remember
- Survives container restarts but not Pod deletion.
- Tested as
- The usual shared volume between main app and sidecar.
- Trap
- Using it for data that must survive rescheduling.
-
PVC binding
A claim binds to a PV whose capacity, access modes and storage class satisfy it.
- Remember
- An empty string storageClassName means no dynamic provisioning.
- Tested as
- Storage tasks fail silently when the claim stays Pending.
- Trap
- Omitting storageClassName and getting the cluster default class instead of the prepared PV.
-
Access modes
ReadWriteOnce, ReadOnlyMany, ReadWriteMany and ReadWriteOncePod.
- Remember
- ReadWriteOnce is per node, not per Pod; ReadWriteOncePod limits to one Pod.
- Tested as
- Shows up when several replicas need the same data.
- Trap
- Assuming ReadWriteOnce stops two Pods on one node from mounting.
-
kubectl create --dry-run=client -o yaml
Generates a manifest skeleton without creating the object.
- Remember
- Works for deployments, jobs, cronjobs and more.
- Tested as
- Saves minutes on every build task.
- Trap
- Forgetting to remove the generated status and creationTimestamp fields when they cause confusion.
Side by side
Concepts candidates mix up, compared on the point that decides the answer.
Choosing a workload controller
| Concept | Meaning | Key difference | Common trap |
|---|---|---|---|
| Deployment | Keeps a set number of identical Pods running | Pods are interchangeable and rolled out gradually | Using it for one-off batch work |
| StatefulSet | Ordered Pods with stable names and per-Pod storage | Needs a headless Service for stable DNS | Choosing it for stateless web front ends |
| DaemonSet | One Pod per eligible node | Replica count follows node count | Setting replicas, which the spec does not have |
| Job | Runs Pods until a number of completions succeed | Stops when done instead of restarting forever | Leaving restartPolicy Always |
| CronJob | Creates Jobs on a cron schedule | Adds overlap control and history limits | Writing the schedule in local time without setting timeZone |
Extra containers in a Pod
| Concept | Meaning | Key difference | Common trap |
|---|---|---|---|
| Init container | Runs to completion before app containers start | Sequential and blocking | Expecting it to keep running |
| Native sidecar | Init container with restartPolicy Always | Starts first and runs for the Pod's lifetime | Leaving restartPolicy unset, which turns it into a blocking init container |
| Ambassador | Proxies the app's outbound connections | App talks to localhost instead of the remote host | Confusing it with a Service |
| Adapter | Converts app output into a standard format | Changes data shape, not connectivity | Labelling any helper a sidecar without stating its role |
Volume lifetimes
| Concept | Meaning | Key difference | Common trap |
|---|---|---|---|
| emptyDir | Scratch space tied to the Pod | Deleted when the Pod is removed | Storing data that must survive rescheduling |
| Generic ephemeral volume | PVC created and deleted with the Pod | Uses a StorageClass but is not kept | Expecting the claim to remain after Pod deletion |
| PersistentVolumeClaim | Request for storage that outlives Pods | Bound PV keeps data between Pods | Deleting the PVC and expecting a Retain PV to rebind automatically |
Exam traps
Each trap is an answer that looks right. Learn the clue that should change your mind.
-
Sidecar declared as a normal container
- What candidates pick
- Adding the log shipper under containers.
- Why it looks right
- Most older tutorials show sidecars that way.
- Why it's wrong
- It works for simple cases but gives no start ordering, and in a Job it keeps the Pod running after the main work ends.
Clue to watch for Wording such as 'must start before the application' or a Job with a helper.
-
CronJob overlap left at default
- What candidates pick
- Writing only the schedule and job template.
- Why it looks right
- The default looks safe when runs are short.
- Why it's wrong
- concurrencyPolicy defaults to Allow, so long runs stack up and the task requirement of no overlap is not met.
Clue to watch for Phrases like 'never run two at once' or 'skip if still running'.
-
Wrong export command
- What candidates pick
- Running docker export on a container.
- Why it looks right
- The name sounds like the right action.
- Why it's wrong
- export flattens one container's filesystem and loses image metadata and layers; save writes the image itself.
Clue to watch for The task names an image and tag, not a container.
-
PVC bound to a dynamic volume
- What candidates pick
- Leaving storageClassName out of the claim.
- Why it looks right
- The field seems optional.
- Why it's wrong
- With a default StorageClass present, the claim is provisioned from it and ignores the prepared PV the grader checks.
Clue to watch for A task that names an existing PersistentVolume to use.
-
Edit applied to the wrong object
- What candidates pick
- Editing a running Pod to add an init container.
- Why it looks right
- kubectl edit opens the Pod immediately.
- Why it's wrong
- Most Pod spec fields are immutable, so the edit fails; export the YAML, delete the Pod and recreate it.
Clue to watch for Any change to containers, volumes or init containers on a bare Pod.
-
Job retries miscounted
- What candidates pick
- Setting completions when the task asks for retries.
- Why it looks right
- Both are small integers on the Job spec.
- Why it's wrong
- completions sets required successes; backoffLimit sets how many failed attempts are tolerated.
Clue to watch for Words such as 'retry up to' or 'give up after'.
Answer framework
Work through these steps whenever a task describes an application and leaves the object design to you.
- Read how the code behaves: always on, finishes once, runs on a schedule, or needs a copy on each node, and note the namespace.
- Pick the controller from that behaviour and generate a skeleton with kubectl create and --dry-run=client -o yaml, saved to a file.
- Add helper containers by role: blocking setup as an init container, continuous support as a native sidecar.
- Wire storage by declaring each volume once, mounting it in every container that needs it, and matching PVC class and access mode.
- Apply, then confirm with kubectl get, describe and logs that Pods run, claims are Bound and files appear where expected.
Practice question
Want more like this? The CKAD practice test has questions for every domain.
Checklist
0 of 11
Tick each one you can do without notes. Your ticks stay in this browser.
Study strategy
Start with images, because many candidates have not built one recently. Write three small Dockerfiles, one of them multi-stage, then build, tag, run and save each with both docker and podman so the commands feel the same. Override command and args in a Pod spec and predict which process runs before you check.
Next, drill workload generation. Use kubectl create deployment, job and cronjob with --dry-run=client -o yaml until you can produce a correct CronJob with concurrency and history settings in under three minutes. Break a Job deliberately with a failing command and watch backoffLimit stop it.
Finish with Pod composition and storage. Add an init container that waits on nslookup of a Service, then convert a plain second container into a native sidecar and compare startup order with kubectl get pod -w. Create a PV and PVC pair, mismatch the class on purpose, and fix the Pending claim. Keep a short list of the fields you had to look up and review it before each mock exam.
FAQ
How much of the CKAD exam is Application Design and Build?
Application Design and Build carries 20% of the score in the CNCF curriculum and on the Linux Foundation exam page. Plan for three or four tasks drawn from its four competencies.
Is docker or podman available on the exam hosts?
Image tasks provide a build tool on the host they run on. Learn both CLIs, because their build, tag and save syntax is almost identical and either may appear.
Do I need to know StatefulSets for the CKAD?
They fall under choosing the right workload resource, so recognise when stable identity or per-Pod storage is needed. Deployments, Jobs and CronJobs appear far more often in developer tasks.
What is a native sidecar container?
It is an entry in initContainers with restartPolicy set to Always. Kubernetes starts it before the app containers and keeps it running, and it does not hold a Job open after the main container exits.
Can I add a container to a running Pod?
No. The container list of an existing Pod cannot be changed. Save the Pod YAML, delete the Pod, edit the file and create it again, or change the template of its controller.
Which storage objects should I expect?
Expect emptyDir for sharing, PersistentVolumeClaims for durable data, and occasionally a PersistentVolume you create yourself with hostPath for a lab-style task.
Other DevOps & Containers certifications
Where the same subject shows up in other exams. Cards marked "Same subject" open the matching domain.
Test your Domain 1 knowledge
Try timed tasks on image builds, workload choice, sidecar and init containers, and PVC mounts before moving to deployment.