Courseiva

CCNA Application Design and Build Questions

75 of 149 questions · Page 1/2 · Application Design and Build · Answers revealed

1
MCQmedium

A developer creates a Deployment with 3 replicas that uses a ConfigMap mounted as a volume. After updating the ConfigMap, the developer expects the pods to pick up the new configuration immediately, but the old configuration is still in use. What is the most likely reason?

A.ConfigMap updates are not propagated to mounted volumes.
B.The kubelet sync interval delays the propagation of ConfigMap changes to pods.
C.The pods must be recreated after a ConfigMap update to see the changes.
D.ConfigMaps are immutable and cannot be updated.
AnswerB

The correct explanation is that the kubelet runs a periodic sync loop (commonly every 1 minute, configurable via `--sync-frequency`) that refreshes ConfigMap data into mounted volumes. Until that sync cycle runs, pods continue reading the previous version of the ConfigMap, which is why updates appear delayed. After the sync, the files are updated in place and subsequent reads see the new data.

Why this answer

When a ConfigMap is mounted as a volume, updates to the ConfigMap are eventually propagated to the pods, but not instantly. The kubelet periodically syncs mounted ConfigMaps (default interval is 60 seconds), so there is a delay before pods see the new configuration. This is the most likely reason the old configuration is still in use.

Exam trap

The trap here is that candidates often assume ConfigMap updates are either instant or require pod recreation, but the CKAD exam tests the nuance that mounted volumes are updated with a kubelet sync delay, while environment variables are not updated at all.

How to eliminate wrong answers

Option A is wrong because ConfigMap updates are propagated to mounted volumes — the kubelet does update the files in the volume, but with a sync delay. Option C is wrong because pods do not need to be recreated; the mounted volume is updated in-place by the kubelet, though some applications may require a restart to reload the configuration. Option D is wrong because ConfigMaps are not immutable by default; they can be updated unless explicitly created with the `immutable: true` field.

2
Multi-Selectmedium

Which TWO of the following are valid fields in a Job spec? (Select TWO.)

Select 2 answers
A.replicas
B.backoffLimit
C.schedule
D.restartPolicy
E.parallelism
AnswersB, E

backoffLimit is a valid field in the Job spec that determines how many retries the Job controller will attempt before marking the Job as failed. Each time a Pod fails, the controller increments the failure count, and when that count exceeds backoffLimit, the Job is considered failed and no further Pods are created. The default value is 6, and setting it to 0 means the Job fails immediately after the first unsuccessful Pod. This field works in conjunction with activeDeadlineSeconds and pod failure policies to control batch job resilience.

Why this answer

Options B (backoffLimit) and E (parallelism) are correct fields in a Job spec. 'backoffLimit' controls the number of retries before marking the Job as failed, and 'parallelism' specifies the maximum number of Pods running in parallel. Option A (replicas) is a field for Deployments, not Jobs. Option C (schedule) is used in CronJobs.

Option D (restartPolicy) is a Pod-level field; in Jobs, the restartPolicy is defaulted to OnFailure or Never but is not a top-level Job spec field.

3
MCQeasy

A team wants a Pod to expose two containers: a web server container listening on port 8080 and a metrics exporter container listening on port 9100. The Pod manifest must give each container its own containerPort so that monitoring tools can discover them. Which YAML snippet correctly declares both container ports in a single Pod?

A.spec: containers: - name: web image: nginx ports: - containerPort: 8080 - name: metrics image: exporter ports: - containerPort: 9100
B.spec: containers: - name: web image: nginx ports: - name: web port: 8080 - name: metrics image: exporter ports: - name: metrics port: 9100
C.spec: containers: - name: web image: nginx ports: - containerPort: 8080 - containerPort: 9100 - name: metrics image: exporter
D.spec: containers: - name: web image: nginx - name: metrics image: exporter ports: - containerPort: 8080 - containerPort: 9100
AnswerA

Each container in the Pod has its own ports list, and containerPort is declared per container. This snippet defines two containers, each with the appropriate containerPort, which matches the requirement that the web server and metrics exporter advertise ports 8080 and 9100 respectively.

Why this answer

Container ports belong inside each container's ports list under the Pod spec. Declaring containerPort 8080 for the web container and 9100 for the metrics container correctly describes two separate listeners in one Pod, matching the requirement for per-container port declarations.

Exam trap

The trap here is confusing Pod-level or Service-level port fields with the per-container containerPort field required in a Pod manifest.

4
MCQeasy

Which Kubernetes API version is used for creating a CronJob?

A.batch/v1beta1
B.batch/v1
C.cron/v1
D.apps/v1
AnswerB

batch/v1 is the stable API version for CronJob, promoted to GA in Kubernetes 1.21. It is the only currently served version, so any CronJob manifest must use apiVersion: batch/v1, kind: CronJob. This indicates that the resource is a controller in the batch group that creates Jobs on a schedule.

Why this answer

CronJob is a Kubernetes resource that was promoted to a stable API version in Kubernetes 1.21. The correct API version for creating a CronJob is batch/v1, as it is the current stable version. The batch/v1beta1 version is deprecated and removed in Kubernetes 1.25, so batch/v1 is the correct choice for CKAD exam scenarios.

Exam trap

The trap here is that candidates may recall the older batch/v1beta1 API version from earlier Kubernetes versions or confuse CronJob with other resources like Deployments (apps/v1), leading them to select a deprecated or incorrect API group.

How to eliminate wrong answers

Option A is wrong because batch/v1beta1 is a deprecated beta API version that was removed in Kubernetes 1.25; using it would fail on modern clusters. Option C is wrong because there is no cron/v1 API group in Kubernetes; CronJobs belong to the batch API group. Option D is wrong because apps/v1 is used for Deployments, StatefulSets, and DaemonSets, not for CronJobs.

5
Multi-Selectmedium

Which of the following are valid concurrencyPolicy values for a CronJob? (Select all that apply.)

Select 3 answers
A.Replace
B.Allow
C.Parallel
D.Forbid
E.Serial
AnswersA, B, D

The `Replace` policy is a valid concurrencyPolicy value, but it is not one of the two selected as correct in this question. It terminates the currently running job and starts a new one when the next scheduled time arrives.

Why this answer

Within a Kubernetes CronJob, the concurrencyPolicy field accepts three valid values: Allow, Forbid, and Replace. Allow permits multiple concurrent executions of the same job. Forbid prevents new executions while a previous one is still running.

Replace cancels the currently running job and starts a new one in its place. Options C (Parallel) and E (Serial) are not valid values. Therefore, the correct answers are Replace, Allow, and Forbid.

Exam trap

The CKAD exam expects you to know all three valid values for concurrencyPolicy. Do not mistakenly think that Replace is invalid; it is one of the three accepted values. Also, avoid selecting Parallel or Serial, as they are not part of the Kubernetes API.

6
MCQmedium

You run 'kubectl run debug-pod --image=busybox -it --restart=Never -- sh' but the pod starts and immediately exits. You want to keep the container running to execute commands later. What flag should you add?

A.--stdin=true
B.--command
C.-- sleep infinity
D.--attach
AnswerC

By placing `--` followed by `sleep infinity` after the image name, you tell `kubectl run` to use that as the container's command, replacing the default `sh` from busybox. `sleep` is a process that suspends execution for the given interval; `infinity` means it never returns, so the main process never exits and the container remains in Running state indefinitely. This gives you a stable debug Pod you can `kubectl exec` into to run troubleshooting commands without worrying about the container dying.

Why this answer

Adding `-- sleep infinity` to the `kubectl run` command overrides the default entrypoint (`sh`) with a command that runs `sleep infinity`, which keeps the container alive indefinitely. Without this, the interactive shell (`sh`) exits immediately when it has no input, causing the pod to terminate. The `--` separator passes the command to the container image's entrypoint, ensuring the process runs in the foreground and does not exit.

Exam trap

The CKAD exam often tests the misconception that `--stdin=true` or `-it` alone keeps the pod running, but without a long-running command, the shell exits immediately, and the pod terminates.

How to eliminate wrong answers

Option A is wrong because `--stdin=true` (or `-i`) keeps STDIN open but does not prevent the shell from exiting when no input is provided; the pod still terminates immediately. Option B is wrong because `--command` is used to override the default command in the container spec, but without specifying a long-running process like `sleep infinity`, the pod will still exit. Option D is wrong because `--attach` (or `-a`) attaches to the container's STDIN/STDOUT/STDERR but does not change the fact that the shell exits immediately; it only affects how the client interacts with the pod.

7
MCQmedium

A user runs 'kubectl run nginx --image=nginx --restart=Never' and the pod goes into 'Pending' state. What is a likely reason?

A.The image name is incorrect
B.The pod is missing a readiness probe
C.The pod's restart policy is set to Never
D.The node has insufficient resources to schedule the pod
AnswerD

Pending is the PodPhase Kubernetes uses while the scheduler attempts to bind the pod to a suitable node. If every node in the cluster lacks the CPU, memory, or other resources requested (or if no node meets the pod's resource requirements), the scheduler leaves the pod unschedulable, and it remains Pending. Running `kubectl describe pod` would show pod events with messages like `0/1 nodes are available: 1 Insufficient cpu/memory`, confirming this cause.

Why this answer

Pending often indicates resource constraints like insufficient CPU or memory.

8
Multi-Selectmedium

Which TWO practices optimize Docker image size? (Select 2)

Select 2 answers
A.Running 'apt-get upgrade' in the Dockerfile
B.Using a full OS base image like ubuntu:latest
C.Including a .dockerignore file to exclude unnecessary files
D.Using multi-stage builds to copy only necessary artifacts
E.Installing all packages in one layer without cleanup
AnswersC, D

Including a .dockerignore file excludes unnecessary files such as .git, node_modules, or build outputs from the Docker build context, so the daemon never sends them. This prevents those bulky files from being accidentally copied into the image with COPY or ADD, directly reducing final image size and also substantially speeding up the build by shrinking context.

Why this answer

A `.dockerignore` file prevents unnecessary files (e.g., local logs, node_modules, .git) from being sent to the Docker daemon during the `docker build` context, reducing the build context size and avoiding bloating the image with irrelevant data. Option D is correct because multi-stage builds allow you to compile or install dependencies in a temporary stage and then copy only the final runtime artifacts (e.g., compiled binaries) into a minimal final image, discarding build tools and intermediate layers.

Exam trap

A common pitfall tested in the CKAD exam is that running cleanup commands like `apt-get clean` in a separate RUN layer is ineffective; cleanup must occur in the same layer as the install to avoid persisting cached data in the intermediate layer.

9
MCQhard

You have a CronJob that runs every 5 minutes. The previous job is still running when the next scheduled time arrives. You want the new job to be skipped if the previous one is still running. Which concurrencyPolicy should you set?

A.Skip
B.Allow
C.Replace
D.Forbid
AnswerD

Setting `concurrencyPolicy: Forbid` on the CronJob ensures that if a previous Job instance is still actively running when the next scheduled time arrives, the new Job is simply skipped rather than queued or allowed to overlap. This directly satisfies the constraint in the stem that the new job must be skipped when the previous one is still executing, preventing concurrent runs without blocking future schedules.

Why this answer

The `Forbid` concurrency policy in Kubernetes CronJobs ensures that if a previous job instance is still running when the next scheduled time arrives, the new job is skipped entirely. This prevents overlapping executions, which is exactly the requirement in the question.

Exam trap

The trap here is that candidates may confuse 'Skip' with 'Forbid' because 'skip' sounds like it means 'do not start the new job,' but Kubernetes uses the term 'Forbid' for this behavior, and 'Skip' is not a valid concurrency policy value.

How to eliminate wrong answers

Option A (Skip) is wrong because there is no 'Skip' concurrency policy in Kubernetes CronJobs; the valid values are Allow, Forbid, and Replace. Option B (Allow) is wrong because it allows concurrent job runs, meaning the new job would start even if the previous one is still running, which contradicts the requirement. Option C (Replace) is wrong because it cancels the currently running job and starts a new one, rather than skipping the new job if the previous is still running.

10
MCQhard

A developer is writing a multi-stage Dockerfile for a Go application. The builder stage compiles the binary, and the final stage uses a minimal base image. The developer wants the final image to contain only the compiled binary and CA certificates, and wants to copy the binary from the builder stage. Which Dockerfile instruction correctly copies the compiled binary from the builder stage into the final stage?

A.RUN cp --from=builder /app/server /usr/local/bin/server
B.COPY --from=builder /app/server /usr/local/bin/server
C.COPY /app/server /usr/local/bin/server
D.ADD --stage=builder /app/server /usr/local/bin/server
AnswerB

The COPY --from flag references an earlier build stage by name, allowing files to be copied from that stage's filesystem into the current stage. This brings only the compiled binary into the final image, which matches the goal of a minimal image containing the binary and certificates.

Why this answer

Multi-stage builds allow later stages to copy artifacts from earlier stages using COPY --from=<stage>. Referencing the builder stage by name copies only the compiled binary into the minimal final image, keeping it small and free of build tooling while still including the binary.

Exam trap

The trap here is assuming a regular COPY or RUN can reach files from another build stage, when only COPY --from (or the older --from=0 index form) can access a previous stage.

11
MCQeasy

Which of the following Dockerfile instructions is used to set a command that runs when the container starts and can be overridden by command-line arguments?

A.EXPOSE
B.CMD
C.COPY
D.RUN
AnswerB

CMD defines the default command and parameters that are executed when a container is started from the image, making it the primary instruction for specifying the main process. It can be overridden by additional arguments passed to `docker run`, and it works together with ENTRYPOINT, where CMD provides default arguments to the entrypoint. Unlike RUN, CMD is not executed during the image build; it is stored in the image as metadata and executed at runtime.

Why this answer

The CMD instruction in a Dockerfile provides default command(s) for the executing container. When a user runs `docker run image [COMMAND]`, the provided COMMAND overrides the CMD value, making it the correct choice for a command that can be overridden by command-line arguments.

Exam trap

In the CKAD exam, candidates often confuse CMD with ENTRYPOINT. CMD provides default command that can be overridden by command-line arguments, whereas ENTRYPOINT specifies the executable that runs when the container starts and is not overridden unless --entrypoint flag is used.

How to eliminate wrong answers

Option A (EXPOSE) is wrong because it only documents which ports the container listens on at runtime; it does not execute any command. Option C (COPY) is wrong because it copies files from the build context into the image filesystem and has no effect on container startup behavior. Option D (RUN) is wrong because it executes commands during the image build process, creating new layers, and its effects are baked into the image; it cannot be overridden at container start.

12
MCQmedium

A DevOps engineer wants to deploy a logging sidecar container that reads log files from the main application container. Which volume type should be used to share files between the two containers?

A.emptyDir
B.persistentVolumeClaim
C.configMap
D.hostPath
AnswerA

emptyDir is a pod-scoped volume that is created empty when a pod is scheduled and survives only as long as the pod runs. It is mounted into all containers sharing the same lifecycle, making it the standard choice for a sidecar that reads logs written by the main application because both can access the same files without any persistent storage overhead. Its ephemeral nature is exactly what you want here—logs are consumed immediately and discarded with the pod, so no cleanup or durability guarantees are needed.

Why this answer

An emptyDir volume is the correct choice because it provides a shared, ephemeral storage space that is created when a Pod is assigned to a node and exists as long as that Pod is running. Both the main application container and the sidecar container can mount the same emptyDir volume at different mount paths, allowing the sidecar to read log files written by the main container. This volume type is ideal for sharing files between containers in the same Pod without requiring persistent storage.

Exam trap

The trap here is that candidates often confuse persistentVolumeClaim with a general-purpose shared volume, not realizing it is for persistent, Pod-independent storage, while emptyDir is the correct ephemeral volume for sharing files between containers in the same Pod.

How to eliminate wrong answers

Option B (persistentVolumeClaim) is wrong because it is used for persistent storage that outlives the Pod, not for sharing files between containers within the same Pod; it also requires a PersistentVolume and is overkill for temporary log sharing. Option C (configMap) is wrong because it is designed to inject configuration data (e.g., key-value pairs or small files) into containers, not for dynamic file sharing like log files that are written and read at runtime. Option D (hostPath) is wrong because it mounts a file or directory from the host node's filesystem into the Pod, which introduces node-level coupling and security risks, and is not the standard Kubernetes approach for inter-container communication within a Pod.

13
MCQmedium

A developer needs to expose a deployment named 'web-app' running on port 8080 to external traffic. The cluster is on-premises with no cloud load balancer. Which service type should be used?

A.ExternalName
B.ClusterIP
C.LoadBalancer
D.NodePort
AnswerD

NodePort is the simplest Service type that exposes an application to traffic from outside the cluster by opening a static port (default range 30000-32767) on every worker node's IP address. Traffic sent to any node's IP at that port is forwarded through the Service to the backing pod(s) selected by the Deployment, regardless of which node actually runs those pods. In the absence of a cloud-provider load balancer, NodePort works on any Kubernetes cluster and is precisely the mechanism that satisfies the developer's requirement to expose the web app externally.

Why this answer

(NodePort) is correct because it exposes a service on a static port on each node's IP address, allowing external traffic to reach the 'web-app' deployment on port 8080 without requiring a cloud load balancer. In on-premises clusters, NodePort is the standard service type for external access when no cloud LB is available, as it opens a high-port (30000-32767) on every node that forwards traffic to the ClusterIP service.

Exam trap

The trap here is that candidates may choose LoadBalancer (C) by default when they see 'expose to external traffic,' forgetting that LoadBalancer requires a cloud provider's external LB, which is not available in on-premises clusters.

How to eliminate wrong answers

Option A is wrong because ExternalName maps a service to an external DNS name (e.g., an external database) via CNAME records, not to expose internal pods to external traffic. Option B is wrong because ClusterIP exposes the service only on a cluster-internal IP, making it unreachable from outside the cluster without additional components like an ingress or proxy. Option C is wrong because LoadBalancer provisions an external load balancer (e.g., AWS ELB, GCP LB), which is unavailable in on-premises environments without a cloud provider integration.

14
MCQhard

A CronJob is configured with 'concurrencyPolicy: Forbid'. If a job from the previous schedule is still running when the next scheduled time arrives, what happens?

A.The CronJob is suspended
B.The new job starts immediately, and the old job is terminated
C.The new job is skipped until the old job completes
D.Both jobs run concurrently
AnswerC

With concurrencyPolicy: Forbid, the CronJob controller prevents overlapping executions by checking for any active Jobs from the same CronJob at each scheduled fire time. If one exists, the new run is not created—it is skipped entirely, and no subsequent catch-up occurs for that missed schedule. Once the active Job completes, the next regular schedule is processed normally, so the skip is permanent for that firing.

Why this answer

When `concurrencyPolicy: Forbid` is set on a CronJob, the CronJob controller will skip creating a new Job if the previous Job from the last schedule is still running. The new Job is effectively skipped (not queued) until the next scheduled time, preventing overlapping executions. This ensures that only one instance of the Job runs at a time.

Exam trap

The trap here is that candidates confuse 'skipped' with 'queued' or 'delayed' — the CronJob does not wait for the old Job to finish and then start the new one; it simply drops the missed run entirely, which is a key distinction tested in the CKAD exam.

How to eliminate wrong answers

Option A is wrong because the CronJob itself is not suspended; only the new Job creation is skipped. The CronJob continues to evaluate its schedule and will attempt to create Jobs at future intervals. Option B is wrong because the CronJob controller does not terminate the running Job; it simply does not start the new one.

Option D is wrong because `concurrencyPolicy: Forbid` explicitly prevents concurrent runs, so both Jobs cannot run simultaneously.

15
Multi-Selecthard

Which THREE of the following are valid fields in a CronJob specification?

Select 3 answers
A.completions
B.successfulJobsHistoryLimit
C.concurrencyPolicy
D.schedule
E.parallelism
AnswersB, C, D

`successfulJobsHistoryLimit` is a valid top-level field in a CronJob's `spec` that limits how many successful Job runs are retained after completion, with a default of 3. It works alongside `failedJobsHistoryLimit` to manage the cluster's storage footprint and keep `kubectl get cronjob` history list clean. This field is uniquely CronJob-level; it has no meaning inside a single Job.

Why this answer

In a CronJob specification, `successfulJobsHistoryLimit` is a valid field that controls how many completed jobs are retained in the cluster's history. This field defaults to 3 and helps manage resource usage by automatically cleaning up old Job records after the limit is exceeded.

Exam trap

In the CKAD exam, a common pitfall is confusing CronJob-level fields with Job template fields. Fields like completions and parallelism belong to the Job template (under jobTemplate.spec), not to the CronJob specification itself.

16
Multi-Selectmedium

Which TWO statements about init containers are true?

Select 2 answers
A.Init containers run to completion before any regular containers start.
B.Init containers run in parallel with regular containers.
C.Init containers run sequentially, one after another.
D.Init containers must use the same image as the main container.
E.Init containers cannot access volumes shared with regular containers.
AnswersA, C

Init containers are a distinct type of container in a Kubernetes pod that are started first, and each must run to completion (exit code 0) before any regular container in the pod is launched. The kubelet ensures that all init containers finish successfully before the main application containers are created, making them a gate for prerequisites. If an init container fails, it is restarted according to the pod's restartPolicy until it succeeds, and regular containers never start until that happens.

Why this answer

Init containers are designed to run to completion before any regular containers in the Pod start. This ensures that prerequisites (e.g., database schema migrations, configuration file generation, or waiting for a service to become available) are satisfied before the main application containers begin execution.

Exam trap

The trap here is that candidates often confuse init containers with sidecar containers, thinking they run in parallel with regular containers, but Kubernetes explicitly runs init containers sequentially and to completion before any regular containers start.

17
MCQmedium

A developer runs 'kubectl run mypod --image=nginx --restart=Never' and the pod is created. However, when the container exits, the pod terminates. Which restart policy ensures the pod does NOT restart after completion?

A.Always
B.OnFailure
C.AlwaysFail
D.Never
AnswerD

Never is the correct restart policy because it instructs the kubelet to not restart the container after it exits, regardless of the exit code. This allows the Pod to remain in the Succeeded phase if the container completed successfully, or Failed if it returned a non-zero exit code. For a one-off Pod like `mypod` that is intended to run to completion and stop, Never ensures the Pod does not restart, matching the developer's expectation.

Why this answer

The `--restart=Never` flag sets the pod's restart policy to `Never`, which means the kubelet will not restart the container when it exits. Since the pod was created with `kubectl run` and `--restart=Never`, it runs as a standalone pod (not managed by a controller), and when the container exits, the pod enters the `Succeeded` or `Failed` phase and is not restarted. This is the only restart policy that guarantees the pod does not restart after completion.

Exam trap

In the CKAD exam, the trap here is that candidates often confuse the `--restart` flag in `kubectl run` with the pod's restart policy, or mistakenly think `OnFailure` prevents all restarts, when in fact it only restarts on non-zero exit codes, and `Never` is the only policy that guarantees no restart after any completion.

How to eliminate wrong answers

Option A is wrong because `Always` is the default restart policy for pods created by controllers like Deployments; it would restart the container indefinitely even after successful completion, which is the opposite of what is desired. Option B is wrong because `OnFailure` restarts the container only if it exits with a non-zero exit code, but if the container exits successfully (exit code 0), it does not restart; however, the question asks for a policy that ensures the pod does NOT restart after completion, and `OnFailure` would still restart on failure, so it does not guarantee no restart in all cases. Option C is wrong because `AlwaysFail` is not a valid Kubernetes restart policy; the only valid restart policies are `Always`, `OnFailure`, and `Never`.

18
MCQmedium

You need to run a one-time batch job that processes 10 work items in parallel, with a maximum of 3 pods running at the same time. Which Job YAML fields should you set?

A.spec.template.spec.containers and spec.completions
B.spec.parallelism: 10 and spec.completions: 3
C.spec.parallelism: 3 and spec.completions: 10
D.spec.backoffLimit: 3 and spec.completions: 10
AnswerC

Correct: spec.parallelism: 3 and spec.completions: 10. Here, parallelism defines the maximum number of pods that may run simultaneously, limiting concurrency to 3. completions specifies that exactly 10 pods must successfully finish overall before the Job is considered complete. As pods complete, the Job controller creates new pods (up to the parallelism limit) until the completion count of 10 is reached, ensuring all 10 work items are processed with the intended degree of parallelism.

Why this answer

`spec.parallelism: 3` limits the maximum number of pods running concurrently, and `spec.completions: 10` ensures the Job runs 10 work items to completion. This combination processes all 10 items in parallel batches of 3, meeting the requirement of a one-time batch job with a maximum of 3 pods at a time.

Exam trap

The trap here is that candidates often confuse `spec.parallelism` with the total number of work items and `spec.completions` with the concurrency limit, leading them to swap the values (e.g., Option B).

How to eliminate wrong answers

Option A is wrong because `spec.template.spec.containers` defines the container image and command, but does not control parallelism or completion count; it is a required field but not sufficient for the given constraints. Option B is wrong because `spec.parallelism: 10` would allow up to 10 pods to run simultaneously, violating the maximum of 3 pods, and `spec.completions: 3` would only require 3 successful completions, not 10 work items. Option D is wrong because `spec.backoffLimit: 3` controls the number of retries before marking the Job as failed, not the parallelism or completion count; it does not address the parallel processing or total work items.

19
MCQmedium

You want to create a Deployment that runs 5 replicas of a web application. Which kubectl command should you use?

A.kubectl run webapp --image=nginx --replicas=5
B.kubectl create pod webapp --image=nginx --replicas=5
C.kubectl apply -f deployment.yaml
D.kubectl create deployment webapp --image=nginx --replicas=5
AnswerD

The correct imperative command is `kubectl create deployment webapp --image=nginx --replicas=5`. This creates a Deployment named webapp with the nginx container image and sets the desired replica count to 5. It is a fully supported current kubectl command that accepts `--replicas` to scale the Deployment at creation time, making it the most direct way to satisfy the requirement.

Why this answer

To create a Deployment with 5 replicas using a single imperative command, use `kubectl create deployment webapp --image=nginx --replicas=5`. This command directly creates a Deployment and sets the desired replicas. Option A (`kubectl run`) no longer creates a Deployment by default in current Kubernetes versions (1.18+); it creates a single Pod and does not support the `--replicas` flag.

Option B (`kubectl create pod`) does not exist and is incorrect. Option C (`kubectl apply -f deployment.yaml`) would also create a Deployment but requires an existing YAML file and is not a single imperative command.

Exam trap

The trap is that candidates might incorrectly believe `kubectl run` with `--replicas` creates a Deployment, as it did in earlier Kubernetes versions. In the CKAD exam environment (Kubernetes 1.31+), `kubectl run` only creates a Pod, and `kubectl create deployment` is the correct imperative command for creating a Deployment with replicas.

How to eliminate wrong answers

Option A is wrong because `kubectl run` does not support a `--replicas` flag; it creates a single Pod (or a Deployment in older versions, but the flag is not valid and would cause an error). Option B is wrong because `kubectl create pod` is not a valid command; Pods are created imperatively with `kubectl run` or declaratively via a manifest, and the `--replicas` flag does not apply to Pods (a Pod is a single instance). Option C is wrong because while `kubectl apply -f deployment.yaml` can create a Deployment, it requires a pre-existing YAML manifest file, which is not provided in the question; the question asks for a single kubectl command to create the Deployment, and this option assumes a file already exists.

20
MCQhard

You have a multi-stage Docker build. The first stage compiles a binary, and the second stage copies the binary from the first stage. What is the correct COPY syntax to copy a file named 'app' from the first stage named 'builder'?

A.COPY app /app/
B.COPY --from=builder app /app/
C.COPY --stage=builder app /app/
D.COPY source=builder app /app/
AnswerB

Using COPY --from=builder explicitly tells Docker to look in the builder stage's filesystem for the app directory and copy it into the current stage's /app. This flag is essential in multi-stage builds to transfer only the compiled artifact while leaving build tools behind. It precisely identifies the source stage by name, making the build reproducible and clear.

Why this answer

The `--from=builder` flag in the COPY instruction allows you to copy files from a specific build stage (named 'builder') in a multi-stage Docker build. This syntax is essential for multi-stage builds, where the first stage compiles artifacts and the second stage copies only the necessary binaries, reducing final image size.

Exam trap

The trap here is that candidates often confuse the `--from` flag with other Docker flags like `--stage` or `source=`, or mistakenly think a simple COPY from the build context will work, failing to recognize that multi-stage builds require explicit stage referencing to access files from previous stages.

How to eliminate wrong answers

Option A is wrong because it copies the file from the build context (the host filesystem), not from the 'builder' stage, which would fail if 'app' is only present in the intermediate stage. Option C is wrong because Docker's COPY instruction does not support a `--stage` flag; the correct flag is `--from`. Option D is wrong because `source=builder` is not a valid COPY syntax; Docker uses `--from=<name>` to reference a previous build stage.

21
MCQhard

A team is deploying a microservice that requires initialization of a database schema before the main application starts. The init container must run a script that writes to a shared volume. Which configuration correctly ensures the init container completes before the main container runs?

A.Run the script as a sidecar container that shares the volume with the main container.
B.Use a postStart lifecycle hook on the main container to run the script.
C.Define an init container with the script and mount the shared volume to both init and main containers.
D.Add a readiness probe to the main container that checks the shared volume.
AnswerC

Init containers always run to completion before any application container in the pod is started, and each init container must exit with status 0. By mounting the same volume in both the init container and the main container, the script can write required files that the main container reads immediately upon startup. This guarantees the initialization is fully completed before the microservice process begins.

Why this answer

An init container runs to completion before any main container in the Pod starts, ensuring the database schema script finishes. By mounting the shared volume to both the init container and the main container, the script's output (e.g., schema files) is available to the main application when it launches.

Exam trap

The trap here is that candidates confuse init containers with sidecar containers or lifecycle hooks, not realizing that only init containers guarantee sequential execution before main containers, while sidecars and hooks run concurrently or asynchronously.

How to eliminate wrong answers

Option A is wrong because a sidecar container runs concurrently with the main container, not before it, so the database schema might not be initialized when the main application starts. Option B is wrong because a postStart lifecycle hook runs asynchronously and does not block the main container's entrypoint; the main container could start before the script completes, leading to race conditions. Option D is wrong because a readiness probe only checks if the main container is ready to serve traffic after it has started; it does not guarantee that the schema initialization script has run before the main container begins execution.

22
MCQhard

A CronJob is configured with concurrencyPolicy: Forbid and schedule: '*/5 * * * *'. The first job takes 7 minutes. What happens when the next scheduled time arrives?

A.The previous job is terminated
B.The new job waits until the previous job completes
C.The new job is skipped
D.A new job is created immediately
AnswerC

With concurrencyPolicy set to Forbid, Kubernetes refuses to start a new job while the previous one is still running, so the 5-minute trigger is skipped. This satisfies the stem's constraint that the 7-minute job still occupies the schedule.

Why this answer

C is correct because when `concurrencyPolicy: Forbid` is set, the CronJob controller skips creating a new job if the previous job is still running at the next scheduled time. Since the first job takes 7 minutes and the schedule is every 5 minutes, the new job is skipped to prevent overlapping executions.

Exam trap

The trap here is that candidates often confuse `Forbid` with `Replace` (which terminates the running job) or assume the new job will queue, but Kubernetes explicitly skips the run without any retry or delay.

How to eliminate wrong answers

Option A is wrong because `concurrencyPolicy: Forbid` does not terminate the running job; it only prevents new jobs from starting. Option B is wrong because `Forbid` does not queue or delay the new job; it simply skips it. Option D is wrong because a new job is not created immediately; the controller checks the policy and skips creation if a job is still active.

23
MCQhard

A pod has an init container that fails. The status shows 'Init:CrashLoopBackOff'. The pod's restartPolicy is 'Always'. What happens to the init container?

A.The pod will be deleted and recreated
B.The main containers will start anyway
C.The init container will restart until it succeeds
D.The init container will not restart because the pod's restartPolicy is Always
AnswerC

According to Kubernetes semantics, init containers are always restarted on failure, regardless of the pod's restartPolicy — the restartPolicy only applies to the main (ephemeral) containers. The kubelet reruns the failed init container, applying an exponential backoff delay, until it exits successfully; only then does the pod proceed to start its regular containers.

Why this answer

Init containers always run to completion before any main containers start, and they are restarted until they succeed regardless of the pod's restartPolicy. The restartPolicy only applies to main containers, not init containers. When an init container fails, Kubernetes restarts it indefinitely until it exits with a zero status, which is why the status shows 'Init:CrashLoopBackOff'.

Exam trap

The trap here is that candidates mistakenly apply the pod's restartPolicy to init containers, not realizing that init containers always restart on failure regardless of the pod's restartPolicy setting.

How to eliminate wrong answers

Option A is wrong because the pod is not deleted and recreated; only the init container is restarted within the existing pod. Option B is wrong because main containers cannot start until all init containers have completed successfully; they are blocked by design. Option D is wrong because the restartPolicy of 'Always' applies only to main containers, not to init containers; init containers always restart on failure regardless of the pod's restartPolicy.

24
MCQmedium

You have a Dockerfile with a multi-stage build. The first stage is named 'builder' and uses 'golang:1.20' to compile a binary. The second stage uses 'alpine:3.18' and should copy the binary from the first stage. Which COPY instruction is correct?

A.ADD --from=builder /app/myapp /usr/local/bin/myapp
B.COPY /app/myapp /usr/local/bin/myapp
C.COPY --from=0 /app/myapp /usr/local/bin/myapp
D.COPY --from=builder /app/myapp /usr/local/bin/myapp
AnswerD

This is the canonical multi-stage build pattern: the final stage copies only the compiled artifact from the named builder stage, leaving build tools and intermediate files out of the runtime image. The flag --from=builder references the stage defined earlier in the Dockerfile, and the destination /usr/local/bin/myapp makes the binary available on PATH. This minimizes image size and attacksurface, which is the main reason multi-stage builds are recommended.

Why this answer

In a multi-stage Docker build, the `COPY --from=<name|index>` instruction copies files from a named previous stage. Option D correctly uses the stage name 'builder' to copy the compiled binary from the first stage into the final Alpine image. This is the standard and most readable approach for multi-stage builds.

Exam trap

The exam often tests the distinction between `COPY` and `ADD` in multi-stage builds, and the trap here is that candidates may incorrectly use `ADD --from` (which is invalid) or forget the `--from` flag entirely, thinking `COPY` defaults to copying from a previous stage.

How to eliminate wrong answers

Option A is wrong because `ADD` is not the correct instruction for copying between stages; `ADD` is used for adding files from the build context or URLs, and it does not support the `--from` flag for multi-stage builds. Option B is wrong because it omits the `--from` flag entirely, which means it will try to copy from the build context (the local filesystem) rather than from the 'builder' stage, and the binary does not exist there. Option C is wrong because while `COPY --from=0` would technically work (referencing the first stage by index), it is fragile and less readable than using the named stage 'builder'; the question explicitly names the stage 'builder', so using the index is not the correct approach.

25
MCQmedium

A developer wants to debug a running container in a Pod named 'web-app' in namespace 'dev'. Which command attaches an ephemeral container with the 'nicolaka/netshoot' image for network debugging?

A.kubectl debug web-app -n dev --image=nicolaka/netshoot -c debugger
B.kubectl run debugger -n dev --image=nicolaka/netshoot --restart=Never
C.kubectl attach web-app -n dev -c debugger --image=nicolaka/netshoot
D.kubectl exec -n dev web-app --image=nicolaka/netshoot -- /bin/bash
AnswerA

kubectl debug injects an ephemeral container named debugger directly into the existing web-app pod using the nicolaka/netshoot image. Ephemeral containers share the pod’s network, IPC, and PID namespaces with the application container, allowing you to inspect its interfaces, sockets, and processes without modifying or restarting the original workload. This is the intended mechanism for bringing a debugging image into a running pod for interactive troubleshooting.

Why this answer

`kubectl debug` is the dedicated command for adding an ephemeral container to a running Pod for troubleshooting. The `--image=nicolaka/netshoot` flag specifies the network debugging image, and `-c debugger` names the ephemeral container. This allows the developer to attach to the Pod's network namespace without restarting or modifying the original container.

Exam trap

Kubernetes often tests the distinction between `kubectl debug` (for ephemeral containers) and `kubectl exec` (for existing containers), trapping candidates who think `exec` can add a new container with a different image.

How to eliminate wrong answers

Option B is wrong because `kubectl run` creates a standalone Pod, not an ephemeral container attached to an existing Pod; it does not share the network namespace of 'web-app'. Option C is wrong because `kubectl attach` attaches to a running container's stdio, not to a new container, and it does not support the `--image` flag. Option D is wrong because `kubectl exec` runs a command in an existing container, not a new container with a different image; the `--image` flag is invalid for `kubectl exec`.

26
MCQhard

A multi-stage build has two stages named 'builder' and 'final'. Which instruction copies artifacts from the builder stage to the final stage?

A.COPY --from=builder /app /app
B.FROM builder /app /app
C.COPY builder /app /app
D.ADD --from=builder /app /app
AnswerA

This is the correct syntax for copying artifacts from a previous stage in a multi-stage Docker build. The `--from=builder` flag specifies the named stage called `builder`, and both `/app` arguments are container filesystem paths: the source path inside the builder stage's filesystem and the destination path in the current build stage. Because the `COPY` instruction requires this exact format to reference another stage, this command successfully copies the application from the builder stage into the final image.

Why this answer

In a multi-stage Docker build, the COPY instruction with the --from flag allows you to copy files from a named previous stage (here 'builder') into the current stage ('final'). This is the correct syntax to selectively transfer build artifacts without carrying over intermediate layers or dependencies.

Exam trap

The trap here is that candidates confuse the COPY --from syntax with the ADD instruction or forget the --from flag entirely, assuming COPY alone can reference a stage name, which leads to a build error or unintended host path copy.

How to eliminate wrong answers

Option B is wrong because 'FROM builder /app /app' is not a valid Dockerfile instruction; FROM is used to specify a base image, not to copy files. Option C is wrong because 'COPY builder /app /app' omits the required --from flag, so Docker would interpret 'builder' as a source path on the host filesystem, not as a stage name. Option D is wrong because ADD does not support the --from flag; ADD is used for adding files from URLs or archives, and multi-stage artifact copying is exclusive to COPY --from.

27
MCQmedium

A pod is stuck in 'Pending' state. You run 'kubectl describe pod mypod' and see the event: '0/4 nodes are available: 4 Insufficient memory'. Which action will resolve the issue?

A.Scale down other pods in the cluster to free memory
B.Add a nodeSelector to target a specific node
C.Increase the memory request in the pod spec
D.Scale up the Deployment to create more pod replicas
AnswerA

When a pod is Pending, one common cause is that no node has enough allocatable memory because the sum of memory requests from pods already assigned to each node is at or near the node's capacity. Scaling down other pods (for example, reducing Deployment replicas) lowers the total requested memory on those nodes, freeing enough headroom for the scheduler to place the pending pod. This directly addresses the scheduling failure, though it may require coordination with other workloads.

Why this answer

The pod is stuck in 'Pending' because no node has enough allocatable memory to satisfy its memory request. Scaling down other pods frees memory on existing nodes, allowing the scheduler to place the pod. This directly resolves the 'Insufficient memory' condition without changing the pod's specification or cluster topology.

Exam trap

The trap here is that candidates often think increasing resource requests or adding selectors will help, but those actions either increase demand or restrict placement, making the problem worse instead of solving the underlying resource shortage.

How to eliminate wrong answers

Option B is wrong because adding a nodeSelector restricts scheduling to nodes matching specific labels, but no node currently has sufficient memory, so the pod will remain unschedulable. Option C is wrong because increasing the memory request would make the pod require even more memory, worsening the shortage and keeping it pending. Option D is wrong because scaling up the Deployment creates more pod replicas, each with the same memory request, increasing total demand and making the memory shortage worse.

28
Drag & Dropmedium

Arrange the steps to create a Kubernetes Deployment with a rolling update strategy.

Drag or tap steps into the slots.

Steps
Order
1Step 1
2Step 2
3Step 3
4Step 4

Why this order

First, define the Deployment in YAML. Then apply it. After an update, modify the YAML and re-apply; kubectl performs rolling update automatically.

29
MCQmedium

Which command attaches an ephemeral container to a running pod for debugging?

A.kubectl attach mypod
B.kubectl exec -it mypod -- sh
C.kubectl logs mypod -c mycontainer
D.kubectl debug -it mypod --image=busybox --target=mycontainer
AnswerD

kubectl debug -it mypod --image=busybox --target=mycontainer creates a new ephemeral container in the pod, attaches it interactively, and joins it to the process namespace of the target container mycontainer. The --target flag makes the ephemeral container see the same processes as mycontainer, enabling low-level debugging with tools like strace or tcpdump. The -it flags allocate a TTY and keep stdin open, while --image=busybox provides the debugging environment, all without restarting the pod.

Why this answer

`kubectl debug` with `-it` and `--image=busybox` creates an ephemeral container in the target pod for interactive debugging, while `--target=mycontainer` attaches the ephemeral container to the same network and process namespace as the specified container. This is the only command that adds a new, temporary container to a running pod without restarting it, which is essential when the existing container lacks debugging tools or is in a crash loop.

Exam trap

The trap here is that candidates confuse `kubectl exec` (which runs in an existing container) with `kubectl debug` (which creates a new ephemeral container), especially when the pod's container is unhealthy or lacks a shell, making `kubectl exec` impossible.

How to eliminate wrong answers

Option A is wrong because `kubectl attach mypod` attaches to the primary container's main process (usually PID 1) in the pod, not an ephemeral container; it does not create a new container and requires the container to have an interactive shell running. Option B is wrong because `kubectl exec -it mypod -- sh` runs a command in an existing container, not an ephemeral container; it fails if the container has no shell or is in a broken state. Option C is wrong because `kubectl logs mypod -c mycontainer` only retrieves log output from a specified container; it does not attach or create any container for debugging.

30
MCQmedium

A Job must run 10 times in total, with up to 3 pods running simultaneously. Which fields should be set?

A.completions: 10, parallelism: 3
B.completions: 10, successfulJobsHistoryLimit: 3
C.completions: 10, parallelism: 10
D.completions: 3, parallelism: 10
AnswerA

This configuration sets the desired Job state: completions: 10 tells the Kubernetes Job controller that it must manage exactly 10 successful pod completions before the Job is marked complete, while parallelism: 3 caps the number of Pods that can run simultaneously. The controller will create Pods in batches, never exceeding the parallelism limit, until the total number of completed Pods reaches 10. This precisely matches the requirement of 10 total runs with at most 3 pods running at any given time.

Why this answer

In a Kubernetes Job, `completions: 10` specifies the total number of successful Pod completions required, and `parallelism: 3` limits the number of Pods that can run concurrently. This ensures the Job runs exactly 10 times with up to 3 Pods in parallel, which matches the requirement.

Exam trap

In CKAD, candidates often confuse `parallelism` (concurrent Pods) with `successfulJobsHistoryLimit` (history retention) or `completions` (total Pod completions). Remember that `parallelism` controls how many Pods run at once, not the total count.

How to eliminate wrong answers

Option B is wrong because `successfulJobsHistoryLimit` controls how many completed Job records are retained in the cluster history, not the number of concurrent Pods; it does not affect parallelism. Option C is wrong because `parallelism: 10` would allow up to 10 Pods to run simultaneously, exceeding the required limit of 3. Option D is wrong because `completions: 3` would only run the Job 3 times total, not 10, and `parallelism: 10` would allow up to 10 concurrent Pods, violating both requirements.

31
MCQhard

You have a multi-stage Dockerfile with two stages: 'builder' and 'runtime'. You want to copy artifacts from the builder stage to the runtime stage. Which Dockerfile instruction achieves this?

A.EXPORT builder /app/artifact /app/
B.ADD --from=builder /app/artifact /app/
C.COPY ../builder/artifact /app/
D.COPY --from=builder /app/artifact /app/
AnswerD

This is the correct way to copy an artifact from a previous build stage. The --from=builder flag tells Docker to treat the source path /app/artifact as being in the filesystem of the stage named builder, rather than in the build context. This copies the compiled artifact into the current stage's /app/ directory, enabling a clean separation between the build environment and the final runtime image. The COPY instruction is specifically designed to support this cross-stage file transfer.

Why this answer

The COPY instruction with --from=stage-name copies files from a previous build stage.

32
MCQhard

You are designing a Pod that must run a diagnostic tool to collect network logs before the main application starts. The diagnostic tool should run to completion, then the main application starts. Which approach should you use?

A.Add the diagnostic tool as an init container in the Pod
B.Add the diagnostic tool as a sidecar container in the same Pod
C.Add the diagnostic tool as a sidecar container with a postStart hook
D.Create a separate Job that runs before the Pod
AnswerA

An init container is the correct choice because Kubernetes runs init containers to completion, in order, before any regular app container is started. This guarantees the diagnostic tool finishes its checks first, and if it exits with a non-zero status, the app container will not be created. The diagnostic is thus an explicit, blocking prerequisite within the same Pod.

Why this answer

Init containers run sequentially before the Pod's main containers start, and they must complete successfully before the main application container begins. This makes them ideal for setup tasks like running a diagnostic tool to collect network logs that must finish before the main application starts.

Exam trap

The trap here is that candidates confuse init containers with sidecar containers or lifecycle hooks, assuming any container that runs before the main application can be a sidecar, but only init containers guarantee sequential execution to completion before the main container starts.

How to eliminate wrong answers

Option B is wrong because a sidecar container runs concurrently with the main container, not before it, so the diagnostic tool would not complete before the main application starts. Option C is wrong because a postStart hook runs inside the main container's lifecycle after the container starts, but it does not block the main application from starting; the hook runs asynchronously, so the main application could begin before the diagnostic tool finishes. Option D is wrong because creating a separate Job introduces unnecessary complexity and does not guarantee the Job completes before the Pod starts; the Pod could be scheduled and run before the Job finishes, and there is no built-in dependency mechanism between a Job and a Pod.

33
Multi-Selectmedium

Which TWO of the following are valid fields in a CronJob spec? (Select 2)

Select 2 answers
A.restartPolicy
B.concurrencyPolicy
C.completions
D.schedule
E.parallelism
AnswersB, D

concurrencyPolicy is a legitimate CronJob.spec field that controls how the controller handles Jobs that should be created while another Job from the same CronJob is still active. It accepts Allow, Forbid, or Replace; Allow starts a new Job immediately, Forbid skips the new run until the next schedule, and Replace cancels the active Job before starting a new one. This is a top-level scheduling-policy field, not something inherited from the Pod or Job template.

Why this answer

B is correct because `concurrencyPolicy` is a valid field in a CronJob spec that controls how concurrent executions of the job are handled. It can be set to `Allow`, `Forbid`, or `Replace`, which determines whether a new job can start while a previous one is still running.

Exam trap

CNCF often tests the distinction between CronJob spec fields and Job spec fields, trapping candidates who confuse `completions` and `parallelism` (Job-level) with CronJob-level fields like `schedule` and `concurrencyPolicy`.

34
MCQhard

A Kubernetes Job with parallelism=3 and completions=6 is created. How many pods will run concurrently at most?

A.3
B.9
C.6
D.1
AnswerA

In Kubernetes Jobs, the 'parallelism' field specifies the maximum number of Pods that may run concurrently. Here it is explicitly set to 3, so at most three Pods will be active at any given time, regardless of how many have completed. Completions only sets the total number of successful Pods required (6), not the concurrency limit.

Why this answer

The `parallelism` field in a Kubernetes Job specifies the maximum number of pods that can run concurrently. With `parallelism=3`, at most 3 pods will run at the same time, regardless of the total number of completions required.

Exam trap

The trap here is confusing `parallelism` (max concurrent pods) with `completions` (total successful pods needed), leading candidates to multiply or add the two values incorrectly.

How to eliminate wrong answers

Option B is wrong because 9 would be the product of parallelism and completions, but Kubernetes does not multiply these values; parallelism caps concurrent pods, not total pods. Option C is wrong because completions=6 sets the total number of successful pod completions needed, not the concurrency limit. Option D is wrong because 1 would be the default parallelism if not set, but here parallelism is explicitly set to 3.

35
MCQmedium

You need to run a batch job that processes 10 items in parallel across 10 Pods, but the job should be considered complete only when all 10 Pods have succeeded. Which Job configuration is correct?

A.spec: completions: 10; parallelism: 1
B.spec: completions: 1; parallelism: 10
C.spec: completions: 10; parallelism: 10
D.spec: completions: 10; parallelism: 0
AnswerC

This is the correct specification because completions 10 and parallelism 10 work together to meet the requirement: the Job controller launches up to 10 Pods concurrently (parallelism), and the Job is considered successful only after 10 distinct Pods complete successfully (completions). Each Pod can handle one of the 10 items, all run in parallel, and the Job waits until every one has finished. The combination precisely matches the stated batch workload.

Why this answer

Setting `completions: 10` and `parallelism: 10` tells Kubernetes to run 10 Pods concurrently (parallelism) and consider the Job successful only after all 10 Pods have completed without error (completions). This matches the requirement of processing 10 items in parallel with a completion condition of all Pods succeeding.

Exam trap

The trap here is confusing `completions` (total successes required) with `parallelism` (concurrent Pods), leading candidates to pick Option B, which runs 10 Pods in parallel but only waits for one to succeed, missing the requirement that all 10 must succeed.

How to eliminate wrong answers

Option A is wrong because `completions: 10; parallelism: 1` runs Pods sequentially (one at a time), not in parallel, so items are processed one after another, not concurrently. Option B is wrong because `completions: 1; parallelism: 10` runs 10 Pods in parallel but the Job is considered complete after only one Pod succeeds, ignoring the other 9 items. Option D is wrong because `parallelism: 0` is invalid; Kubernetes requires parallelism to be a positive integer (or unset, defaulting to 1), and setting it to 0 would cause the Job to never start any Pods.

36
MCQmedium

A developer wants to create a Job that runs exactly 3 pods in parallel. Which field should be set in the Job spec?

A.spec.ttlSecondsAfterFinished: 3
B.spec.backoffLimit: 3
C.spec.parallelism: 3
D.spec.completions: 3
AnswerC

Setting spec.parallelism: 3 tells the Job controller to run up to three Pods concurrently, meaning the Job will schedule three Pods at the same time rather than a single Pod. This field directly controls the degree of parallelism; for a fixed-completion Job, the controller keeps parallelism Pods active until the desired completions count is reached. To achieve exactly three Pods running in parallel, parallelism is the correct knob to use.

Why this answer

`spec.parallelism` in a Kubernetes Job spec defines the desired number of Pods that should run concurrently. Setting `spec.parallelism: 3` tells the Job controller to run exactly 3 Pods in parallel, meeting the requirement of running 3 pods simultaneously.

Exam trap

The trap here is confusing `spec.parallelism` with `spec.completions` — candidates often think completions controls concurrency, but it actually defines the total number of successful completions needed, not how many run at once.

How to eliminate wrong answers

Option A is wrong because `spec.ttlSecondsAfterFinished` controls how long a completed Job is retained before automatic cleanup, not the number of parallel pods. Option B is wrong because `spec.backoffLimit` sets the number of retries for a failed Pod before marking the Job as failed, not parallelism. Option D is wrong because `spec.completions` defines the total number of successful Pod completions required for the Job to be considered complete, not the number of pods running in parallel.

37
MCQhard

You have a Job that should retry up to 3 times if it fails, and should be considered failed after 4 failures total (including retries). Which YAML fields should you set?

A.spec.activeDeadlineSeconds: 4
B.spec.backoffLimit: 4
C.spec.restartPolicy: OnFailure and spec.backoffLimit: 3
D.spec.backoffLimit: 3
AnswerD

spec.backoffLimit: 3 is the correct field because it directly defines how many times the Job controller will re-create a pod after it fails. The initial pod run counts as the first attempt, and each subsequent re-creation is a retry, so with backoffLimit set to 3, there are exactly 3 retries and a total of 4 attempts. This precisely matches the requirement and is the standard approach for controlling retry attempts in a Kubernetes Job.

Why this answer

The `spec.backoffLimit` field in a Kubernetes Job defines the number of retries before considering the Job as failed. Setting it to 3 means the Job will retry up to 3 times after the initial failure, resulting in a total of 4 failures (1 initial + 3 retries), which matches the requirement.

Exam trap

The trap here is that candidates often confuse `spec.backoffLimit` with the total number of allowed failures. In Kubernetes Jobs, `spec.backoffLimit` sets the number of retries after an initial failure, so to allow 4 total failures (initial + up to 3 retries), the value must be 3, not 4.

How to eliminate wrong answers

Option A is wrong because `spec.activeDeadlineSeconds` sets a hard time limit for the Job's execution, not a retry count; it would terminate the Job after 4 seconds regardless of retries. Option B is wrong because setting `spec.backoffLimit: 4` would allow 4 retries, leading to a total of 5 failures (1 initial + 4 retries), exceeding the required 4 failures. Option C is wrong because `spec.restartPolicy: OnFailure` is not a valid field for a Job (Jobs use `spec.template.spec.restartPolicy` and only support `Never` or `OnFailure`), and even if corrected, `spec.backoffLimit: 3` alone is sufficient without needing to set `restartPolicy` explicitly.

38
MCQhard

A Job has the following spec: apiVersion: batch/v1 kind: Job metadata: name: pi spec: template: spec: containers: - name: pi image: perl command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"] restartPolicy: Never backoffLimit: 4 If the pod fails, how many times will Kubernetes retry the job before considering it failed?

A.4
B.1
C.0
D.5
AnswerA

In a Kubernetes Job, backoffLimit defines the number of retries before the Job is considered failed. The backoffLimit field is set to 4, meaning the controller can retry the Pod up to 4 times after a failure. After those 4 retries are exhausted, the Job transitions to the Failed condition. Thus, the correct number of retries is exactly 4.

Why this answer

The `backoffLimit` field in a Job spec specifies the number of retries before the Job is considered failed. In this YAML, `backoffLimit: 4` means Kubernetes will retry the Job up to 4 times after the initial failure, for a total of 5 attempts (1 initial + 4 retries). The question asks 'how many times will Kubernetes retry the job before considering it failed?', which directly corresponds to the `backoffLimit` value of 4.

Exam trap

The trap here is that candidates often confuse the `backoffLimit` value with the total number of attempts (including the initial one), leading them to pick 5 instead of 4, but the question specifically asks for the number of retries, not total attempts.

How to eliminate wrong answers

Option B is wrong because it suggests only 1 retry, but the `backoffLimit` is explicitly set to 4, not 1. Option C is wrong because it suggests 0 retries, which would only be the case if `backoffLimit` were set to 0 or omitted (default is 6), but here it is 4. Option D is wrong because it suggests 5 retries, which is a common misinterpretation: the total number of attempts (initial + retries) is 5, but the number of retries is 4, as defined by `backoffLimit`.

39
MCQeasy

Which of the following commands creates a deployment named 'webapp' that runs the image 'nginx:1.25' with 3 replicas?

A.kubectl create deployment webapp --image=nginx:1.25 --replicas=3
B.kubectl run webapp --image=nginx:1.25 --replicas=3
C.kubectl create deployment webapp --image=nginx:1.25
D.kubectl expose deployment webapp --port=80
AnswerA

kubectl create deployment webapp --image=nginx:1.25 --replicas=3 is the canonical imperative command that generates a Deployment named 'webapp' with the specified container image and desired replica count. The --replicas flag is explicitly supported by kubectl create deployment, and the resulting Deployment object will manage three Pod replicas using the nginx:1.25 image. This fully satisfies the requirement to create a Deployment with those parameters.

Why this answer

The correct command to create a Deployment named 'webapp' with the nginx:1.25 image and 3 replicas is 'kubectl create deployment webapp --image=nginx:1.25 --replicas=3'. Option B uses 'kubectl run', which creates a Pod, not a Deployment, and does not support the --replicas flag in modern Kubernetes. Option C is missing the --replicas flag, so it creates a Deployment with only the default of 1 replica.

Option D uses 'kubectl expose', which creates a Service, not a Deployment.

Exam trap

The temptation is to choose an option that looks similar to the correct one, but pay close attention to the missing flags and the command verb.

How to eliminate wrong answers

Option A is wrong because `kubectl create deployment` does not support a `--replicas` flag; the correct flag is `--replicas` (note the spelling difference), and even with the correct flag, the command syntax is identical to D but the option is listed as incorrect due to the trap. Option B is wrong because `kubectl run` creates a Pod, not a Deployment; it does not support `--replicas` or `--port` flags in the same way, and using those flags would either be ignored or cause an error. Option C is wrong because it is a duplicate of the correct command but is marked as incorrect in the question's answer options; the question explicitly labels D as correct, so C is considered a distractor.

40
MCQhard

A CronJob is configured with concurrencyPolicy: Replace and a job execution takes 10 minutes. The schedule is */5 * * * *. Which statement is true about job executions?

A.Jobs will never overlap because the schedule is too frequent
B.Every 5 minutes, a new job is created, and if the previous job is still running, it is killed
C.The job will be skipped if the previous one hasn't finished
D.Jobs will overlap, with up to two jobs running concurrently
AnswerB

This is exactly what concurrencyPolicy: Replace does. When the CronJob controller fires a new schedule, it checks whether the Job from the previous invocation is still active; if so, it deletes that existing Job (terminating its Pods) and creates a fresh Job for the current run. This ensures the schedule is always honored and only one Job's worth of work executes at a time.

Why this answer

With `concurrencyPolicy: Replace`, if a new job is triggered by the schedule (every 5 minutes) while the previous job is still running (it takes 10 minutes), the running job is terminated and replaced by the new one. This ensures only one job runs at a time, and the new job starts immediately, even if the previous one hasn't finished.

Exam trap

The trap here is that candidates confuse 'Replace' with 'Forbid' or 'Allow', and mistakenly think the job is skipped or that overlap is allowed, when in fact 'Replace' actively terminates the running job to start a new one.

How to eliminate wrong answers

Option A is wrong because the schedule is every 5 minutes, but the job takes 10 minutes, so jobs would overlap if not for the concurrency policy; the statement 'too frequent' is irrelevant as the policy explicitly handles overlap. Option C is wrong because 'Replace' does not skip jobs; it kills the running job and starts the new one, unlike 'Forbid' which would skip. Option D is wrong because 'Replace' prevents overlapping by terminating the existing job, so up to two jobs never run concurrently.

41
MCQmedium

You have a multi-container pod with a main container and a sidecar container that collects logs. The sidecar container should start before the main container and must complete initialization tasks before the main container starts. Which type of container should you use for this purpose?

A.Ephemeral container
B.Init container
C.Job
D.Regular sidecar container
AnswerB

Init containers are special containers that run to completion sequentially before any regular containers in the pod start. Each init container must finish successfully before the next one begins, and the main container is only started after all init containers have succeeded. This makes them the correct choice for initialization tasks such as setting up volumes, waiting for dependencies, or performing migrations. If an init container fails, it is retried according to the pod's restartPolicy, ensuring the main container never starts prematurely.

Why this answer

Init containers run to completion before any regular containers in the pod start, making them ideal for prerequisites like initialization tasks or log setup. In this scenario, the sidecar must complete its initialization before the main container begins, which is exactly the behavior of an init container. Regular sidecar containers run concurrently with the main container, not before it.

Exam trap

Init containers are a key concept in CKAD. Candidates often mistakenly think a regular sidecar container can be configured to start before the main container, but Kubernetes does not support ordering among regular containers in a pod. Only init containers guarantee completion before other containers start.

How to eliminate wrong answers

Option A is wrong because ephemeral containers are temporary containers injected into a running pod for debugging purposes, not for initialization tasks. Option C is wrong because a Job is a standalone Kubernetes resource that runs a task to completion, not a container type within a pod, and cannot enforce ordering relative to other containers in the same pod. Option D is wrong because a regular sidecar container runs concurrently with the main container and does not guarantee completion before the main container starts.

42
MCQeasy

Which of the following is NOT a valid restart policy for a Pod?

A.OnFailure
B.Always
C.Never
D.UnlessStopped
AnswerD

UnlessStopped is not a recognized value for the restartPolicy field in Kubernetes; the only valid values are Always, OnFailure, and Never. It might sound familiar from Docker's own restart policies, but Kubernetes deliberately does not implement it. Attempting to use UnlessStopped in a Pod manifest will cause the API server to reject the definition with an invalid value error.

Why this answer

Kubernetes supports exactly three restart policies for Pods: Always, OnFailure, and Never. 'UnlessStopped' is not a valid restart policy in the Kubernetes API; it is a fabricated option designed to test your knowledge of the allowed values for the `restartPolicy` field in a Pod spec.

Exam trap

The trap here is that candidates may confuse Kubernetes restart policies with Docker's restart policies (which include 'unless-stopped'), assuming they are identical, but Kubernetes only supports the three explicit policies defined in the PodSpec.

How to eliminate wrong answers

Option A is wrong because 'OnFailure' is a valid restart policy that restarts the container only when the container exits with a non-zero exit code. Option B is wrong because 'Always' is the default restart policy and is valid; it automatically restarts the container regardless of the exit code. Option C is wrong because 'Never' is a valid restart policy that never restarts the container after it exits.

43
MCQhard

You need to debug a pod that has no running container because it crashed. The pod is in CrashLoopBackOff. Which command allows you to start a temporary container in the same pod for debugging?

A.kubectl debug <pod> -it --image=busybox
B.kubectl attach <pod>
C.kubectl run debug --image=busybox
D.kubectl exec -it <pod> -- /bin/bash
AnswerA

kubectl debug with an explicit image creates an ephemeral container that is injected directly into the existing Pod, even when its primary container is not running. This ephemeral container shares the Pod’s network, storage, and optionally its process namespace, letting you inspect crashed processes or mounted volumes from inside the Pod context. The interactive -it session gives you a shell without ever needing the original container to be alive, which is precisely why it succeeds where exec, attach, or a separate run would fail.

Why this answer

`kubectl debug` can create an ephemeral container in an existing pod for debugging purposes, even when the original container is in CrashLoopBackOff. The `-it` flag provides an interactive terminal, and `--image=busybox` supplies a lightweight debugging image. This allows you to inspect the pod's filesystem, network, or environment without restarting the failing container.

Exam trap

The trap here is that candidates assume `kubectl exec` can debug any pod, but it requires a running container, whereas `kubectl debug` is the correct tool for pods in CrashLoopBackOff.

How to eliminate wrong answers

Option B is wrong because `kubectl attach` connects to a running container's stdin/stdout/stderr; it cannot start a new container or debug a crashed pod. Option C is wrong because `kubectl run debug --image=busybox` creates a separate, standalone pod, not a temporary container inside the existing pod, so it cannot share the same network namespace or volumes. Option D is wrong because `kubectl exec` requires a running container to execute commands against; it fails when the container is in CrashLoopBackOff.

44
MCQeasy

Which Dockerfile instruction is used to specify the base image for a build?

A.COPY
B.RUN
C.FROM
D.CMD
AnswerC

FROM declares the base image that subsequent build stages start from, pulling it from a registry or referencing a prior build stage. It must be the first instruction in a stage, establishing the filesystem and environment on which RUN, COPY, and other instructions operate.

Why this answer

The FROM instruction initializes a new build stage and sets the base image for subsequent instructions. In Docker, every Dockerfile must start with a FROM (or ARG before FROM) to specify an existing image, such as `FROM ubuntu:22.04` or `FROM alpine:3.18`, from which the new image is built. Without FROM, the build has no foundation and will fail.

Exam trap

A common trap in the Dockerfile section of the CKAD exam is confusing build-time instructions (FROM, RUN, COPY) with runtime instructions (CMD, ENTRYPOINT). Candidates often select CMD (which sets the default command) instead of FROM, which is required to specify the base image.

How to eliminate wrong answers

Option A is wrong because COPY is used to copy files or directories from the build context into the container filesystem, not to specify the base image. Option B is wrong because RUN executes commands in a new layer on top of the current image during the build, such as installing packages, and does not define the base image. Option D is wrong because CMD provides default arguments for the container's entrypoint at runtime, not the base image for the build.

45
MCQmedium

Which of the following is true about the CMD instruction in a Dockerfile?

A.CMD is always executed during the image build process
B.CMD is used to expose ports
C.CMD cannot be used in conjunction with ENTRYPOINT
D.CMD provides a default command that can be overridden at runtime
AnswerD

This is correct. CMD defines the default command and parameters that run when the container starts, but it is intentionally overridable. For example, docker run image <command> replaces the CMD entirely. This flexibility makes CMD useful for providing sensible defaults while allowing users to supply their own command.

Why this answer

The CMD instruction in a Dockerfile provides default arguments for the container's main process, which can be overridden when the container is started with a command-line argument (e.g., `docker run <image> <command>`). It is not executed during the image build (that's RUN), it does not expose ports (that's EXPOSE), and it can be used with ENTRYPOINT to supply default parameters that are overridable.

Exam trap

The trap here is that candidates often confuse CMD with RUN, thinking CMD runs during build, or mistakenly believe CMD and ENTRYPOINT are mutually exclusive, when in fact they are designed to work together.

How to eliminate wrong answers

Option A is wrong because CMD is not executed during the image build process; it only defines the default command for the container at runtime, while RUN executes commands during the build. Option B is wrong because exposing ports is done with the EXPOSE instruction, not CMD. Option C is wrong because CMD can be used in conjunction with ENTRYPOINT; when both are present, CMD provides default arguments to the ENTRYPOINT executable, which can be overridden at runtime.

46
Multi-Selecthard

Which THREE are valid reasons to use a StatefulSet instead of a Deployment?

Select 3 answers
A.The application requires rolling updates.
B.Each pod requires a stable, unique network identity.
C.Each pod needs its own persistent volume that persists across rescheduling.
D.The application cannot be scaled down.
E.Pods must be terminated in reverse order during shutdown.
AnswersB, C, E

StatefulSet pods are assigned a stable, unique network identity based on their ordinal index (e.g., my-statefulset-0, my-statefulset-1). This hostname remains consistent across pod rescheduling, and when paired with a headless Service, each pod has a stable DNS name that other components can rely on. Deployments, by contrast, create pods with random suffixes and no guarantee of stable hostnames.

Why this answer

StatefulSet assigns each pod a stable, unique network identity (e.g., a hostname like `web-0`, `web-1`) via a headless Service, which is critical for stateful applications like databases that rely on consistent DNS names for clustering and discovery. Deployments create pods with random, ephemeral hostnames, making them unsuitable for workloads requiring predictable network identities.

Exam trap

CNCF often tests the misconception that only StatefulSets support rolling updates, but both controllers do; the trap is confusing a shared feature with a unique StatefulSet capability.

47
MCQhard

You have a CronJob that runs every 5 minutes. The job sometimes takes longer than 5 minutes to complete. You want to ensure that while a job is running, the next scheduled job is skipped (not started). Which concurrencyPolicy should you use?

A.Forbid
B.Skip
C.Allow
D.Replace
AnswerA

Forbid is the correct concurrencyPolicy for a CronJob that must not overlap runs. When set, the controller skips the next scheduled invocation if a previous Job created by this CronJob is still active (i.e., has not completed successfully or failed). This guarantees serial execution, which is critical for jobs that mutate shared state or cannot safely run in parallel.

Why this answer

The `Forbid` concurrencyPolicy ensures that if a previous job instance is still running when the next scheduled time arrives, the new job is simply skipped (not created). This prevents overlapping executions, which is exactly what you need when a CronJob's duration can exceed its schedule interval.

Exam trap

The trap here is that candidates confuse the 'Skip' option (which is not a valid Kubernetes value) with the correct 'Forbid' policy, or they mistakenly think 'Replace' will skip the next job instead of killing the current one.

How to eliminate wrong answers

Option B (Skip) is wrong because 'Skip' is not a valid concurrencyPolicy value in Kubernetes; the correct term is 'Forbid'. Option C (Allow) is wrong because it permits multiple job instances to run concurrently, which would allow overlapping executions even if the previous job hasn't finished. Option D (Replace) is wrong because it would cancel the currently running job and start a new one, which is not the same as skipping the next scheduled run.

48
MCQhard

You run 'kubectl apply -f pod.yaml' but the pod remains in 'Pending' state. 'kubectl describe pod' shows '0/1 nodes are available: 1 Insufficient cpu'. What is the most likely cause?

A.The pod's memory limit is too low
B.The container image is not found in the registry
C.The node is under disk pressure
D.The pod's CPU request exceeds the available CPU capacity on any node
AnswerD

The exact scheduler event 'Insufficient cpu' means no node in the cluster satisfies the pod's CPU request after accounting for the allocatable CPU and existing pod requests. The pod remains Pending because the scheduler cannot find a feasible node, and it does not even attempt to bind the pod. This is the correct interpretation because the message directly indicates a lack of available CPU capacity, not memory, disk, or image issues.

Why this answer

The error '0/1 nodes are available: 1 Insufficient cpu' indicates that the pod's CPU request (specified in the container spec under `resources.requests.cpu`) exceeds the allocatable CPU capacity on any node in the cluster. The scheduler evaluates CPU requests, not limits, for admission decisions; if no node has enough unallocated CPU to satisfy the request, the pod remains Pending.

Exam trap

Candidates often confuse resource requests and limits. The scheduler uses CPU requests, not limits, to determine node capacity. Limits are for resource enforcement after scheduling.

How to eliminate wrong answers

Option A is wrong because memory limits do not affect CPU scheduling; the error specifically mentions 'Insufficient cpu', not memory. Option B is wrong because an image pull failure would result in an 'ErrImagePull' or 'ImagePullBackOff' event, not a Pending state with a CPU insufficiency message. Option C is wrong because disk pressure is a node condition that would be reported as 'Insufficient disk space' or 'DiskPressure', not 'Insufficient cpu'.

49
MCQmedium

A developer needs to run a one-off task that processes a queue and then exits. The task must run exactly once per invocation, and if the Pod fails, Kubernetes should restart it until it succeeds. The task should not be restarted after it completes successfully. Which Kubernetes resource should the developer create?

A.A Job with a restartPolicy of OnFailure and no completions or parallelism settings.
B.A bare Pod with a restartPolicy of OnFailure and no controller managing it.
C.A CronJob with a schedule that runs every minute and a restartPolicy of Never.
D.A Deployment with a single replica and a restartPolicy of Always.
AnswerA

A Job is designed for run-to-completion workloads. With restartPolicy OnFailure, the Pod is restarted only if the container exits with a non-zero code, and no restart occurs after a successful exit. Default completions and parallelism of one ensure the task runs a single time.

Why this answer

A Job is the correct resource for run-to-completion tasks. Setting restartPolicy to OnFailure restarts the Pod only on failure, and the default single completion with no parallelism ensures the task runs once and stops after success, matching the requirement.

Exam trap

The trap here is choosing a Deployment or bare Pod for a task that should stop after success, when only a Job provides run-to-completion semantics with failure retries.

50
Multi-Selecthard

Which THREE statements are true about init containers? (Select 3)

Select 3 answers
A.Init containers support liveness and readiness probes
B.Init containers cannot have resource limits
C.Init containers must complete successfully before any main container starts
D.Init containers run sequentially in the order they are defined
E.If an init container fails, it will restart until it succeeds, regardless of the pod's restartPolicy
AnswersC, D, E

This is the fundamental purpose of an init container: the kubelet will not start any main container until every init container has exited with a zero exit code. The main containers are held in a pending state while init containers execute. If any init container fails, the entire pod's startup is blocked, and the failed init container is retried according to the restart policy, so the main containers never see the failed state.

Why this answer

Init containers are specialized containers that run to completion before any main application containers in the pod start. They must exit with a zero status (success) for the pod to proceed to the next init container or to start the main containers. This ensures prerequisite setup tasks are completed before the application runs.

Exam trap

The trap here is that candidates confuse init containers with regular containers, assuming they support probes or cannot have resource limits, when in fact init containers are a distinct type with different lifecycle rules and full support for resource constraints.

51
MCQmedium

A developer wants to containerize a Node.js application. The Dockerfile should first copy only package.json and package-lock.json, run npm install, then copy the rest of the source code. Which Dockerfile best achieves this?

A.COPY . /app\nRUN npm install
B.ADD package*.json /app/\nRUN npm install\nADD . /app/
C.COPY package*.json /app/\nRUN npm install\nCOPY . /app/
D.ADD . /app\nRUN npm install
AnswerC

This is the recommended pattern: copying only `package*.json` first makes the `RUN npm install` layer depend solely on dependency manifests, so it remains cached unless those files change. After install, the remaining application code is copied in a separate layer, letting source-code edits rebuild quickly without reinstalling dependencies. Using `COPY` for both operations is correct for local build-context files, and if the source contains a `node_modules` directory, a `.dockerignore` entry should exclude it to avoid overwriting the freshly installed dependencies.

Why this answer

It first copies only package.json and package-lock.json (using a wildcard pattern), runs `npm install` to leverage Docker's layer caching, and then copies the rest of the source code. This ensures that subsequent builds only re-run `npm install` when the dependency files change, not on every source code modification, which is a best practice for efficient Docker builds.

Exam trap

In the CKAD exam, candidates often mistakenly use `ADD` instead of `COPY`, but `COPY` is the recommended command for copying local files to a Docker image without unnecessary side effects. The exam emphasizes efficient layer caching, so using `COPY` for local files and separating dependency installation from source code copying is a best practice.

How to eliminate wrong answers

Option A is wrong because it copies the entire source code before running `npm install`, which defeats Docker layer caching — any source code change invalidates the npm install cache, causing unnecessary re-installations. Option B is wrong because it uses `ADD` instead of `COPY`; while `ADD` can copy files, it has additional behaviors like automatic tar extraction and remote URL fetching, which are unnecessary here and violate the principle of using `COPY` for local file copies unless extra features are needed. Option D is wrong because it copies the entire source code before running `npm install`, similar to option A, and uses `ADD` instead of `COPY`, introducing unnecessary complexity and potential side effects.

52
MCQmedium

A user runs: kubectl apply -f job.yaml. The Job spec has backoffLimit: 0. The pod fails immediately. What happens?

A.The Job is retried indefinitely
B.The pod is restarted until it succeeds
C.The Job enters a Failed state
D.A new pod is created automatically
AnswerC

The Job controller evaluates the failure count against backoffLimit after a Pod fails; because the limit is 0, the first failure already equals the maximum allowed retries. As a result, the controller marks the Job with the Failed condition, records the failed Pod in status, and stops any further reconciliation. No pending retries remain, so the Job cannot be Active or Complete; its terminal state is Failed.

Why this answer

When `backoffLimit: 0` is set in a Job spec and the pod fails immediately, the Job controller does not retry the pod because the backoff limit is zero. According to Kubernetes Job semantics, the Job is considered failed once the number of failures reaches the `backoffLimit` (0 in this case), so the Job transitions to a Failed state without any further pod creation or retries.

Exam trap

The trap here is that candidates often confuse `backoffLimit` with pod restart policies (e.g., `restartPolicy: OnFailure`), but `backoffLimit` controls the number of retries at the Job level, not pod restarts, and a value of 0 means no retries, not infinite retries.

How to eliminate wrong answers

Option A is wrong because `backoffLimit: 0` means the Job will not retry at all, not indefinitely; indefinite retries would require a negative value or no limit. Option B is wrong because the pod is not restarted; the Job controller does not restart pods—it creates new pods, and with `backoffLimit: 0`, no new pod is created after the first failure. Option D is wrong because a new pod is not created automatically; the Job controller only creates a new pod if the failure count is below the `backoffLimit`, which is 0, so it stops immediately.

53
MCQmedium

You want to debug a running pod by starting a temporary container that has network access to the pod's containers. Which kubectl command should you use?

A.kubectl debug -it <pod> --image=debian --target=<container>
B.kubectl attach <pod>
C.kubectl run debug --image=debian --restart=Never
D.kubectl exec -it <pod> -- /bin/bash
AnswerA

kubectl debug -it <pod> --image=debian --target=<container> creates an ephemeral container in the same pod, sharing the pod's network and storage volumes, and uses --target to attach to the process namespace of the specified existing container. This injects a fresh Debian image with debugging tools directly into the running pod's context without restarting the workload or modifying its spec.

Why this answer

`kubectl debug` creates an ephemeral container in the same pod, sharing the pod's network namespace (including localhost and the same IP address) with the target container. The `--target` flag specifies which existing container's namespaces (network, PID, etc.) the ephemeral container should join, enabling direct network debugging of that container without modifying its process.

Exam trap

The trap here is that candidates often confuse `kubectl exec` (which runs inside an existing container) with `kubectl debug` (which creates a new, separate container in the same pod), and fail to recognize that `exec` cannot add a different image or provide network isolation from the target container's process environment.

How to eliminate wrong answers

Option B is wrong because `kubectl attach` connects to an already running container's stdin/stdout/stderr; it does not create a new container and provides no network debugging capabilities beyond what the existing container offers. Option C is wrong because `kubectl run debug --image=debian --restart=Never` creates a separate standalone pod with its own network namespace, so it cannot access the target pod's network stack (e.g., localhost services). Option D is wrong because `kubectl exec -it <pod> -- /bin/bash` runs a command inside an existing container, which may lack debugging tools (like `tcpdump`, `curl`, or `netcat`) and cannot add a separate container with a different image.

54
MCQeasy

Which command builds a Docker image from the current directory and tags it as 'myapp:v1'?

A.docker image build --name myapp:v1 .
B.docker build -t myapp:v1 .
C.docker build myapp:v1 .
D.docker tag myapp:v1 .
AnswerB

The `docker build -t myapp:v1 .` command is the correct syntax. The `-t` (or `--tag`) flag assigns the name and tag `myapp:v1` to the built image, while the `.` specifies the current directory as the build context, containing the Dockerfile and any files needed for the build. This command reads the Dockerfile from the context, builds the image, and tags it accordingly.

Why this answer

The `docker build` command with the `-t` flag (short for `--tag`) is the standard way to build an image from a Dockerfile in the current directory (`.`) and assign it a tag `myapp:v1`. The `-t` flag specifies the repository and tag in the format `name:tag`, and the `.` indicates the build context (the current directory).

Exam trap

The trap here is that candidates confuse the `docker build` syntax with `docker tag` or misplace the tag argument, thinking it can be passed as a positional parameter instead of using the `-t` flag.

How to eliminate wrong answers

Option A is wrong because `docker image build` is a valid subcommand, but the `--name` flag does not exist; the correct flag for tagging is `-t` or `--tag`. Option C is wrong because `docker build myapp:v1 .` places the tag argument in the wrong position — the tag must follow the `-t` flag, not be the first positional argument. Option D is wrong because `docker tag` is used to tag an existing image, not to build one; it requires an existing image ID or source tag as the first argument, not a build context.

55
MCQeasy

Which of the following best describes the purpose of an init container?

A.Init containers run in parallel with the main containers to provide auxiliary functionality
B.Init containers run to completion before the main containers start, and are used for setup tasks
C.Init containers share the same lifecycle as the main containers
D.Init containers are restarted if they exit with a non-zero exit code
AnswerB

This is the core purpose of an init container: it runs to completion before any application container in the pod is launched. Init containers are perfect for setup tasks such as database schema migrations, waiting for dependent services, or preparing configuration files. They are guaranteed to finish successfully before the pod transitions to its Running phase, making them a reliable bootstrap mechanism.

Why this answer

Init containers are specialized containers that run and complete to exit before any pod's main containers start. They are ideal for performing setup tasks such as waiting for a service to be ready, populating configuration files, or running database migrations. This ensures the main application containers start in a fully prepared environment.

Exam trap

The trap here is that candidates confuse init containers with sidecar containers, thinking they run concurrently or share the same lifecycle, when in fact init containers run to completion before any main containers start and are not part of the main container's runtime.

How to eliminate wrong answers

Option A is wrong because init containers run sequentially, not in parallel with main containers, and they complete before main containers start. Option C is wrong because init containers have a separate lifecycle: they run to completion and are not restarted unless the pod is recreated, while main containers run continuously. Option D is wrong because init containers are restarted if they exit with a non-zero exit code only if the restart policy is set to Always or OnFailure; with the default restart policy (Always), they are restarted regardless of exit code, but the key point is that they are restarted until they succeed, not that they are restarted only on non-zero exit.

56
MCQmedium

You need to ensure that a Pod always runs on a node with an SSD. Which node selector mechanism should you use?

A.Tolerations
B.Pod affinity
C.nodeName
D.nodeSelector with a label matching nodes with SSD
AnswerD

This is the correct approach. By labeling nodes that have SSDs (e.g., disktype=ssd), you can set pod.spec.nodeSelector to {disktype: ssd}, which directs the scheduler to place the pod only on nodes carrying that label. This is a simple, declarative, and supported mechanism for node-level constraints based on node labels. It works even across multiple nodes and integrates with the scheduler's filtering phase, ensuring the pod runs on an SSD-equipped node as requested.

Why this answer

`nodeSelector` is the simplest and most direct mechanism for scheduling a Pod onto nodes that possess a specific label, such as `ssd=true`. By labeling nodes that have SSDs and adding the corresponding `nodeSelector` in the Pod spec, Kubernetes ensures the Pod is only scheduled on those nodes. This approach is declarative, requires no additional controllers, and is the recommended method for simple node-level constraints.

Exam trap

The trap here is that candidates often confuse tolerations with node selection, mistakenly thinking tolerations can actively choose nodes, when in fact tolerations only permit scheduling on tainted nodes and do not enforce placement on nodes with specific hardware labels.

How to eliminate wrong answers

Option A is wrong because tolerations are used to allow Pods to schedule onto nodes that have taints, not to select nodes based on labels or hardware attributes; they enable scheduling on tainted nodes but do not actively select nodes with SSDs. Option B is wrong because Pod affinity is designed to co-locate Pods relative to other Pods (e.g., schedule near a database Pod), not to match node-level hardware characteristics like SSD presence. Option C is wrong because `nodeName` bypasses the scheduler entirely and directly assigns the Pod to a specific node by name, which is inflexible, does not use labels, and cannot dynamically select nodes based on attributes like SSD availability.

57
MCQeasy

What is the purpose of a .dockerignore file in a Docker build context?

A.It limits the number of layers in the final image
B.It excludes files and directories from being sent to the Docker daemon during the build
C.It defines environment variables for the container
D.It specifies the order of layers in the Docker image
AnswerB

A .dockerignore file defines patterns that exclude files and directories from the build context before it is transmitted to the Docker daemon. This reduces the amount of data sent, shortens build times, and prevents sensitive information like .env, SSH keys, or large local caches such as node_modules from being uploaded. Ignored files are not available for COPY or ADD within the Dockerfile, but the exclusion is purely at the context-transmission stage.

Why this answer

The .dockerignore file, when placed in the Docker build context, instructs the Docker CLI to exclude specified files and directories from the tar archive that is sent to the Docker daemon during the `docker build` command. This reduces the build context size, speeds up the build, and prevents sensitive files (e.g., .env, .git) from being included in the image layers.

Exam trap

The CKAD exam often tests the distinction between build-time and runtime configuration; the trap here is confusing the .dockerignore file (which affects the build context sent to the daemon) with files that control image layers or container runtime behavior, leading candidates to select options about layer count or environment variables.

How to eliminate wrong answers

Option A is wrong because the number of layers in a Docker image is determined by the number of RUN, COPY, and ADD instructions in the Dockerfile, not by the .dockerignore file. Option C is wrong because environment variables for a container are defined using the ENV instruction in the Dockerfile or the --env flag at runtime, not by a .dockerignore file. Option D is wrong because the order of layers in a Docker image is dictated by the sequence of instructions in the Dockerfile, not by any ignore file.

58
MCQmedium

You need to debug a running pod that does not have a shell installed. Which kubectl command allows you to start an ephemeral container with a shell?

A.kubectl create pod debug --image=busybox --attach
B.kubectl exec -it <pod> -- /bin/sh
C.kubectl debug <pod> --image=busybox --stdin --tty
D.kubectl run debug --image=busybox --attach
AnswerC

The debug subcommand injects an ephemeral container into the existing pod's namespaces, using the busybox image to supply a shell. This works when the original container lacks a shell, satisfying the debugging requirement without restarting the pod.

Why this answer

`kubectl debug` is specifically designed to add an ephemeral container to a running pod for troubleshooting purposes, even when the original container lacks a shell. The `--image=busybox` flag provides a lightweight image with common debugging tools, and `--stdin --tty` allocates an interactive terminal, allowing you to run commands like `/bin/sh` inside the ephemeral container without modifying the original pod's containers.

Exam trap

The trap here is that candidates often confuse `kubectl exec` (which requires a shell in the existing container) with `kubectl debug` (which adds a new container with a shell), or mistakenly think `kubectl run` or `kubectl create pod` can attach to an existing pod's context.

How to eliminate wrong answers

Option A is wrong because `kubectl create pod debug --image=busybox --attach` creates a new standalone pod, not an ephemeral container attached to an existing running pod, so it cannot debug the target pod's environment. Option B is wrong because `kubectl exec -it <pod> -- /bin/sh` attempts to execute a shell inside the existing container, which fails if the container does not have a shell installed (e.g., a distroless or minimal image). Option D is wrong because `kubectl run debug --image=busybox --attach` launches a new pod in the cluster, not an ephemeral container in the target pod, and thus cannot access the target pod's filesystem, processes, or network namespace.

59
MCQmedium

A CronJob has concurrencyPolicy set to 'Forbid'. At the scheduled time, if the previous job is still running, what happens?

A.The new job is delayed until the previous job completes
B.The new job is skipped (does not run)
C.Both jobs run concurrently
D.The previous job is terminated and the new job starts
AnswerB

With concurrencyPolicy: Forbid, the CronJob controller checks for any active Jobs from the same CronJob at the scheduled start time. If one exists, the controller deliberately does not create the new Job, and the scheduled invocation is skipped entirely without being queued or retried. The CronJob can then run again only at its next configured schedule, assuming no overlapping Job is still active.

Why this answer

When a CronJob has `concurrencyPolicy: Forbid`, Kubernetes ensures that if a previous job instance is still running at the next scheduled time, the new job is simply skipped (does not run). This prevents overlapping executions, which is critical for workloads that must not run concurrently, such as database migrations or batch processing that would cause data corruption.

Exam trap

The trap here is that candidates often confuse 'Forbid' with 'Replace' (which terminates the previous job) or assume Kubernetes will queue the job, but 'Forbid' strictly skips the run without any retry or delay.

How to eliminate wrong answers

Option A is wrong because 'Forbid' does not delay the new job; it skips it entirely, unlike `concurrencyPolicy: Allow` which would queue or run concurrently. Option C is wrong because 'Forbid' explicitly prevents concurrent runs, which is the opposite of running both jobs concurrently. Option D is wrong because 'Forbid' does not terminate the previous job; termination would require a custom controller or manual intervention, and Kubernetes CronJobs do not automatically kill running jobs when a new one is skipped.

60
MCQmedium

You need to schedule a task that runs every day at 2:00 AM. The task should be allowed to run even if a previous instance is still running. Which concurrencyPolicy should you set in the CronJob spec?

A.Allow
B.Replace
C.Forbid
D.Ignore
AnswerA

The concurrencyPolicy Allow (which is also the default) permits a new Job to be created even if a previous Job from the same CronJob is still running. For a daily 02:00 schedule, this ensures the task starts at the scheduled time regardless of whether the prior run completed. Since the requirement only says the task should run every day and imposes no restriction on overlapping execution, Allow is the correct and standard policy.

Why this answer

Setting `concurrencyPolicy: Allow` in a CronJob spec permits a new job instance to start even if a previous instance is still running. This is the default behavior when the field is omitted, and it directly satisfies the requirement that the task must run at 2:00 AM regardless of any overlapping executions.

Exam trap

The trap here is that candidates may confuse concurrencyPolicy with restartPolicy or assume 'Ignore' is a valid option, but Kubernetes only supports Allow, Forbid, and Replace, and the default is Allow.

How to eliminate wrong answers

Option B (Replace) is wrong because it would cancel the currently running job and start a new one, which violates the requirement to allow the previous instance to continue. Option C (Forbid) is wrong because it would skip the new job if a previous instance is still running, preventing the scheduled execution. Option D (Ignore) is not a valid value for the concurrencyPolicy field in Kubernetes; the only valid values are Allow, Forbid, and Replace.

61
MCQhard

A Pod has two containers: one with a liveness probe that fails after 30 seconds. The restartPolicy is 'Never'. What state will the Pod be in after the liveness probe fails?

A.Running
B.Failed
C.Unknown
D.CrashLoopBackOff
AnswerB

A liveness probe failure makes the kubelet kill the container; with restartPolicy: Never the kubelet will not restart it. The container's exit is processed as a terminal status, and the Pod is marked Failed (the phase is exactly Failed when all containers in a Pod have terminated and at least one has exited non-zero or was killed). This is the expected result in this scenario rather than a crash loop.

Why this answer

When a liveness probe fails, Kubernetes terminates the container and, because the restartPolicy is 'Never', does not restart it. The Pod transitions to the 'Failed' phase, as the container has exited with a non-zero exit code and will not be recreated. This is the expected behavior for a Pod with a single container that fails its health check under a 'Never' restart policy.

Exam trap

The trap here is that candidates often confuse the restartPolicy 'Never' with 'OnFailure' and assume the Pod will enter CrashLoopBackOff, but CrashLoopBackOff only applies when the restartPolicy allows restarts; with 'Never', the Pod fails permanently.

How to eliminate wrong answers

Option A is wrong because 'Running' indicates that all containers in the Pod are operational, but the liveness probe failure causes the container to be terminated, so the Pod cannot remain in the Running state. Option C is wrong because 'Unknown' is a transient state used when the node cannot report the Pod's status (e.g., due to network partition), not the final state after a liveness probe failure. Option D is wrong because 'CrashLoopBackOff' only occurs when the restartPolicy is 'Always' or 'OnFailure' and the container repeatedly crashes; with 'Never', no restart is attempted, so the Pod goes directly to 'Failed'.

62
Multi-Selectmedium

Which TWO statements about the .dockerignore file are true?

Select 2 answers
A.It is automatically applied to all docker commands
B.It supports pattern matching similar to .gitignore
C.It can be used to specify which Dockerfile to use
D.It can override the base image from the Dockerfile
E.It can exclude files from being copied into the image by COPY and ADD instructions
AnswersB, E

The .dockerignore file follows standard Go filepath.Match glob rules and supports patterns like `*`, `?`, character classes, and `**` for directory trees, closely mirroring .gitignore semantics. This allows users to define broad exclusion rules, such as `*/temp*` or `**/*.md`, to filter the build context efficiently. It also supports comments and negation with `!`, though re-inclusion after an exclusion requires careful path handling.

Why this answer

The .dockerignore file supports pattern matching using glob patterns, similar to .gitignore. This allows you to define patterns to exclude files and directories from the Docker build context, preventing them from being sent to the Docker daemon during a build.

Exam trap

The CKAD exam often tests the misconception that .dockerignore affects all Docker commands, when in reality it only applies to the docker build context, not to docker run, docker push, or other commands.

63
MCQmedium

You are writing a Dockerfile and want to ensure that the CMD instruction is overridable when running the container, but the ENTRYPOINT should not be easily overridden. Which combination should you use?

A.ENTRYPOINT ["myapp"]; CMD ["--help"]
B.CMD ["myapp", "--help"]
C.ENTRYPOINT myapp; CMD --help
D.ENTRYPOINT ["myapp"]
AnswerA

This is correct because `ENTRYPOINT ["myapp"]` uses the exec form to set `myapp` as the immutable primary process, while `CMD ["--help"]` supplies default arguments. When the container starts, Docker runs `myapp --help`; if a user passes `docker run image <args>`, those args replace the CMD list, yielding `myapp <args>` without needing `--entrypoint` redefinition. Thus the ENTRYPOINT is not easily overridden and the CMD is overridable, satisfying both requirements.

Why this answer

It uses the exec form for ENTRYPOINT, which makes ENTRYPOINT the main command that cannot be easily overridden by simply appending arguments to `docker run`. The CMD instruction provides default arguments that can be overridden by passing arguments to `docker run`. This satisfies both requirements: ENTRYPOINT is not easily overridden, and CMD is overridable.

Option D lacks a CMD instruction, so there is nothing to override; arguments passed to `docker run` become arguments to ENTRYPOINT, not a replacement of CMD. Option B uses only CMD, so ENTRYPOINT defaults to the shell and is easily overridden via --entrypoint. Option C uses shell form for ENTRYPOINT, which causes CMD and runtime arguments to be ignored, so CMD cannot be overridden — that violates the requirement.

Exam trap

The CKAD exam often tests the distinction between exec form and shell form. The trap here is that candidates mistakenly think shell form (option C) is the correct way to make ENTRYPOINT non-overridable while keeping CMD overridable. In fact, shell form ENTRYPOINT ignores CMD and runtime arguments, so it fails the CMD-overridable requirement.

Exec form is required for the desired behavior.

How to eliminate wrong answers

Option A is wrong because it uses both ENTRYPOINT and CMD in exec form, where CMD provides default arguments to ENTRYPOINT; however, the CMD can still be overridden by passing arguments to `docker run`, but the ENTRYPOINT itself is not overridable, which partially meets the requirement but the CMD is not independently overridable as a separate command. Option B is wrong because using only CMD in exec form means the entire command is overridable by `docker run` arguments, leaving no fixed ENTRYPOINT. Option C is wrong because it uses shell form for both ENTRYPOINT and CMD, which means the ENTRYPOINT runs via `/bin/sh -c`, making it easily overridable by `docker run` arguments (since shell form does not prevent override), and the CMD is also overridable.

64
Multi-Selectmedium

Which TWO statements about init containers are true? (Select 2)

Select 2 answers
A.Init containers support liveness and readiness probes.
B.Init containers share the same filesystem as the application containers by default.
C.Init containers run sequentially in the order they are defined.
D.Init containers have a restart policy of Always.
E.Init containers must complete successfully before application containers start.
AnswersC, E

The kubelet processes init containers strictly in the order they appear in the pod spec, starting the next one only after the previous has exited with code 0. This sequential behavior allows you to stage steps like waiting for a service or making a schema migration before the main app starts. There is no parallel or lazy execution among init containers.

Why this answer

Init containers in a Kubernetes Pod are executed sequentially in the exact order they are defined in the `initContainers` array. Each init container must exit successfully (return code 0) before the next one starts, ensuring a strict dependency chain for initialization tasks.

Exam trap

The trap here is that candidates often confuse init containers with regular containers, assuming they support probes or share filesystems by default, or misremember the restart policy as Always instead of OnFailure.

65
MCQhard

A pod named 'app' has a container that logs to stdout. You want to add a sidecar container that streams these logs to a centralized logging service. Which pattern does this represent?

A.Ambassador pattern
B.Adapter pattern
C.Sidecar pattern
D.Init container pattern
AnswerC

A sidecar container runs alongside the primary application container in the same pod, sharing its lifecycle, network namespace and volumes. Here it reads the app container's stdout log stream and forwards it to the centralised logging service, which is the defining sidecar pattern.

Why this answer

The sidecar pattern involves adding a secondary container (the sidecar) to the same pod as the primary container to extend or enhance its functionality without altering the primary container itself. In this scenario, the sidecar container reads the logs from the primary container's stdout (typically via a shared volume or by tailing the container's log file) and forwards them to a centralized logging service, such as Elasticsearch, Fluentd, or a cloud logging endpoint. This pattern is a core Kubernetes design pattern for modular, non-invasive extensions.

Exam trap

The trap here is that candidates often confuse the Sidecar pattern with the Ambassador pattern because both involve adding a helper container, but the Ambassador pattern specifically handles network proxying, not log streaming.

How to eliminate wrong answers

Option A is wrong because the Ambassador pattern is used to proxy network traffic to external services, not to handle log streaming; it typically involves a container that acts as a network proxy (e.g., Envoy) to abstract service discovery or authentication. Option B is wrong because the Adapter pattern is used to standardize output from multiple containers or pods into a common format (e.g., converting application metrics to Prometheus format), not to stream logs from a single container to an external service. Option D is wrong because the Init container pattern runs a container to completion before the main containers start, often for setup tasks like initializing volumes or waiting for dependencies, and is not designed for continuous log streaming.

66
MCQmedium

A user runs: kubectl run my-pod --image=nginx --restart=Never --dry-run=client -o yaml. Which apiVersion is used in the generated YAML?

A.apps/v1
B.batch/v1
C.networking.k8s.io/v1
D.v1
AnswerD

The correct answer is v1, the core Kubernetes API group, which defines foundational resources like Pods, Services, ConfigMaps, and Secrets using the short `apiVersion: v1`. With `--restart=Never`, kubectl's generator emits a standalone Pod manifest with `kind: Pod` and `apiVersion: v1`, served under the `/api/v1` REST endpoint. No other listed group defines a standalone Pod resource, making core v1 the only valid choice.

Why this answer

The `kubectl run` command, when used with `--restart=Never`, creates a standalone Pod. Pods are the most basic Kubernetes resource and belong to the core API group, which uses the `v1` apiVersion (i.e., `apiVersion: v1`). Options like `apps/v1` or `batch/v1` are for higher-level controllers such as Deployments or Jobs, not for a direct Pod creation.

Exam trap

The trap here is that candidates often associate `kubectl run` with Deployments (which use `apps/v1`) because that is the default behavior when no `--restart` flag is specified, but the `--restart=Never` flag changes the resource type to a standalone Pod, which uses `v1`.

How to eliminate wrong answers

Option A is wrong because `apps/v1` is the apiVersion for higher-level workloads like Deployments, StatefulSets, and DaemonSets, not for a standalone Pod created by `kubectl run --restart=Never`. Option B is wrong because `batch/v1` is the apiVersion for Jobs and CronJobs, which are used for batch processing, not for a simple Pod. Option C is wrong because `networking.k8s.io/v1` is the apiVersion for NetworkPolicy and Ingress resources, which are unrelated to Pod creation.

67
MCQmedium

You need to run a batch job that processes a queue and must ensure exactly 5 pods run successfully in parallel. Which Job configuration field should be set?

A.spec.backoffLimit: 5
B.spec.ttlSecondsAfterFinished: 5
C.spec.parallelism: 5
D.spec.completions: 5
AnswerC

spec.parallelism defines the desired number of Pods that the Job controller runs simultaneously, which is exactly what you need when processing a queue with five concurrent workers. Setting it to 5 makes the controller create up to five Pods at the same time, each pulling items from the queue in parallel. This directly satisfies the requirement to run a batch job that processes a queue with a concurrency of five.

Why this answer

`spec.parallelism` controls the maximum number of Pods that can run concurrently for a Job. Setting `parallelism: 5` ensures exactly 5 Pods run in parallel, which matches the requirement to process a queue with five simultaneous workers.

Exam trap

The trap here is confusing `spec.parallelism` (concurrent Pods) with `spec.completions` (total successful Pods), leading candidates to pick D when the question explicitly asks for parallel execution.

How to eliminate wrong answers

Option A is wrong because `spec.backoffLimit` sets the number of retries before marking the Job as failed, not the number of parallel Pods. Option B is wrong because `spec.ttlSecondsAfterFinished` controls how long a completed Job is retained before automatic cleanup, not parallelism. Option D is wrong because `spec.completions` defines the total number of successful Pod completions required for the Job to finish, not the number of Pods running simultaneously.

68
MCQmedium

A developer is writing a Dockerfile and wants to ensure that the container runs a Python script named 'app.py' as its main process. Which instruction should be used?

A.EXPOSE 8080
B.CMD ["python", "app.py"]
C.ENTRYPOINT ["python", "app.py"]
D.RUN ["python", "app.py"]
AnswerC

ENTRYPOINT sets the container's primary executable and is the instruction that ensures python app.py runs whenever the container starts, because the command is baked into the image's configuration. Any arguments supplied with docker run are appended to the ENTRYPOINT array rather than replacing it, so the default process remains python app.py. Only the explicit --entrypoint flag can override it, making ENTRYPOINT the correct choice when the application must always be the container's main process.

Why this answer

ENTRYPOINT defines the executable that runs as the main process in the container. When combined with CMD (or used alone in exec form), it ensures that 'python app.py' is the primary process with PID 1, which is essential for proper signal handling and container lifecycle management.

Exam trap

The trap here is that candidates confuse CMD with ENTRYPOINT, thinking CMD always runs the main process, but CMD can be overridden and is often used for default arguments, while ENTRYPOINT is designed to be the immutable executable.

How to eliminate wrong answers

Option A is wrong because EXPOSE is a documentation-only instruction that declares the container listens on a port; it does not run any process. Option B is wrong because CMD provides default arguments to ENTRYPOINT or a default command, but it can be overridden at runtime; if used alone, it runs the command but is not guaranteed to be the main process in all scenarios (e.g., when ENTRYPOINT is also defined). Option D is wrong because RUN executes commands during image build, not at container runtime, so it cannot set the main process for the container.

69
MCQeasy

Which of the following is the correct apiVersion for a CronJob in Kubernetes v1.29?

A.v1
B.cronjob/v1
C.batch/v1beta1
D.batch/v1
AnswerD

Since Kubernetes v1.21, CronJob is available as a stable API with the apiVersion `batch/v1`. The apiVersion correctly includes the API group `batch` (which also contains Job) and the stable version `v1`, ensuring the manifest is accepted by the API server. This is the recommended and currently supported version for creating CronJob resources.

Why this answer

In Kubernetes v1.29, the correct apiVersion for a CronJob is batch/v1, as CronJob has been stable since v1.21. Option D is correct because batch/v1 is the stable API version for CronJob resources in this release.

Exam trap

The trap here is that candidates may remember older Kubernetes versions where CronJob was still in beta (batch/v1beta1) and fail to update their knowledge to the stable batch/v1, or they might confuse the apiVersion format with a non-existent cronjob/v1.

How to eliminate wrong answers

Option A is wrong because v1 is the apiVersion for core resources like Pod, Service, and ConfigMap, not for CronJob which belongs to the batch API group. Option B is wrong because there is no apiVersion format like cronjob/v1; Kubernetes uses group/version format, and CronJob is part of the batch group. Option C is wrong because batch/v1beta1 was deprecated in v1.21 and removed in v1.25; using it in v1.29 would cause an error.

70
MCQmedium

A CronJob must run a task every day at midnight, but if the previous job is still running, the new job should be skipped. Which concurrencyPolicy should be set?

A.Skip
B.Forbid
C.Allow
D.Replace
AnswerB

Forbid is the correct concurrencyPolicy because it tells the CronJob controller to skip the scheduled invocation if a job from the previous run is still active. Unlike Allow, it never starts an overlapping job, and unlike Replace, it does not terminate or re-create anything; it simply leaves the current job running and drops that particular tick. This yields the skip-if-still-running behavior that the question asks for.

Why this answer

B is correct because the `Forbid` concurrency policy ensures that if a previous job instance is still running when the next scheduled trigger fires, the new job is simply skipped. This matches the requirement to avoid overlapping executions without terminating the running job.

Exam trap

The trap here is that candidates may confuse `Forbid` with `Skip` (which is not a valid Kubernetes value) or incorrectly think `Replace` is the correct way to avoid overlaps, when in fact `Replace` kills the running job instead of skipping the new one.

How to eliminate wrong answers

Option A is wrong because `Skip` is not a valid concurrencyPolicy value in Kubernetes; the valid options are `Allow`, `Forbid`, and `Replace`. Option C is wrong because `Allow` would let the new job start even if the previous one is still running, leading to concurrent executions. Option D is wrong because `Replace` would terminate the currently running job and start a new one, which does not meet the requirement to skip the new job if the previous is still running.

71
Drag & Dropmedium

Sequence the steps to expose a Kubernetes Service using a NodePort for external access.

Drag or tap steps into the slots.

Steps
Order
1Step 1
2Step 2
3Step 3
4Step 4

Why this order

Deployment first, then define NodePort Service, apply, retrieve port, then access externally.

72
MCQeasy

What is the primary purpose of an Init Container in a Pod?

A.Perform initialization tasks such as waiting for a database to be ready
B.Run a sidecar proxy alongside the main container
C.Provide a health check endpoint for the main container
D.Collect logs and metrics from the main container
AnswerA

Init containers exist specifically to run one-time setup tasks that must finish successfully before the main application containers are started. A canonical example is polling or blocking until a database or external service is reachable, because the app cannot function until that prerequisite exists. They execute sequentially, run to completion, and if one fails, the whole pod is restarted according to its restartPolicy — they are not long-running processes.

Why this answer

Init containers run to completion before the main application containers start, making them ideal for blocking or delaying the main container until prerequisites like a database readiness check succeed. They execute sequentially and can use different container images, allowing setup tasks without bloating the main app image or requiring special permissions.

Exam trap

The trap here is confusing init containers with sidecar containers — both run in the same Pod, but init containers are ephemeral and block startup, while sidecars persist for the Pod's lifetime.

How to eliminate wrong answers

Option B is wrong because a sidecar proxy (e.g., Envoy or Istio sidecar) runs continuously alongside the main container, not as a one-time init task; init containers terminate after completion. Option C is wrong because health check endpoints (liveness/readiness probes) are configured on the main container or a sidecar, not provided by an init container which exits before the main container starts. Option D is wrong because log and metric collection is typically done by a sidecar container (e.g., Fluentd) or a daemon set, not by an init container which runs only once and exits.

73
MCQmedium

You are tasked with containerizing a Go application. The application compiles into a binary. Which Dockerfile best implements a multi-stage build to produce a minimal image?

A.FROM AS builder\nWORKDIR /app\nCOPY . .\nRUN go build -o myapp\nFROM scratch\nCOPY --from=builder /app/myapp /myapp\nCMD ["/myapp"]
B.FROM ubuntu:latest\nRUN apt-get update && apt-get install -y golang\nCOPY . /app\nWORKDIR /app\nRUN go build -o myapp\nCMD ["./myapp"]
C.FROM golang:1.21 AS builder\nWORKDIR /app\nCOPY . .\nRUN go build -o myapp\nFROM scratch\nCOPY --from=builder /app/myapp /myapp\nCMD ["/myapp"]
D.FROM golang:1.21\nWORKDIR /app\nCOPY . .\nRUN go build -o myapp\nCMD ["./myapp"]
AnswerC

This multi-stage build is the optimal solution: the first stage uses golang:1.21 to compile the application in a controlled environment, then the second stage copies only the compiled binary into a scratch (empty) image. The final image contains just the executable, which is possible because Go can statically link most programs without a runtime or system libraries, yielding a minimal, secure container with fast startup and a tiny attack surface.

Why this answer

It uses a multi-stage build: the first stage uses the official `golang:1.21` image to compile the Go binary, and the second stage copies only the compiled binary into a `scratch` (empty) image. This produces a minimal image containing only the binary and no build tools, reducing attack surface and image size.

Exam trap

The CKAD exam often tests the requirement to explicitly name the builder stage (e.g., `AS builder`) and use the correct `COPY --from=builder` syntax, and the trap here is that candidates may pick Option A thinking it is valid multi-stage, overlooking the missing base image in the first `FROM`.

How to eliminate wrong answers

Option A is wrong because it omits the base image name in the `FROM` line (`FROM AS builder` is invalid; a base image like `golang:1.21` must be specified). Option B is wrong because it uses `ubuntu:latest` and installs Go via `apt-get`, which creates a large image with unnecessary OS packages and build dependencies, defeating the purpose of a minimal image. Option D is wrong because it is a single-stage build that includes the entire Go toolchain and source code in the final image, resulting in a bloated image.

74
MCQmedium

You want to expose a container's port 8080 in the Dockerfile. Which instruction should you use?

A.PORT 8080
B.EXPOSE 8080
C.LISTEN 8080
D.PUBLISH 8080
AnswerB

EXPOSE 8080 is the correct Dockerfile instruction; it informs Docker that the container listens on TCP port 8080 at runtime. This declaration acts as metadata and also enables the docker run -P flag to automatically publish every exposed port to a random host port. Without a protocol specified, EXPOSE defaults to TCP, so EXPOSE 8080 and EXPOSE 8080/tcp are equivalent.

Why this answer

The `EXPOSE` instruction in a Dockerfile informs Docker that the container listens on the specified network port at runtime. It is a metadata declaration that does not actually publish the port; it serves documentation and inter-container communication purposes via Docker networks.

Exam trap

The trap here is that candidates confuse `EXPOSE` with actually publishing the port to the host, thinking it makes the container accessible externally, when in fact it only declares intent and requires `-p` or `--publish` for host access.

How to eliminate wrong answers

Option A is wrong because `PORT` is not a valid Dockerfile instruction; the correct keyword is `EXPOSE`. Option C is wrong because `LISTEN` is not a Dockerfile instruction; it is a directive used in configuration files for services like Apache or Nginx. Option D is wrong because `PUBLISH` is not a Dockerfile instruction; port publishing is done at container runtime using the `-p` or `--publish` flag with `docker run`.

75
MCQhard

You have a Pod that runs a web server and you want to add a sidecar container that exposes a Prometheus metrics endpoint by scraping the web server's logs. Which sidecar pattern does this exemplify?

A.Sidecar pattern (generic)
B.Adapter pattern
C.Ambassador pattern
D.Init container pattern
AnswerB

The adapter pattern is a sidecar specialization that modifies or transforms data produced by the main container to match an external interface expected by consumers. In this scenario, the sidecar reads the web server's raw logs and converts them into structured metrics (e.g., request count, latency) that a monitoring system can ingest. This is the correct classification because the core action is data format conversion, not generic process execution or network proxying.

Why this answer

The Adapter pattern is a sidecar pattern where the sidecar container transforms or adapts the main container's output into a format consumable by an external system. Here, the sidecar scrapes the web server's logs and exposes them as Prometheus metrics, adapting log data into a metrics endpoint. This is a classic example of the Adapter pattern.

Exam trap

The trap is confusing the Adapter pattern with the Ambassador pattern; candidates may think any sidecar that communicates externally is an Ambassador, but Adapter specifically transforms data format, while Ambassador proxies network traffic.

How to eliminate wrong answers

Option A is wrong because 'Sidecar pattern (generic)' is too broad; the specific pattern is Adapter. Option C is wrong because the Ambassador pattern proxies network traffic to and from the main container, typically for external service access, not for transforming logs into metrics. Option D is wrong because an Init container runs before the main container to perform setup tasks, not alongside it to provide ongoing functionality.

Page 1 of 2 · 149 questions totalNext →

Ready to test yourself?

Try a timed practice session using only Application Design and Build questions.