Courseiva

Certified Kubernetes Application Developer CKAD (CKAD) — Questions 76–150

826 questions total · 12pages · All types, answers revealed

Page 1

Page 2 of 12

Page 3
76
Multi-Selectmedium

Which THREE of the following are valid fields in a PodSecurityPolicy (PSP) that control Linux capabilities? (Select exactly 3)

Select 3 answers
A.privileged
B.defaultAddCapabilities
C.readOnlyRootFilesystem
D.requiredDropCapabilities
E.allowedCapabilities
AnswersB, D, E

`defaultAddCapabilities` specifies a list of Linux capabilities that are appended to the `default` set of capabilities for every container created under the policy. It is a valid capability field because it directly controls which capabilities are added by default, complementing the container runtime defaults.

Why this answer

`defaultAddCapabilities` is a valid field in a PodSecurityPolicy (PSP) that specifies a list of Linux capabilities to be added to containers by default, even if not explicitly requested in the container's security context. This field is part of the PSP's capabilities control mechanism, as defined in the Kubernetes PodSecurityPolicy spec.

Exam trap

CNCF often tests the distinction between fields that directly control capabilities (like `allowedCapabilities`, `defaultAddCapabilities`, `requiredDropCapabilities`) and other security-related fields (like `privileged` or `readOnlyRootFilesystem`) that serve different purposes, causing candidates to select options that are not capability-specific.

77
MCQmedium

A NetworkPolicy named 'default-deny-ingress' is applied to a namespace but contains no rules. What is the effect on pods in that namespace?

A.All ingress traffic is denied.
B.Only traffic from pods with label 'allow: true' is allowed.
C.All ingress traffic is allowed.
D.Only traffic from pods in the same namespace is allowed.
AnswerA

A NetworkPolicy with an empty ingress rules list applies an implicit default-deny behavior: the pod selected by the podSelector is isolated, and because no source is listed as allowed, the Kubernetes network plugin blocks all incoming traffic to that pod. There is no separate 'deny all' rule needed; the absence of any ingress rule is itself the deny-all condition. This is why the policy is called a default-deny ingress policy.

Why this answer

A NetworkPolicy with no rules defaults to denying all ingress traffic because Kubernetes NetworkPolicies are additive: any pod selected by a NetworkPolicy is isolated, and only traffic explicitly allowed by rules is permitted. Since this policy has no rules, no ingress traffic is allowed, effectively creating a deny-all ingress policy for pods in the namespace.

Exam trap

The trap here is that candidates assume an empty NetworkPolicy has no effect or allows all traffic by default, but Kubernetes isolates pods as soon as they are selected by any NetworkPolicy, and an empty rules list means deny all.

How to eliminate wrong answers

Option B is wrong because a NetworkPolicy with no rules does not implicitly allow traffic from pods with a specific label; any allow rule must be explicitly defined. Option C is wrong because applying a NetworkPolicy to a namespace isolates pods, and without any rules, all ingress traffic is denied, not allowed. Option D is wrong because allowing traffic only from the same namespace requires an explicit rule with a namespaceSelector or podSelector; an empty policy does not grant any such permission.

78
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.

79
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.

80
MCQhard

A Pod is configured with securityContext: { runAsUser: 1000, runAsGroup: 2000, fsGroup: 3000 }. The container's image runs a process that must listen on a TCP port below 1024 (e.g., port 80). The process is currently failing to start. What should you modify to allow the process to bind to a privileged port?

A.Set 'allowPrivilegeEscalation: true'
B.Add 'capabilities.drop: [ALL]' to the container's securityContext
C.Add 'capabilities.add: [NET_BIND_SERVICE]' to the container's securityContext
D.Set runAsUser: 0 to run as root
AnswerC

Adding the NET_BIND_SERVICE capability to the container's securityContext grants the precise Linux capability that allows a non-root process to bind to Internet domain sockets with port numbers below 1024. This directly solves the port-binding problem while preserving the principle of least privilege, because the process continues to run as the unprivileged user 1000 and retains no other unnecessary capabilities. It is the correct, secure approach to exposing a service on a standard HTTP/HTTPS port.

Why this answer

The container process runs as a non-root user (UID 1000) and needs to bind to a privileged port (below 1024). Linux requires either root privileges or the CAP_NET_BIND_SERVICE capability to bind to ports below 1024. Adding this capability to the container's securityContext grants the process the necessary privilege without running as root, which is the correct and secure approach.

Exam trap

The trap here is that candidates often confuse allowPrivilegeEscalation with granting specific capabilities, or they incorrectly assume that dropping all capabilities is a safe default that still allows low-port binding, when in fact it removes the very capability needed.

How to eliminate wrong answers

Option A is wrong because allowPrivilegeEscalation controls whether a process can gain more privileges than its parent (e.g., via setuid binaries), but it does not grant the specific capability needed to bind to a privileged port. Option B is wrong because dropping all capabilities (capabilities.drop: [ALL]) removes all Linux capabilities, including any that might allow binding to low ports, making the problem worse. Option D is wrong because setting runAsUser: 0 runs the container as root, which would work but violates the principle of least privilege and is not the minimal change required; the question asks what to modify to allow binding, and adding the specific capability is the correct targeted fix.

81
MCQeasy

Which command is used to rollback a Deployment to the previous revision?

A.kubectl rollout undo deployment my-deployment
B.kubectl rollout redo deployment my-deployment
C.kubectl rollout revert deployment my-deployment
D.kubectl rollout history deployment my-deployment
AnswerA

The `kubectl rollout undo deployment my-deployment` command is the correct rollback mechanism because it reverts the Deployment to the previously active ReplicaSet, effectively restoring the last known good Pod template. You can optionally specify `--to-revision` to target a specific historical revision; otherwise, it undoes only the most recent rollout, scaling down the current ReplicaSet and scaling up the prior one.

Why this answer

'kubectl rollout undo deployment my-deployment'. Option B rolls forward? Option C is not valid. Option D is for history.

82
MCQeasy

What is the purpose of a ResourceQuota in Kubernetes?

A.To set default resource limits for containers that do not specify them.
B.To limit the total amount of resources (CPU, memory, etc.) that can be consumed by all pods in a namespace.
C.To limit the number of nodes in a cluster.
D.To limit the number of replicas in a Deployment.
AnswerB

A ResourceQuota is a namespaced API object that, via the admission controller, enforces hard limits on aggregate resource use — such as requests.cpu, requests.memory, limits.cpu, limits.memory, and extended or storage resources — across every workload in the namespace. When a new object's resource totals would push the namespace past those limits, the creation request is rejected. In effect, it caps the combined consumption of all pods rather than applying constraints to any single container.

Why this answer

A ResourceQuota is a Kubernetes object that enforces aggregate resource consumption limits on a per-namespace basis. It constrains the total CPU, memory, and other resource requests and limits across all pods in that namespace, preventing any single namespace from exhausting cluster resources. Option B correctly identifies this namespace-level resource cap.

Exam trap

The trap here is confusing ResourceQuota (namespace-wide resource cap) with LimitRange (per-container default limits), as both deal with resource constraints but at different scopes and with different enforcement mechanisms.

How to eliminate wrong answers

Option A is wrong because setting default resource limits for containers is the purpose of a LimitRange, not a ResourceQuota; a LimitRange applies default requests/limits per container, while a ResourceQuota caps total namespace usage. Option C is wrong because the number of nodes in a cluster is managed by cluster autoscalers or cloud provider configurations, not by a ResourceQuota, which operates only within a namespace. Option D is wrong because limiting replicas in a Deployment is done via the Deployment's spec.replicas field or a HorizontalPodAutoscaler, not by a ResourceQuota, which does not control replica counts directly.

83
MCQeasy

During a rolling update, you want to ensure that at most 2 pods are unavailable at any time. Which field should you set in the Deployment spec?

A.spec.strategy.type: Recreate
B.spec.replicas: 2
C.spec.strategy.rollingUpdate.maxSurge: 2
D.spec.strategy.rollingUpdate.maxUnavailable: 2
AnswerD

spec.strategy.rollingUpdate.maxUnavailable: 2 directly caps the number of pods that may be unavailable during a rolling update, ensuring that at most 2 pods are down at any given time relative to the desired replica count. The Deployment controller uses this value to decide when it can scale down old ReplicaSets and scale up new ones, keeping the available pod count at desired minus 2. This is the exact setting needed for the stated requirement of allowing at most 2 replicas to be unavailable.

Why this answer

`spec.strategy.rollingUpdate.maxUnavailable` specifies the maximum number of Pods that can be unavailable during a rolling update. Setting `maxUnavailable: 2` ensures that at most 2 Pods are unavailable at any time, allowing the update to proceed while maintaining the desired availability.

Exam trap

The trap here is confusing `maxSurge` (which controls extra Pods created above the desired count) with `maxUnavailable` (which controls Pods that can be unavailable), leading candidates to incorrectly select `maxSurge` when the question asks about limiting unavailable Pods.

How to eliminate wrong answers

Option A is wrong because `spec.strategy.type: Recreate` terminates all existing Pods before creating new ones, which would cause all Pods to be unavailable during the update, not limiting unavailability to 2. Option B is wrong because `spec.replicas: 2` sets the desired number of Pod replicas to 2, but does not control the number of unavailable Pods during a rolling update; it defines the target count, not a constraint on unavailability. Option C is wrong because `spec.strategy.rollingUpdate.maxSurge: 2` controls the maximum number of Pods that can be created above the desired replica count during an update, not the number of unavailable Pods.

84
MCQmedium

You need to grant a ServiceAccount 'my-sa' read-only access to pods in the 'test' namespace. Which RBAC YAML should you create?

A.kind: ClusterRole\napiVersion: rbac.authorization.k8s.io/v1\nmetadata:\n name: pod-reader\nrules:\n- apiGroups: [""]\n resources: ["pods"]\n verbs: ["get", "list", "watch"]\n---\nkind: ClusterRoleBinding\napiVersion: rbac.authorization.k8s.io/v1\nmetadata:\n name: read-pods\nsubjects:\n- kind: ServiceAccount\n name: my-sa\n namespace: test\nroleRef:\n kind: ClusterRole\n name: pod-reader\n apiGroup: rbac.authorization.k8s.io
B.kind: Role\napiVersion: rbac.authorization.k8s.io/v1\nmetadata:\n namespace: test\n name: pod-reader\nrules:\n- apiGroups: [""]\n resources: ["pods"]\n verbs: ["get", "list", "watch"]\n---\nkind: RoleBinding\napiVersion: rbac.authorization.k8s.io/v1\nmetadata:\n namespace: test\n name: read-pods\nsubjects:\n- kind: ServiceAccount\n name: my-sa\n namespace: test\nroleRef:\n kind: Role\n name: pod-reader\n apiGroup: rbac.authorization.k8s.io
C.kind: Role\napiVersion: rbac.authorization.k8s.io/v1\nmetadata:\n namespace: test\n name: pod-reader\nrules:\n- apiGroups: [""]\n resources: ["pods"]\n verbs: ["create", "delete"]
D.kind: Role\napiVersion: rbac.authorization.k8s.io/v1\nmetadata:\n name: pod-reader\n namespace: default\nrules: ...\n---\nkind: RoleBinding ...
AnswerB

This correctly defines a namespaced Role in the test namespace with read-only pod verbs (get, list, watch) and binds it to the specified service account using a RoleBinding in the same test namespace. Because both the Role and RoleBinding are namespaced, the access is scoped precisely to the test namespace. The verb set is limited to read operations, satisfying the read-only requirement exactly.

Why this answer

It creates a Role in the 'test' namespace with read-only verbs ('get', 'list', 'watch') on pods, and binds that Role to the ServiceAccount 'my-sa' in the same namespace via a RoleBinding. This grants the ServiceAccount scoped, namespace-level read-only access to pods, which matches the requirement precisely.

Exam trap

CNCF often tests the distinction between Role and ClusterRole, and between RoleBinding and ClusterRoleBinding, to see if candidates understand that namespace-scoped access requires a Role and RoleBinding, not a ClusterRole and ClusterRoleBinding, even when the permissions are identical.

How to eliminate wrong answers

Option A is wrong because it uses a ClusterRole and ClusterRoleBinding, which grant cluster-wide access; the requirement is for read-only access only in the 'test' namespace, so a namespace-scoped Role and RoleBinding are appropriate. Option C is wrong because it defines a Role with 'create' and 'delete' verbs, which are write operations, not read-only; it also lacks a RoleBinding to actually bind the Role to the ServiceAccount. Option D is wrong because the Role is created in the 'default' namespace, not the 'test' namespace, so it would not grant access to pods in the 'test' namespace.

85
MCQmedium

A pod named 'test-pod' in namespace 'test' has a service account 'my-sa' attached. The service account has a RoleBinding to a Role that allows get/list pods. However, the pod cannot list pods. What is the most likely issue?

A.The pod is using the default service account instead of 'my-sa'
B.The RoleBinding is in a different namespace than the pod
C.RoleBindings cannot grant access to list pods
D.The pod has automountServiceAccountToken set to false
AnswerB

RoleBindings are namespace-scoped resources: they bind a Role to a service account only within the namespace where the RoleBinding is created. If the RoleBinding resides in, say, 'kube-system' instead of 'test', the SA 'my-sa' in 'test' has no permissions, and the pod cannot list pods. The RoleBinding must be in the same namespace as the pod and its service account to take effect.

Why this answer

RoleBindings in Kubernetes are namespace-scoped and can only grant permissions within the namespace where they are created. If the RoleBinding is in a different namespace than the pod, the service account 'my-sa' will not have the get/list pods permissions in the pod's namespace, causing the pod to fail when trying to list pods.

Exam trap

CNCF often tests the namespace-scoping of RoleBindings versus ClusterRoleBindings, tricking candidates into thinking a RoleBinding in any namespace can grant permissions to a pod in another namespace.

How to eliminate wrong answers

Option A is wrong because the question explicitly states the pod has service account 'my-sa' attached, so it is not using the default service account. Option C is wrong because RoleBindings can grant access to list pods via a Role that includes the 'list' verb on 'pods' resources; this is a standard RBAC capability. Option D is wrong because automountServiceAccountToken set to false would prevent the pod from mounting the service account token, but the pod would then have no credentials at all, not just fail to list pods; the question states the pod cannot list pods specifically, implying it has some token but lacks the correct permissions.

86
MCQeasy

A developer needs to create a Secret named 'db-credentials' in the 'staging' namespace using the literal values username=admin and password=S3cr3t!. Which kubectl command will accomplish this?

A.kubectl create secret tls db-credentials --from-literal=username=admin --from-literal=password=S3cr3t! -n staging
B.kubectl create secret generic db-credentials --from-literal=username:admin --from-literal=password:S3cr3t! -n staging
C.kubectl create secret generic db-credentials --from-literal=username=admin --from-literal=password=S3cr3t! -n staging
D.kubectl create secret generic db-credentials --from-file=username=admin --from-file=password=S3cr3t! -n staging
AnswerC

This command uses kubectl create secret generic with the --from-literal flag to specify key-value pairs directly. The -n staging flag targets the correct namespace. This is the standard way to create a Secret from literal values. The resulting Secret will have base64-encoded data for each key, which is the expected format for Kubernetes Secrets.

Why this answer

The kubectl create secret generic command with --from-literal is designed to create a Secret from literal key-value pairs. The -n flag specifies the namespace. The other options either use incorrect flags or syntax that does not match the intended use, such as --from-file requiring files or the tls type requiring certificates.

Exam trap

The trap here is confusing --from-literal with --from-file, or using a colon instead of an equals sign in the key-value pair.

87
MCQeasy

A developer wants to deploy a stateless application as a set of identical pods. They need the pods to be distributed across nodes and have stable network identities. Which resource should they use?

A.Job
B.Deployment
C.DaemonSet
D.StatefulSet
AnswerD

A StatefulSet assigns each pod a stable, zero-based ordinal hostname (e.g., web-0, web-1) derived from the StatefulSet name and replica index. These identities persist across rescheduling because a replacement pod always inherits the same ordinal and, if configured, the same PersistentVolumeClaim. Combined with a headless service, each pod gets a unique DNS name, which perfectly fulfills the requirement for stable network identities in a stateless or stateful application.

Why this answer

StatefulSet is the correct resource because it provides each pod with a stable, unique network identity (e.g., pod-name-0, pod-name-1) that persists across rescheduling. While Deployment manages replicas for stateless applications, it does not assign per-pod stable hostnames. The question explicitly requires 'stable network identities' for identical pods, which is a defining feature of StatefulSet.

A Service combined with a Deployment gives a stable endpoint for the set, not per-pod identities.

Exam trap

Candidates may incorrectly choose Deployment, thinking that a Service provides stable network identities. However, a Service provides a stable endpoint for the entire set of pods, not individual pod identities. StatefulSet is needed for per-pod stable DNS names, which match the requirement for 'stable network identities' for each pod.

How to eliminate wrong answers

Option A is wrong because a Job is designed for batch processing or one-time tasks, not for running a continuously serving stateless application with multiple identical pods. Option C is wrong because a DaemonSet ensures exactly one pod per node, which is used for node-level services (e.g., logging, monitoring) and does not distribute pods arbitrarily across nodes for scaling. Option D is wrong because a StatefulSet is intended for stateful applications requiring stable, unique network identities and persistent storage, which is unnecessary for a stateless application.

88
MCQeasy

A developer needs to view the logs of a pod named 'web-app-84b7f6f5b6-abcde' that crashed and has been restarted. Which kubectl command should they use to see the logs from the previous (crashed) instance?

A.kubectl logs web-app-84b7f6f5b6-abcde
B.kubectl logs --all-containers web-app-84b7f6f5b6-abcde
C.kubectl logs --previous web-app-84b7f6f5b6-abcde
D.kubectl logs -f web-app-84b7f6f5b6-abcde
AnswerC

The --previous flag instructs kubectl to retrieve logs from the previous, terminated instance of the container rather than the current one. In a typical crash-loop scenario, the kubelet retains the log file of the last terminated container on the node, and kubectl accesses it through the API's 'previous' option. This gives the developer visibility into the exact output that caused the prior container to exit, making it the correct command when the pod is named with an instance suffix and the developer suspects a restart has occurred.

Why this answer

The `--previous` flag in `kubectl logs` retrieves logs from the previous instance of a container that has been restarted. This is essential for debugging a crashed pod, as the current container's logs only reflect the new instance after the restart.

Exam trap

The trap here is that candidates often confuse `--previous` with `--all-containers` or `-f`, not realizing that only `--previous` specifically targets logs from the terminated container instance.

How to eliminate wrong answers

Option A is wrong because `kubectl logs` without flags only shows logs from the current (running) container, not the crashed instance. Option B is wrong because `--all-containers` targets all containers in the pod but still fetches logs from the current instance, not the previous one. Option D is wrong because `-f` (follow) streams logs in real-time from the current container, which does not provide access to logs from the previous crashed instance.

89
MCQmedium

Which command outputs the pod's full YAML specification including status?

A.kubectl describe pod <pod-name>
B.kubectl get pod <pod-name> --export
C.kubectl get pod <pod-name> -o json
D.kubectl get pod <pod-name> -o yaml
AnswerD

kubectl get pod <pod-name> -o yaml returns the live pod object from the API server serialized as YAML, including metadata (annotations/labels), spec, and status. This is the canonical way to dump the complete pod specification as stored by Kubernetes, though it includes defaulted fields and status that aren't part of the original input manifest.

Why this answer

`kubectl get pod <pod-name> -o yaml` outputs the full YAML specification of the pod, including its status (e.g., conditions, container statuses, phase). The `-o yaml` flag retrieves the complete Kubernetes resource object from the API server, which includes both the desired spec and the current status, as stored in etcd.

Exam trap

The trap here is that candidates often confuse `kubectl describe` (which shows status in a readable format) with `kubectl get -o yaml` (which outputs the full YAML specification including status), or mistakenly think `--export` preserves status when it actually strips it.

How to eliminate wrong answers

Option A is wrong because `kubectl describe pod` outputs a human-readable summary, not the full YAML specification; it omits many fields and is not structured for programmatic use. Option B is wrong because `--export` is a deprecated flag that strips cluster-specific information (like status, nodeName, and uid) to produce a minimal spec for re-creation, so it does not include status. Option C is wrong because `-o json` outputs the full specification in JSON format, not YAML, so it does not match the question's requirement for YAML output.

90
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.

91
MCQmedium

You have an Ingress that should route requests to 'api.example.com' to a service named 'api-svc' on port 80, and requests to 'www.example.com' to 'web-svc' on port 80. Which host-based routing rule is correct?

A.spec: rules: - http: paths: - host: api.example.com backend: service: name: api-svc port: number: 80 - host: www.example.com backend: service: name: web-svc port: number: 80
B.spec: rules: - host: api.example.com http: paths: - backend: service: name: api-svc port: number: 80 - host: www.example.com http: paths: - backend: service: name: web-svc port: number: 80
C.spec: rules: - host: api.example.com - backend: service: name: api-svc port: number: 80 - host: www.example.com - backend: service: name: web-svc port: number: 80
D.spec: rules: - host: api.example.com http: paths: - backend: serviceName: api-svc servicePort: 80 - host: www.example.com http: paths: - backend: serviceName: web-svc servicePort: 80
AnswerB

This correctly defines two separate Ingress rules, each with its own `host` at the rule level. Each rule then has an `http` block containing a `paths` array, and each path designates a backend using the current `service.name` and `service.port.number` fields. This enables host-based routing: requests for api.example.com go to api-svc, while www.example.com requests go to web-svc.

Why this answer

It follows the Kubernetes Ingress v1 API specification: each rule in `spec.rules` is an object with a `host` field and an `http` field, and within `http`, a `paths` array containing backend references. This structure correctly routes requests for `api.example.com` to `api-svc:80` and `www.example.com` to `web-svc:80`.

Exam trap

The trap here is that candidates confuse the placement of `host` as a field inside `paths` (Option A) or omit the `http:` wrapper (Option C), because they think host-based routing is defined per path rather than per rule, or they recall the deprecated API syntax (Option D) from older Kubernetes versions.

How to eliminate wrong answers

Option A is wrong because it places the `host` field inside the `paths` array under `http`, but `host` is a property of the rule, not a path entry; the Ingress controller will ignore or reject this malformed structure. Option C is wrong because it uses a list item (`- backend:`) directly under the rule without the required `http:` key and `paths:` array, which is invalid YAML/JSON for the Ingress spec. Option D is wrong because it uses the legacy `serviceName` and `servicePort` fields from the deprecated `extensions/v1beta1` API; the current `networking.k8s.io/v1` API requires `name` and `number` under `service`.

92
MCQmedium

A StatefulSet named 'web' is created with 3 replicas. What is the DNS name for the second pod (index 1)?

A.web-1.web.default.svc.cluster.local
B.web-2.web.default.svc.cluster.local
C.web.default.svc.cluster.local
D.web-1.default.svc.cluster.local
AnswerA

web-1.web.default.svc.cluster.local is correct because StatefulSet pods follow the stable DNS naming pattern <pod-name>.<governing-service>.<namespace>.svc.cluster.local. The pod is named web-1 and the governing service is web, so combining the two yields this exact FQDN. This allows clients to target a specific replica's stable network identity.

Why this answer

In Kubernetes, a StatefulSet creates pods with a stable, ordinal hostname based on the pattern `<statefulset-name>-<ordinal>`. The second pod (index 1) is named `web-1`. When a headless Service (named `web`) is associated with the StatefulSet, each pod gets a DNS A record in the form `<pod-name>.<service-name>.<namespace>.svc.cluster.local`.

Therefore, the correct DNS name is `web-1.web.default.svc.cluster.local`.

Exam trap

The trap here is that candidates often forget the Service name must appear between the pod name and namespace, or they confuse the ordinal index (starting at 0) with the replica count, leading them to pick `web-2` for the second pod.

How to eliminate wrong answers

Option B is wrong because it uses `web-2`, which corresponds to the third pod (index 2), not the second pod (index 1). Option C is wrong because it omits the pod-specific ordinal prefix (`web-1`), resolving to the Service's DNS name rather than an individual pod's DNS name. Option D is wrong because it omits the Service name (`web`) between the pod name and namespace, which is required for the StatefulSet pod DNS format.

93
MCQhard

You want to enforce a Pod Security Standard of 'restricted' in a namespace. Which command applies the correct label?

A.kubectl label namespace my-ns psp=restricted
B.kubectl label namespace my-ns pod-security.kubernetes.io/enforce=restricted
C.kubectl annotate namespace my-ns pod-security.kubernetes.io/enforce=restricted
D.kubectl label namespace my-ns pod-security.kubernetes.io/audit=restricted
AnswerB

This is the correct syntax because the PodSecurity admission controller reads the pod-security.kubernetes.io/enforce label to determine the enforced level for the namespace. Setting it to 'restricted' makes the controller reject every pod that does not conform to the Restricted Pod Security Standard, including privileged containers, host namespaces, or missing seccomp profiles. The label must be placed on the namespace, and the controller evaluates it at pod admission time, failing API requests that violate the policy.

Why this answer

Pod Security Standards are enforced by applying a label with the key `pod-security.kubernetes.io/enforce` to a namespace. The value `restricted` sets the most restrictive Pod Security Standard, which prevents pods from running with privileged access or insecure capabilities. This label is part of the built-in Pod Security Admission (PSA) controller, which replaced PodSecurityPolicy in Kubernetes v1.23+.

Exam trap

The trap here is that candidates confuse the deprecated PodSecurityPolicy (PSP) label key `psp` with the correct Pod Security Admission label key `pod-security.kubernetes.io/enforce`, or they mistakenly use `annotate` instead of `label` because both commands can attach metadata to resources.

How to eliminate wrong answers

Option A is wrong because the label key `psp` is not a valid Pod Security Standard label; it references the deprecated PodSecurityPolicy (PSP) feature, which is removed in Kubernetes v1.25. Option C is wrong because `kubectl annotate` adds an annotation, not a label, and Pod Security Standards are enforced via labels, not annotations. Option D is wrong because the label key `pod-security.kubernetes.io/audit` sets the audit level, which only logs violations without blocking them; the enforce level requires the key `pod-security.kubernetes.io/enforce`.

94
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.

95
MCQmedium

You want to restrict total memory usage in a namespace to 10 Gi. Which resource should you create?

A.ResourceQuota
B.PodDisruptionBudget
C.LimitRange
D.NetworkPolicy
AnswerA

A ResourceQuota is an admission controller resource that sets a hard ceiling on aggregate resource usage in a namespace. By configuring spec.hard.requests.memory to 10Gi, the Kubernetes API server sums the memory requests of all existing and newly created Pods in that namespace and rejects any new Pod that would push the total over 10Gi. This directly satisfies the requirement to restrict total memory usage across all Pods in the namespace.

Why this answer

A ResourceQuota is the correct Kubernetes object to enforce aggregate resource consumption limits at the namespace level. By defining a ResourceQuota with `spec.hard.memory: 10Gi`, you restrict the total memory requested and used by all pods in that namespace to 10 GiB. This directly meets the requirement to limit total memory usage.

Exam trap

CNCF often tests the distinction between per-container limits (LimitRange) and aggregate namespace limits (ResourceQuota), leading candidates to mistakenly choose LimitRange when the question explicitly asks for total namespace-wide restrictions.

How to eliminate wrong answers

Option B is wrong because a PodDisruptionBudget (PDB) controls the minimum number of available pods during voluntary disruptions (e.g., node drains), not resource usage limits. Option C is wrong because a LimitRange sets per-container default and minimum/maximum resource constraints, not an aggregate namespace-wide limit. Option D is wrong because a NetworkPolicy governs ingress/egress traffic rules using labels and CIDR blocks, not memory or CPU restrictions.

96
MCQhard

An Ingress has two rules: - host: app.example.com, path: /api -> service-a:80 - host: api.example.com, path: / -> service-b:80 A request to `app.example.com/api/v1` reaches which service?

A.Both services
B.Neither service
C.service-a
D.service-b
AnswerC

service-a is correct: the ingress rule for host app.example.com with path /api uses Prefix path matching, and the request URL /api/v1 begins with /api, so the path condition is satisfied. Since the Host header also matches app.example.com, the controller forwards the request to service-a. No other rule has both matching host and path.

Why this answer

Ingress rules match the longest prefix of the request path for the given host. For `app.example.com/api/v1`, the path `/api` is a prefix match (since `/api/v1` starts with `/api`), so it routes to service-a:80. The second rule requires host `api.example.com`, which does not match, so service-b is not considered.

Exam trap

The trap here is that candidates assume path matching requires an exact match (e.g., `/api` only matches `/api`, not `/api/v1`), but Kubernetes Ingress uses prefix matching by default, so `/api` matches any path starting with `/api`.

How to eliminate wrong answers

Option A is wrong because only one host matches the request; a request cannot be routed to both services simultaneously. Option B is wrong because the request does match the first rule's host and path prefix, so it reaches a service. Option D is wrong because the host `api.example.com` does not match `app.example.com`, so service-b is never selected.

97
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.

98
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.

99
MCQhard

You are asked to ensure that a pod with a slow-starting container (requires 60 seconds to initialize) is not prematurely restarted by the liveness probe. The liveness probe should start only after the container is fully initialized. Which probe type should you add to the pod spec?

A.startupProbe
B.readinessProbe
C.livenessProbe with initialDelaySeconds=60
D.lifecycle preStop hook
AnswerA

A startupProbe is the only probe type designed for slow-starting containers; it runs repeatedly until the process signals it has initialized successfully. Kubelet disables liveness and readiness probes until this probe succeeds, so the container gets unlimited (or configured) attempts to start without being killed. You can set a large failureThreshold with short periodSeconds to allow a long but controlled startup window.

Why this answer

A startupProbe is specifically designed for slow-starting containers. It runs at pod startup and only after it succeeds does the liveness probe begin. This prevents the liveness probe from restarting the container during its 60-second initialization period, as the startupProbe will keep failing until the container is fully ready.

Exam trap

CNCF often tests the misconception that initialDelaySeconds on a liveness probe is sufficient for slow-starting containers, but the trap is that initialDelaySeconds is a fixed delay that does not account for variable startup times, whereas a startupProbe dynamically waits until the container is actually ready.

How to eliminate wrong answers

Option B is wrong because a readinessProbe controls whether the pod receives traffic, not whether the container is restarted; it does not prevent the liveness probe from killing the container during initialization. Option C is wrong because initialDelaySeconds only delays the first liveness probe check by 60 seconds, but if the container takes exactly 60 seconds to initialize and the probe fires immediately after, a single slow response could still trigger a restart; moreover, initialDelaySeconds is a static delay and does not adapt to variable startup times. Option D is wrong because a lifecycle preStop hook runs before a container is terminated, not at startup, and has no effect on preventing premature restarts during initialization.

100
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`.

101
MCQmedium

You create a Service with the following YAML: ``` apiVersion: v1 kind: Service metadata: name: my-service spec: ports: - name: http port: 80 targetPort: 8080 selector: app: my-app ``` What is the default Service type?

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

ClusterIP is the default Service type in Kubernetes. When you create a Service without specifying the `type` field, the Kubernetes API server automatically assigns a cluster-internal virtual IP (ClusterIP) that is only reachable from within the cluster. This provides a stable endpoint for pod-to-pod communication and internal load balancing without exposing the Service externally, aligning with the principle of least privilege.

Why this answer

When no `type` field is specified in a Service YAML, Kubernetes defaults to `ClusterIP`. This assigns a stable internal IP address reachable only within the cluster, enabling pod-to-pod communication without external exposure. The `spec.type` field is optional, and `ClusterIP` is the implicit default.

Exam trap

The trap here is that candidates often assume `NodePort` is the default because it's commonly used in examples, but Kubernetes explicitly defaults to `ClusterIP` when no `type` is set.

How to eliminate wrong answers

Option A is wrong because `NodePort` is not the default; it requires explicit `type: NodePort` and exposes the service on a static port on every node's IP. Option C is wrong because `LoadBalancer` is not the default; it requires explicit `type: LoadBalancer` and provisions an external cloud load balancer, which also implies NodePort and ClusterIP. Option D is wrong because `ExternalName` is not the default; it requires explicit `type: ExternalName` and maps the service to a DNS name via CNAME, not to selectors or ports.

102
Multi-Selecteasy

A developer is creating a Deployment with 4 replicas. The application requires a rolling update with zero downtime. Which TWO strategies ensure zero downtime during an update?

Select 2 answers
A.Set maxSurge=1
B.Set maxUnavailable=1
C.Use Recreate strategy
D.Set maxUnavailable=0
E.Set maxSurge=0
AnswersA, D

Setting maxSurge=1 allows the deployment controller to create one additional pod beyond the desired 4 replicas before terminating any existing pods. This temporarily raises the total pod count to 5, ensuring that the running workload always has at least 4 available replicas throughout the rolling update. This strategy results in zero downtime as new pods become ready before old ones are removed.

Why this answer

Setting maxSurge=1 allows Kubernetes to spin up one new Pod before terminating any old Pod during a rolling update. This ensures that the total number of available Pods never drops below the desired replica count, maintaining service capacity and achieving zero downtime.

Exam trap

In Kubernetes, the trap here is that candidates often confuse maxSurge and maxUnavailable, thinking that allowing one Pod to be unavailable (maxUnavailable=1) is safe, but in a strict zero-downtime requirement, even a single unavailable Pod can cause capacity loss if the application cannot tolerate reduced replicas.

103
MCQmedium

A Deployment is configured with strategy type 'Recreate'. What happens during an update to the pod template?

A.Old pods are terminated and then new pods are created
B.New pods are created before old ones are terminated
C.Pods are updated in place
D.The update is paused until manual approval
AnswerA

When a Deployment's strategy is set to Recreate, the controller first scales the current ReplicaSet to zero, ensuring every old pod has terminated gracefully, and only then creates the new ReplicaSet and starts new pods. This eliminates any overlap between old and new versions, guaranteeing that no mixed-version traffic can occur, but it also means the application experiences full downtime during the transition. The ordering is strictly linear: the old pods must be gone before the new pods appear.

Why this answer

The Recreate strategy first terminates all existing pods, then creates new pods. This ensures that only one version is running at a time, but causes downtime.

104
MCQeasy

You need to perform a rolling update of a Deployment named 'web-app' with a new image version. Which command should you use?

A.kubectl edit deployment web-app
B.kubectl replace -f web-app.yaml
C.kubectl set image deployment/web-app app=nginx:1.21
D.kubectl rollout restart deployment/web-app
AnswerC

kubectl set image deployment/web-app app=nginx:1.21 changes the container named app in the Deployment web-app to use the nginx:1.21 image, directly altering the pod template of the Deployment. This triggers a rolling update by creating a new ReplicaSet and scaling it up while scaling down the old one, honoring maxSurge and maxUnavailable. It is the concise, imperative command explicitly designed for this image-update operation.

Why this answer

The 'kubectl set image' command is used to update the container image of a Deployment, triggering a rolling update. In this case, 'kubectl set image deployment/web-app app=nginx:1.21' updates the container named 'app' to the new image version. Options A, B, and D are incorrect: A requires editing the manifest interactively, B replaces the entire resource definition, and D restarts pods without changing the image.

105
MCQmedium

An admin wants to expose a Service only for internal cluster communication, without external access. Which Service type should they use?

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

The ClusterIP type assigns a stable virtual IP from the Service CIDR that is reachable only from within the cluster. kube-proxy programs iptables or IPVS rules on every node to load-balance traffic to the backing pods, and the Service DNS name resolves to this internal IP. Since no host network path or external load balancer is involved, it remains isolated from traffic outside the cluster and is the default choice for internal-only services.

Why this answer

ClusterIP is the default Kubernetes Service type and exposes the Service on a cluster-internal IP address, making it reachable only from within the cluster. This is the correct choice for internal cluster communication because no external endpoints are created, and traffic is routed via kube-proxy using iptables or IPVS rules.

Exam trap

The CKAD exam often tests the misconception that ClusterIP is only for default or unspecified use, leading candidates to choose NodePort or LoadBalancer for 'internal' scenarios, but the trap here is that ClusterIP is explicitly designed for internal-only access and is the only type that does not expose the Service externally by default.

How to eliminate wrong answers

Option A is wrong because ExternalName maps a Service to a DNS name (e.g., an external hostname) via CNAME records, which is used for external access, not internal-only communication. Option B is wrong because NodePort exposes the Service on each node's IP at a static port (30000-32767), allowing external traffic to reach the Service from outside the cluster. Option C is wrong because LoadBalancer provisions an external cloud load balancer (e.g., AWS ELB, GCP LB) with a public IP, explicitly enabling external access.

106
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.

107
MCQmedium

You want to ensure your containerized application handles SIGTERM gracefully and shuts down within 30 seconds. Which field should you set in the Pod spec?

A.terminationPeriodSeconds
B.terminationGracePeriodSeconds
C.shutdownTimeoutSeconds
D.gracefulShutdownPeriod
AnswerB

terminationGracePeriodSeconds is the correct PodSpec field that sets the time allotted for a container to shut down gracefully. After the kubelet sends SIGTERM to the primary process, it waits this many seconds before sending SIGKILL to force termination. The default value is 30 seconds, and you can override it per deletion request with kubectl delete --grace-period.

Why this answer

`terminationGracePeriodSeconds` is the Pod spec field that controls the duration Kubernetes waits between sending a SIGTERM signal to the container and forcibly killing it with SIGKILL. Setting this to 30 seconds ensures the application has up to 30 seconds to perform cleanup and shut down gracefully after receiving SIGTERM.

Exam trap

The trap here is that candidates confuse the generic concept of a 'grace period' with the exact Kubernetes field name, often picking a plausible-sounding but non-existent field like `shutdownTimeoutSeconds` or `gracefulShutdownPeriod` instead of the precise `terminationGracePeriodSeconds`.

How to eliminate wrong answers

Option A is wrong because `terminationPeriodSeconds` is not a valid Kubernetes field; the correct field name is `terminationGracePeriodSeconds`. Option C is wrong because `shutdownTimeoutSeconds` is not a Kubernetes Pod spec field; it does not exist in the API. Option D is wrong because `gracefulShutdownPeriod` is not a Kubernetes Pod spec field; it is a generic term that might be used in other orchestrators or application configurations, but not in Kubernetes.

108
MCQmedium

You have a Helm release named 'my-app' that you want to revert to revision 3. Which command accomplishes this?

A.helm undo my-app --revision 3
B.helm rollback my-app 3
C.helm revert my-app 3
D.helm upgrade my-app --revision 3
AnswerB

The `helm rollback my-app 3` command is the valid way to revert the release to revision 3. Helm will take the chart manifest and values stored at revision 3, apply them to the cluster, and then record a new revision number (for example, revision 5 if the current is 4) to preserve the ability to later roll forward or back. This is the canonical command for undoing a bad upgrade and it works exactly as written, with the release name and target revision as positional arguments.

Why this answer

The correct command to revert a Helm release to a previous revision is `helm rollback <release-name> <revision>`. In this case, `helm rollback my-app 3` will roll back the 'my-app' release to revision 3, restoring the Kubernetes resources to the state defined in that revision's chart and values.

Exam trap

The trap here is that candidates may confuse `helm rollback` with other verbs like `undo` or `revert` that exist in other tools (e.g., Git), or assume `helm upgrade` can target a specific revision, when in fact only `helm rollback` is the correct command for this operation.

How to eliminate wrong answers

Option A is wrong because `helm undo` is not a valid Helm command; the correct verb is `rollback`. Option C is wrong because `helm revert` is not a valid Helm command; the correct verb is `rollback`. Option D is wrong because `helm upgrade --revision` is not a valid flag; `helm upgrade` is used to install a new version of a chart, not to revert to a previous revision, and the `--revision` flag is not supported for that purpose.

109
MCQhard

An admin creates a Service without a selector. Which of the following is true about such a Service?

A.The Service will use the default ClusterIP and route to all pods in the cluster.
B.The Service will automatically route traffic to all pods in the namespace.
C.The admin must manually create an Endpoints object with the desired IPs.
D.The Service will not have any endpoints until a selector is added.
AnswerC

This is correct because a Service without a selector needs a separately-created Endpoints object to define the backend IP addresses and ports. The admin can create an Endpoints resource with the same name as the Service, listing the IPs and port numbers where traffic should be forwarded. This pattern is commonly used to route to external databases, legacy systems, or services outside the cluster. Once the Endpoints exist, the Service becomes routable.

Why this answer

When a Service is created without a selector, Kubernetes does not automatically manage its endpoints. The admin must manually create an Endpoints object (or use an EndpointSlice) that lists the IP addresses and ports to which the Service should route traffic. This allows the Service to direct traffic to external resources, such as databases running outside the cluster, or to specific pods not matching a label selector.

Exam trap

The trap here is that candidates often assume a Service must have a selector to function, but Kubernetes allows headless or manually-endpointed Services, and the exam tests whether you know that endpoints can be created independently of selectors.

How to eliminate wrong answers

Option A is wrong because a Service without a selector does not use a default ClusterIP to route to all pods; it has no automatic endpoint management and requires manual endpoint configuration. Option B is wrong because the Service does not automatically route traffic to all pods in the namespace; without a selector, no pods are automatically associated, and traffic only goes to manually defined endpoints. Option D is wrong because the Service can have endpoints immediately if the admin creates a corresponding Endpoints object; endpoints are not dependent on a selector being added later.

110
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.

111
Multi-Selecthard

Which THREE statements about NetworkPolicy are correct? (Select 3)

Select 3 answers
A.NetworkPolicy follows an allow-list model; if no policy matches, traffic is denied.
B.NetworkPolicy can block traffic to specific external IP addresses using ipBlock.
C.NetworkPolicy can use namespaceSelector to allow traffic from all pods in a namespace.
D.NetworkPolicy is a cluster-scoped resource.
E.NetworkPolicy can restrict egress traffic from pods.
AnswersA, C, E

Correct. In the Kubernetes NetworkPolicy model, a pod that is selected by any policy is isolated: all traffic that does not match an explicit allow rule is denied. This is an allow-list (whitelist) approach, meaning policies never add 'block' rules—they only declare allowed traffic. The apparent contradiction with the default allow-all behavior for unselected pods actually confirms the rule: isolation, and therefore default deny, only starts when at least one policy matches the pod.

Why this answer

NetworkPolicy follows an allow-list model: by default, all traffic to and from pods is allowed. Once a NetworkPolicy selects a pod, that pod becomes isolated, and only traffic explicitly allowed by the policy's rules is permitted for the specified direction (ingress/egress). Any traffic not matching an allow rule is denied for that direction.

Option A is correct because once a policy applies, the default behavior becomes deny for unmatched traffic. Option C is correct because namespaceSelector can select a namespace, allowing traffic from all pods in that namespace. Option E is correct because NetworkPolicy can restrict egress traffic via egress rules.

Option B is incorrect because ipBlock can be used to allow or block IP ranges, but blocking specific external IPs is possible only if the CNI supports it (and it's not universally supported). Option D is incorrect because NetworkPolicy is namespaced, not cluster-scoped.

Exam trap

A common pitfall in the CKAD exam is thinking NetworkPolicy is cluster-scoped (like a ClusterRole) or that it can block arbitrary external IPs without a CNI plugin that supports egress. Also, remember that by default all traffic is allowed; only when a policy selects a pod does the default become deny for the directions specified.

112
MCQeasy

What is the default Service type when creating a Service via 'kubectl create service' or YAML without specifying type?

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

Correct. ClusterIP is the default service type, assigned automatically when no `type` is specified. It provides a stable virtual IP address from the cluster's service CIDR, which is reachable only from within the cluster, enabling pod-to-pod communication and service discovery through the cluster's DNS.

Why this answer

When creating a Service via `kubectl create service` or defining it in YAML without specifying the `type` field, Kubernetes defaults to `ClusterIP`. This is because `ClusterIP` is the implicit default type defined in the Service spec, providing internal cluster-wide virtual IP-based load balancing without external exposure.

Exam trap

The trap here is that candidates often assume `NodePort` is the default because it is commonly used in examples or because `kubectl expose` defaults to `ClusterIP` only when no `--type` flag is provided, but `kubectl create service` without `--tcp` or `--type` also defaults to `ClusterIP` — the CKAD exam tests this subtle distinction to catch those who confuse `kubectl expose` behavior with the YAML default.

How to eliminate wrong answers

Option A is wrong because `NodePort` is not the default; it must be explicitly set via `type: NodePort` or by using `kubectl expose` with `--type=NodePort`. Option B is wrong because `ExternalName` is a special type that maps a Service to a DNS name via the `externalName` field and is never a default. Option C is wrong because `LoadBalancer` requires an external cloud provider integration and must be explicitly specified; it is not the default type.

113
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.

114
MCQmedium

You have a Deployment running a web application that takes 60 seconds to start up. You need to configure probes so that Kubernetes waits for the application to fully start before checking its health and directing traffic to it. Which combination of probes should you use?

A.Liveness probe with initialDelaySeconds=10 and readiness probe without delay
B.Readiness probe with initialDelaySeconds=60 only
C.Liveness probe with initialDelaySeconds=60 and readiness probe with initialDelaySeconds=60
D.Startup probe with failureThreshold=30 and periodSeconds=2, plus liveness and readiness probes
AnswerD

A startup probe with failureThreshold=30 and periodSeconds=2 gives the container up to 60 seconds to become ready (30 failures × 2 seconds). The kubelet runs the startup probe first, and only after it succeeds do the liveness and readiness probes begin executing. This cleanly separates the startup phase from steady-state health checking, preventing premature liveness restarts without limiting the app's startup time to a hard-coded initialDelay. Once the startup probe passes, the liveness probe takes over to restart the container if it later becomes unhealthy, while the readiness probe controls traffic admission.

Why this answer

A startup probe with a low failureThreshold and periodSeconds allows Kubernetes to wait up to 60 seconds (30 failures × 2 seconds) for the application to start, after which the liveness and readiness probes begin. This ensures the liveness probe does not kill the container prematurely during the slow startup, and the readiness probe only directs traffic once the app is fully ready.

Exam trap

The trap here is that candidates often rely solely on initialDelaySeconds for liveness probes, not realizing that a startup probe provides a more robust mechanism for slow-starting containers by decoupling the startup grace period from the regular health-check cycle.

How to eliminate wrong answers

Option A is wrong because a liveness probe with initialDelaySeconds=10 would start checking health after only 10 seconds, likely killing the container before the 60-second startup completes. Option B is wrong because a readiness probe with initialDelaySeconds=60 alone does not protect against the liveness probe killing the container during startup; the liveness probe would still start immediately and fail. Option C is wrong because setting both liveness and readiness probes with initialDelaySeconds=60 still allows the liveness probe to start after 60 seconds, but if the app takes exactly 60 seconds, the first liveness check might fail and restart the container; a startup probe provides a more flexible grace period.

115
MCQmedium

You have a Deployment named 'frontend' with 4 replicas. You want to perform a rolling update with the following constraints: the number of pods above the desired count should never exceed 1, and the number of unavailable pods should never exceed 0. Which deployment strategy configuration achieves this?

A.strategy: rollingUpdate: {maxSurge: 2, maxUnavailable: 0}
B.strategy: rollingUpdate: {maxSurge: 25%, maxUnavailable: 25%}
C.strategy: rollingUpdate: {maxSurge: 1, maxUnavailable: 0}
D.strategy: type: Recreate
AnswerC

This is the correct configuration because maxSurge: 1 caps the total number of pods at one beyond the desired 4, so at most 5 pods run during the update. Meanwhile, maxUnavailable: 0 forbids terminating any old pod until a new pod has become Ready, ensuring at least 4 pods are always available to serve traffic. Together they enforce exactly the stated constraints: no more than one extra pod and zero downtime.

Why this answer

Setting `maxSurge: 1` ensures that during a rolling update, at most one additional pod is created above the desired replica count of 4, and `maxUnavailable: 0` guarantees that no pods are taken down until the new ones are ready. This satisfies the constraints of never exceeding one extra pod and never having unavailable pods.

Exam trap

The trap here is that candidates often confuse `maxSurge` and `maxUnavailable` as percentages versus absolute values, or they mistakenly think `Recreate` can achieve zero downtime, when in fact it causes complete unavailability during the update.

How to eliminate wrong answers

Option A is wrong because `maxSurge: 2` would allow up to 2 extra pods above the desired count, violating the constraint that the number of pods above the desired count should never exceed 1. Option B is wrong because `maxUnavailable: 25%` (which equals 1 pod out of 4) would allow at least one pod to be unavailable during the update, violating the constraint that unavailable pods should never exceed 0. Option D is wrong because the `Recreate` strategy terminates all existing pods before creating new ones, causing all pods to be unavailable during the update, which directly violates the constraint of zero unavailable pods.

116
MCQhard

A developer wants to run a container as a non-root user and prevent it from gaining additional privileges. The container image runs as root by default. Which securityContext configuration should be applied to the container to achieve this?

A.securityContext: { runAsUser: 1000, privileged: true }
B.securityContext: { runAsGroup: 1000, allowPrivilegeEscalation: true }
C.securityContext: { runAsNonRoot: true, privileged: false }
D.securityContext: { runAsUser: 1000, allowPrivilegeEscalation: false }
AnswerD

Setting runAsUser: 1000 ensures the container process runs as a non-root user. allowPrivilegeEscalation: false prevents the process from gaining more privileges than its parent (e.g., via setuid or setgid binaries). Together, these satisfy the requirements. This is a common best practice for hardening container security.

Why this answer

To run as a non-root user, runAsUser must be set to a non-zero UID. To prevent privilege escalation, allowPrivilegeEscalation must be false. The combination of runAsUser: 1000 and allowPrivilegeEscalation: false achieves both goals.

Other options either fail to set a non-root user, enable privilege escalation, or rely on runAsNonRoot without specifying a UID.

Exam trap

The trap here is thinking that runAsNonRoot alone is sufficient, or that privileged: false prevents privilege escalation, when actually allowPrivilegeEscalation is the specific control.

117
MCQmedium

During a rolling update of a Deployment with 10 replicas, you set maxSurge to 3 and maxUnavailable to 2. What is the maximum number of pods that can be unavailable during the update?

A.5
B.3
C.2
D.10
AnswerC

The maxUnavailable field directly specifies the maximum number of pods that can be unavailable during a rolling update relative to the desired replica count. With maxUnavailable set to 2, the Deployment controller will ensure that at least 8 of the 10 original pods remain available at any time. Therefore, the maximum number of unavailable pods is exactly 2.

Why this answer

maxUnavailable: 2 means at most 2 pods can be unavailable. Option C is correct.

118
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.

119
MCQmedium

A HorizontalPodAutoscaler (HPA) is configured to scale a Deployment based on CPU utilization. The target CPU utilization percentage is set to 80%. The current CPU utilization is 90%. What will the HPA do?

A.Delete the pod with the highest CPU usage
B.Scale up the number of replicas
C.Do nothing because 90% is within acceptable range
D.Scale down the number of replicas
AnswerB

The HPA calculates the desired replicas using the formula desiredReplicas = ceil(currentReplicas * (currentMetric / targetMetric)). With current average CPU at 90% and target at 80%, the ratio is 1.125, so the HPA will increase the replica count to spread traffic and reduce per-pod CPU utilization back toward 80%. This is the only response aligned with the HPA's design, as scaling out dilutes workload across more pods and brings the metric within the target threshold.

Why this answer

The HPA will increase the number of replicas to bring CPU utilization down towards 80%. The exact new replicas depends on the metric, but generally it scales up.

120
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.

121
Multi-Selectmedium

Which THREE of the following are valid parameters for a probe?

Select 3 answers
A.maxRetries
B.initialDelaySeconds
C.timeoutSeconds
D.backoffSeconds
E.periodSeconds
AnswersB, C, E

This is a valid parameter in the Kubernetes probe specification. It sets the number of seconds the kubelet waits after the container starts before performing the first probe, giving the application time to initialize. Properly setting this value is critical for liveness probes to avoid restarting containers that are still starting up.

Why this answer

`initialDelaySeconds` is a valid field in a Kubernetes probe specification that defines the number of seconds to wait before initiating the first probe after the container starts. This allows the application time to initialize before health checks begin, preventing premature failures.

Exam trap

The trap here is that candidates confuse Kubernetes probe parameters with similar concepts from other systems (e.g., retry logic or backoff strategies) and assume `maxRetries` or `backoffSeconds` are valid, when in fact Kubernetes uses `failureThreshold` and fixed-interval polling instead.

122
MCQeasy

A Service uses a selector to target Pods. After updating the Pod labels, you notice the endpoints list is empty. What is the most likely reason?

A.The Service port was changed
B.The new labels do not match the Service selector
C.The Service type changed to ExternalName
D.The Pods have a different container port
AnswerB

The Service's selector is a label query that must exactly match the labels present on the pod's metadata, and the endpoints controller is continuously reconciling based on that query. Once the pods' labels are updated and no longer satisfy all key-value pairs in the selector, the controller removes the pod IPs from the Endpoints object, leaving the Service with zero ready endpoints. This is the classic cause of connection failures after a deployment label change, even when all pods are Running and Ready.

Why this answer

A Service uses a label selector to dynamically discover Pods and populate its endpoints. When Pod labels are updated, the selector remains unchanged; if the new labels do not match the selector, the Service cannot find any matching Pods, resulting in an empty endpoints list. This is the most direct and common cause of the issue.

Exam trap

The trap here is that candidates often assume updating Pod labels will automatically update the Service's endpoint list, but they forget that the Service selector must explicitly match the new labels for endpoints to be populated.

How to eliminate wrong answers

Option A is wrong because changing the Service port would affect connectivity but not the endpoints list; endpoints are populated based on label matching, not port values. Option C is wrong because changing the Service type to ExternalName would remove the selector entirely and use a DNS CNAME instead, but the question states the selector is still used and the endpoints list is empty, not that the Service type changed. Option D is wrong because a different container port does not prevent label matching; the Service selector targets Pods by labels, and the container port is only relevant for routing traffic after the Pod is selected.

123
MCQhard

A cluster administrator wants to enforce that no pod in namespace 'prod' uses more than 4Gi of memory. Which Kubernetes resource should be created?

A.PodDisruptionBudget
B.NetworkPolicy
C.LimitRange
D.ResourceQuota
AnswerC

A LimitRange is a namespace-scoped resource that defines minimum, maximum, and default values for CPU and memory requests and limits per container or pod. Setting a max limit in a LimitRange ensures that any pod that declares a memory limit exceeding that maximum is rejected during admission control. It also can set default requests/limits for pods that do not specify them, giving the administrator direct control over per-pod resource bounds.

Why this answer

A LimitRange resource in the 'prod' namespace can set a default memory limit and a maximum memory limit per container or pod, enforcing that no pod exceeds 4Gi of memory. This is the appropriate Kubernetes primitive for per-pod resource constraints within a namespace, as it applies to all pods that do not specify their own limits.

Exam trap

The trap here is confusing ResourceQuota (namespace-level aggregate limits) with LimitRange (per-pod/per-container limits), leading candidates to select D when the question explicitly asks for per-pod enforcement.

How to eliminate wrong answers

Option A is wrong because a PodDisruptionBudget is used to define the minimum number of replicas that must be available during voluntary disruptions (e.g., node drains), not to enforce memory limits. Option B is wrong because a NetworkPolicy controls ingress and egress traffic between pods based on labels and ports, not resource usage. Option D is wrong because a ResourceQuota sets aggregate resource consumption limits for the entire namespace (e.g., total memory across all pods), not per-pod maximums, and cannot prevent a single pod from using more than 4Gi.

124
Multi-Selectmedium

Which TWO of the following are valid types of probes in Kubernetes? (Select 2)

Select 2 answers
A.Readiness probe
B.HTTP probe
C.Liveness probe
D.Exec probe
E.TCP probe
AnswersA, C

Readiness probes are a first-class probe type that tells the kubelet when a container is ready to begin accepting traffic. If the probe fails, the Pod's IP is removed from the endpoints of all Services, but the container is not terminated or restarted. This allows the container to remain running while it load-balances nothing, making it distinct from liveness probes which restart containers. The assignment of readiness is crucial for rolling updates to avoid sending requests to Pods still starting up.

Why this answer

A is correct because a Readiness probe determines whether a Pod is ready to serve traffic. If the probe fails, the Pod is removed from the Service's endpoints, preventing traffic from being routed to an unready container. This is essential for rolling updates and graceful shutdowns.

Exam trap

The trap here is that candidates confuse the probe types (liveness, readiness, startup) with the handler mechanisms (HTTP, TCP, exec), leading them to select handler names as if they were probe types.

125
MCQmedium

You run 'kubectl port-forward pod/my-pod 8080:80'. What does this command do?

A.Exposes the pod on port 8080 on each node's IP
B.Forwards local port 8080 to port 80 on the pod
C.Forwards local port 8080 to port 80 on the Service
D.Creates a Service that maps port 8080 to port 80 on the pod
AnswerB

This is precisely what the command does: it opens a local TCP listener on port 8080 (typically on 127.0.0.1) and forwards every connection to port 80 on the pod named mypod. The kubectl binary acts as a client that establishes a connection to the Kubernetes API server, which then proxies a bidirectional stream to the requested port on the pod. This is a convenient way to reach a pod that is not exposed by a Service, without altering the cluster state.

Why this answer

`kubectl port-forward pod/my-pod 8080:80` creates a tunnel from localhost:8080 on your client machine to port 80 on the specified pod. This command does not expose the pod to the network; it only provides a direct, temporary connection for debugging or accessing a specific pod without a Service.

Exam trap

The trap here is that candidates confuse `kubectl port-forward` with `kubectl expose` or a NodePort Service, thinking it makes the pod accessible externally, when in fact it only forwards traffic from a local port to the pod on the client machine.

How to eliminate wrong answers

Option A is wrong because `kubectl port-forward` does not expose the pod on each node's IP; it only binds to localhost (127.0.0.1) by default, not to node IPs. Option C is wrong because the command targets a pod directly (`pod/my-pod`), not a Service; forwarding to a Service would require a different syntax like `service/my-service`. Option D is wrong because `kubectl port-forward` does not create any Kubernetes resource; it is a client-side operation that establishes a temporary tunnel, not a persistent Service object.

126
Multi-Selectmedium

Which THREE of the following are valid fields in a Pod's container spec for resource management? (Choose three.)

Select 3 answers
A.resources.limits.ephemeral-storage
B.resources.requests.cpu
C.resources.limits.memory
D.resources.requests.gpu
E.resources.requests.storage
AnswersA, B, C

resources.limits.ephemeral-storage is a valid field in a container's resources block because ephemeral-storage is one of Kubernetes' three built-in basic resource types, alongside cpu and memory. It caps the amount of local scratch space (e.g., emptyDir volumes, container logs, and image layers) a container may consume, protecting node stability from runaway disk usage. Unlike persistent storage, this quota applies to the pod/container's usage of the node's local ephemeral storage, making it a legitimate resource field under resources.limits.

Why this answer

`ephemeral-storage` is a valid resource type in Kubernetes that can be specified under `resources.limits` to control the maximum temporary storage a container can use, preventing pods from exhausting node storage. This is defined in the Kubernetes resource model and is commonly used for scratch space or logs.

Exam trap

The trap here is that candidates often confuse `resources.requests.storage` with `PersistentVolumeClaim` storage requests, or assume `gpu` is a built-in resource like CPU or memory, when in fact Kubernetes only natively supports CPU and memory as core resources, with extended resources requiring explicit configuration.

127
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.

128
Multi-Selectmedium

Which THREE of the following are benefits of using a ResourceQuota in a namespace? (Select THREE)

Select 3 answers
A.It sets default resource requests and limits for Pods that don't specify them
B.It can enforce that every Pod has resource limits set
C.It restricts which users can create Pods in the namespace
D.It prevents a single namespace from exhausting cluster resources
E.It limits the total amount of CPU and memory that can be consumed by all Pods in the namespace
AnswersB, D, E

By declaring `limits.cpu` and `limits.memory` in the quota's `hard` map, the namespace is forced to have every Pod set these fields explicitly. The quota admission controller rejects any Pod whose PodSpec does not include a CPU and memory limit, regardless of the actual values. This guarantees that no Pod can run unbounded, although it does not enforce a particular limit size; a LimitRange or individual Pod spec sets the actual numbers.

Why this answer

Option B is correct because a ResourceQuota can include the key limits.cpu and limits.memory (or requests.cpu/requests.memory), which forces every Pod in the namespace to declare matching resource limits or requests—otherwise the Pod is rejected at admission time. Option D is correct because by capping aggregate CPU, memory, storage, and object counts per namespace, ResourceQuota stops one namespace from consuming the entire cluster's capacity and starving other tenants. Option E is correct because ResourceQuota tracks the sum of requests/limits across all Pods in the namespace and denies any new Pod that would push the total past the configured CPU or memory ceiling.

Option A is not correct because setting default requests and limits is the job of a LimitRange, not a ResourceQuota. Option C is not correct because restricting which users can create Pods is handled by RBAC (Roles/RoleBindings) or admission policies, not by ResourceQuota.

Exam trap

The trap here is that candidates often confuse the purpose of a ResourceQuota with a LimitRange, mistakenly thinking a ResourceQuota sets default resource requests/limits, when in fact that is exclusively a LimitRange feature.

129
Multi-Selectmedium

Which TWO statements about readiness probes are correct? (Choose two.)

Select 2 answers
A.Readiness probes are only used during initial startup
B.Readiness probes run continuously after the container starts
C.Readiness probes can only be of type httpGet
D.Readiness probes restart the container if they fail
E.If a readiness probe fails, the pod is removed from all Service endpoints
AnswersB, E

This statement is correct because a readiness probe is a recurring health check, not a one-time gate. The kubelet executes it every periodSeconds once the container is running, even after the pod has already become Ready. If the probe later fails, the pod is marked NotReady and traffic is withdrawn; if it passes again, the pod is marked Ready and endpoints are restored.

Why this answer

Readiness probes are designed to run continuously throughout the lifecycle of a container, not just during startup. They are periodically executed by the kubelet to determine whether the container is ready to accept traffic, and their success or failure directly controls the pod's inclusion in Service endpoints.

Exam trap

The trap here is confusing readiness probes with liveness probes, leading candidates to incorrectly think readiness probes restart containers or are only used at startup, when in fact readiness probes manage traffic routing without restarting the pod.

130
MCQmedium

You have a Service named 'web' in namespace 'default'. Which DNS name resolves to the Service's ClusterIP?

A.web.default.cluster.local
B.web.default.svc.cluster.local
C.web.svc.cluster.local
D.web.default.pod.cluster.local
AnswerB

This is the fully qualified DNS name used by Kubernetes for any normal or headless Service in a given namespace, constructed as <service-name>.<namespace>.svc.<cluster-domain>. Here, 'web' is the Service name, 'default' is its namespace, and 'cluster.local' is the default cluster domain configured in CoreDNS. When a Pod connects to this name, the cluster's DNS resolver returns the Service's ClusterIP (or the pod IPs for a headless Service), making it the correct and standard address.

Why this answer

In Kubernetes, the DNS name for a Service follows the pattern `<service>.<namespace>.svc.cluster.local`. For a Service named 'web' in the 'default' namespace, the correct FQDN is `web.default.svc.cluster.local`. This resolves to the Service's ClusterIP, allowing pods to reach the service via a stable DNS name.

Exam trap

The CKAD exam often tests the exact DNS format for Services, and the trap here is that candidates may forget the `svc` subdomain or omit the namespace, leading them to choose options that look plausible but are missing a critical component.

How to eliminate wrong answers

Option A is wrong because `web.default.cluster.local` omits the required `svc` subdomain; the correct format includes `svc` to indicate it is a Service record. Option C is wrong because `web.svc.cluster.local` omits the namespace component; the namespace must be included to uniquely identify the Service. Option D is wrong because `web.default.pod.cluster.local` uses `pod` instead of `svc`, which is the subdomain for pod hostnames, not Service ClusterIP resolution.

131
MCQmedium

You need to temporarily access a pod's HTTP endpoint on port 8080 from your local machine. Which command should you use?

A.kubectl exec -it pod/my-pod -- curl http://localhost:8080
B.kubectl proxy --port=8080
C.kubectl attach pod/my-pod
D.kubectl port-forward pod/my-pod 8080:8080
AnswerD

kubectl port-forward pod/my-pod 8080:8080 correctly forwards localhost:8080 on your workstation to port 8080 on the pod. It establishes a tunnel through the Kubernetes API server, letting you access the pod's HTTP endpoint as if it were running locally, without requiring a Service or exposing the pod externally.

Why this answer

`kubectl port-forward` creates a direct tunnel from a local port to a pod's port, allowing you to access the pod's HTTP endpoint at `localhost:8080` from your local machine. This is the standard method for temporarily exposing a pod's network endpoint without creating a Service or modifying cluster networking.

Exam trap

The trap here is that candidates often confuse `kubectl port-forward` with `kubectl proxy` or `kubectl exec`, thinking that running a command inside the pod or proxying the API server will expose the pod's application port, when in fact only port-forward creates a direct local-to-pod TCP tunnel.

How to eliminate wrong answers

Option A is wrong because `kubectl exec` runs a command inside the container, not on your local machine; `curl http://localhost:8080` would attempt to connect to the container's loopback interface, which only works if the HTTP server is listening on 127.0.0.1, and it does not expose the endpoint to your local machine. Option B is wrong because `kubectl proxy` creates a proxy to the Kubernetes API server, not to a specific pod's port; it forwards to the API server's REST endpoints, not to the pod's HTTP service on port 8080. Option C is wrong because `kubectl attach` attaches to a running process's stdin/stdout/stderr inside a container, typically for interactive debugging, and does not provide network access to the pod's HTTP endpoint.

132
MCQmedium

When using 'kubectl apply' vs 'kubectl create', which statement is correct?

A.'kubectl create' will update a resource if it already exists
B.'kubectl apply' can create or update resources; 'kubectl create' only creates and fails if resource exists
C.'kubectl apply' and 'kubectl create' are interchangeable
D.'kubectl apply' can only create resources, not update them
AnswerB

kubectl apply operates declaratively: it sends the object configuration to the API server, which computes a difference between the desired state, the current live object, and the last-applied configuration, then issues a PATCH (or a POST if the resource does not exist). This allows apply to transparently create new resources and update existing ones in the same workflow. In contrast, kubectl create is imperative and always attempts to create a fresh resource per invocation; if the API server finds an existing object with the same identity, it returns an error instead of reconciling the object. Therefore, apply is suitable for both initial creation and ongoing updates, while create is intentionally limited to one-time creation where failure on duplicates is desirable.

Why this answer

'kubectl apply' uses a declarative approach that creates a resource if it does not exist and updates it if it does, while 'kubectl create' is imperative and will fail with an error if the resource already exists. This distinction is fundamental to Kubernetes resource management, where 'apply' manages the full object state via last-applied-configuration annotations, and 'create' only handles initial creation.

Exam trap

The trap here is that candidates often confuse 'kubectl apply' with 'kubectl replace' or assume 'kubectl create' can update resources, but the CKAD exam specifically tests the declarative vs imperative paradigm and the error behavior of 'create'.

How to eliminate wrong answers

Option A is wrong because 'kubectl create' does not update an existing resource; it returns an error (e.g., 'AlreadyExists') if the resource already exists. Option C is wrong because 'kubectl apply' and 'kubectl create' are not interchangeable; they have different behaviors for updates and error handling. Option D is wrong because 'kubectl apply' can both create and update resources, as it merges the provided configuration with the existing object's state.

133
MCQeasy

Which kubectl command is used to view the rollout history of a Deployment?

A.kubectl rollout history deployment my-deployment --revision=2
B.kubectl rollout list deployment my-deployment
C.kubectl rollout history deployment my-deployment
D.kubectl rollout status deployment my-deployment
AnswerC

`kubectl rollout history deployment my-deployment` is the canonical command to view a Deployment's rollout history. It lists all revisions, showing their revision numbers and change-cause annotations (if recorded), which gives you an overview of every template change. This is exactly what the question asks for, and it provides the foundation for rolling back to a specific revision.

Why this answer

`kubectl rollout history` is the dedicated command to view the revision history of a Deployment, including the list of revisions and, optionally, details of a specific revision when combined with `--revision`. This command directly queries the Deployment's rollout history stored in its annotations (e.g., `deployment.kubernetes.io/revision`).

Exam trap

A common mistake is confusing `kubectl rollout history` (viewing past revisions) with `kubectl rollout status` (viewing current rollout progress).

How to eliminate wrong answers

Option A is wrong because it includes `--revision=2`, which is a valid flag but not required to view the overall history; the question asks for the command to view the rollout history, and the base command without the revision flag is sufficient. Option B is wrong because `kubectl rollout list` is not a valid kubectl command; the correct subcommand for listing rollout history is `history`, not `list`. Option D is wrong because `kubectl rollout status` is used to check the current status of a rollout (e.g., whether it succeeded or is still progressing), not to view the historical record of revisions.

134
MCQmedium

Which field in the container spec controls the time Kubernetes waits after sending SIGTERM before sending SIGKILL during pod shutdown?

A.timeoutSeconds
B.periodSeconds
C.terminationGracePeriodSeconds
D.activeDeadlineSeconds
AnswerC

terminationGracePeriodSeconds is actually a Pod-level field in the pod spec, not a container-level field, and it controls the duration Kubernetes waits after sending SIGTERM to containers before forcefully sending SIGKILL. This grace period gives processes time to save state, close connections, and complete cleanup handlers. After the period elapses, the kubelet forcibly terminates any containers that have not exited, and overriding it on a per-container basis is impossible.

Why this answer

`terminationGracePeriodSeconds` is the field in the Pod spec that defines the duration Kubernetes waits after sending SIGTERM to the main process in each container before forcefully sending SIGKILL. This grace period allows the application to perform clean shutdown tasks, such as closing connections or flushing data. The default value is 30 seconds if not specified.

Exam trap

The trap here is that candidates confuse `terminationGracePeriodSeconds` with probe-related fields like `timeoutSeconds` or `periodSeconds`, or with Job-level fields like `activeDeadlineSeconds`, because all involve time-based configuration but serve entirely different purposes in the lifecycle of a Pod.

How to eliminate wrong answers

Option A is wrong because `timeoutSeconds` is not a valid field in the container spec; it is used in probes (e.g., livenessProbe, readinessProbe) to specify the timeout for probe execution, not for pod termination. Option B is wrong because `periodSeconds` is also a probe-related field that defines how often a probe is performed, not related to shutdown behavior. Option D is wrong because `activeDeadlineSeconds` is a field in the Job spec (not container spec) that limits the duration a Job can run before being terminated, and it applies to the Job's overall runtime, not the pod shutdown sequence.

135
MCQmedium

You have a Deployment named 'web-app' with 5 replicas. You want to perform a rolling update with a maximum of 2 extra pods during the update and allow at most 1 pod to be unavailable. Which YAML snippet correctly configures the rolling update strategy?

A.strategy: type: RollingUpdate rollingUpdate: maxSurge: 3 maxUnavailable: 0
B.strategy: type: RollingUpdate rollingUpdate: maxSurge: 1 maxUnavailable: 2
C.strategy: type: RollingUpdate rollingUpdate: maxSurge: "50%" maxUnavailable: "20%"
D.strategy: type: RollingUpdate rollingUpdate: maxSurge: 2 maxUnavailable: 1
AnswerD

This is the correct configuration: maxSurge=2 allows the Deployment to temporarily run up to 7 pods (5 desired + 2 extra), while maxUnavailable=1 guarantees that no more than 1 of the 5 desired replicas is unavailable, so at least 4 are always serving traffic. The controller first creates 2 new pods, then terminates old ones in a controlled manner, maintaining both the surge cap and availability floor. These values exactly match the requirement of allowing 2 extra pods and 1 unavailable pod during the update.

Why this answer

Ly sets maxSurge to 2 and maxUnavailable to 1. maxSurge: 2 allows up to 2 extra pods above the desired 5 replicas (total 7). maxUnavailable: 1 ensures at most 1 pod is unavailable during the update, meeting the requirement of allowing at most 1 unavailable pod.

136
MCQmedium

A CKAD candidate must make a container's exit code observable after a crash so that a monitoring agent reading pod status can distinguish an application error from an out-of-memory kill. The container has terminated and restarted several times. Which command shows the exit code and termination reason of the most recent terminated instance of the container?

A.kubectl get pod <pod> -o jsonpath='{.status.containerStatuses[*].lastState.terminated}'
B.kubectl describe node <node> | grep -i exit
C.kubectl logs <pod> --previous
D.kubectl get pod <pod> -o jsonpath='{.status.containerStatuses[*].state.running}'
AnswerA

The lastState.terminated object records the previous container instance, including its exitCode, reason, and signal. Querying it with jsonpath returns exactly the diagnostic data the monitoring agent needs, allowing a reason of OOMKilled to be separated from a generic Error exit code without inspecting node-level logs or restarting anything.

Why this answer

Container termination facts are persisted on the pod's status under containerStatuses, where lastState.terminated holds the exitCode, reason, and timing of the previous instance. Extracting that subtree with jsonpath or a custom-columns output gives the monitoring agent the precise reason value, such as OOMKilled, that distinguishes a memory kill from an ordinary application failure. Logs and node descriptions do not carry this structured field.

Exam trap

The trap here is reaching for kubectl logs --previous when the requested datum is a structured exit code that only exists in pod status.

137
MCQhard

A StatefulSet is deployed with a headless service (clusterIP: None). The pods are named 'web-0', 'web-1', 'web-2'. What DNS name resolves to the specific IP of 'web-1'?

A.web-1.web.default.svc.cluster.local
B.web-1.default.svc.cluster.local
C.web-0.web.default.svc.cluster.local
D.web.web-1.default.svc.cluster.local
AnswerA

This FQDN follows the exact pattern for a StatefulSet-managed pod backed by a headless service: <pod-name>.<service-name>.<namespace>.svc.cluster.local. Because the service is headless (clusterIP: None), Kubernetes publishes an A record for each of its endpoints, and web-1 is a valid ordinal pod name in the StatefulSet. Therefore, this name resolves directly to the IP address of the web-1 pod and is the correct target address.

Why this answer

A is correct because in a StatefulSet with a headless service (clusterIP: None), each pod gets a unique DNS name following the pattern `<pod-name>.<service-name>.<namespace>.svc.cluster.local`. For pod 'web-1' in the default namespace, this resolves to the pod's specific IP address via a DNS A record, not a service VIP.

Exam trap

The trap here is that candidates often confuse the DNS naming pattern for StatefulSet pods with the standard service DNS (which uses the service name only), leading them to omit the pod name or misorder the components.

How to eliminate wrong answers

Option B is wrong because it omits the service name 'web', so the DNS name 'web-1.default.svc.cluster.local' would not match the StatefulSet's headless service naming convention and would not resolve to the pod's IP. Option C is wrong because it references 'web-0', which is the DNS name for the first pod, not 'web-1'. Option D is wrong because the format 'web.web-1.default.svc.cluster.local' reverses the pod and service name order; the correct pattern is `<pod-name>.<service-name>.<namespace>.svc.cluster.local`, not the other way around.

138
MCQmedium

You have a headless service 'db' in namespace 'data'. Pods in that namespace can resolve 'db.data.svc.cluster.local'. What is the effect of a headless service on DNS resolution?

A.It does not create any DNS record
B.It returns the IP of the first pod
C.It returns a round-robin list of pod IPs
D.It returns the ClusterIP of the service
AnswerC

This is correct: since a headless service is defined with clusterIP: None, its DNS name is bound directly to the pod IPs, and the DNS server returns all matching pod IPs as multiple A records. Clients and resolvers often iterate through these records in a round-robin manner, enabling client-side load balancing across the underlying pods without a virtual service IP.

Why this answer

A headless service (with `clusterIP: None`) does not have a ClusterIP, so DNS queries for the service name return the IP addresses of all ready pods backing the service, rather than a single virtual IP. This enables client-side load balancing via DNS round-robin, as the DNS resolver returns multiple A records that the client can cycle through. Option C correctly describes this behavior.

Exam trap

The trap here is that candidates confuse headless services with regular ClusterIP services, assuming DNS returns a single virtual IP (ClusterIP) or no records at all, when in fact headless services return multiple pod IPs for direct pod-to-pod communication.

How to eliminate wrong answers

Option A is wrong because a headless service does create DNS records—specifically, it returns A/AAAA records for each ready pod, not no records at all. Option B is wrong because it does not return the IP of the first pod; it returns all pod IPs, and the order may vary depending on DNS resolver implementation, but there is no guaranteed 'first' pod. Option D is wrong because a headless service has no ClusterIP by definition (clusterIP: None), so it cannot return a ClusterIP.

139
MCQhard

A pod has a readiness probe using tcpSocket on port 3306. The application listens on port 3306 but returns errors on database queries. What is the effect of the readiness probe?

A.The pod will be evicted from the node
B.The pod will be considered ready as long as the TCP port is open, even if the application is not fully functional
C.The pod will be marked not ready because the application returns errors
D.The container will be restarted due to readiness probe failure
AnswerB

A tcpSocket readiness probe is considered successful if the kubelet can establish a TCP connection to the specified port, typically via a three-way handshake. It does not send any application-level data, nor does it read or inspect the application's response. Consequently, as long as the listening socket is open, the pod is marked Ready and receives traffic, even if the application inside is misconfigured, returning errors, or not fully initialized.

Why this answer

A readiness probe with tcpSocket only checks whether the TCP port is open and accepting connections. It does not verify application-level health, such as whether the application can process queries or return valid responses. Since port 3306 is open, the probe succeeds, and the pod is considered ready, even though the application returns errors on database queries.

Exam trap

The trap here is that candidates often assume readiness probes check application health or error responses, but a tcpSocket probe only verifies that the port is open, not that the application is working correctly.

How to eliminate wrong answers

Option A is wrong because readiness probe failures do not cause pod eviction; eviction is related to node resource pressure or taints, not probe results. Option C is wrong because a tcpSocket readiness probe does not evaluate application-level errors; it only checks if the TCP handshake succeeds on the specified port. Option D is wrong because readiness probe failures do not restart the container; only liveness probe failures trigger container restarts.

140
MCQmedium

A developer deploys a set of Pods labeled app=frontend and wants to expose them internally within the cluster on a stable IP. Which resource should be used?

A.Service of type NodePort
B.Service of type LoadBalancer
C.Service of type ClusterIP
D.Ingress resource
AnswerC

A ClusterIP Service is the default and correct Service type for internal-only communication. It assigns a stable virtual IP from the cluster's service CIDR that is reachable only from inside the cluster, and it provides built-in load balancing across the backend Pods via iptables/IPVS rules managed by kube-proxy. The frontend Pods can reliably resolve the Service by DNS name and connect to it, without any external exposure, which exactly matches the requirement for a backend that should not be accessible from outside the cluster.

Why this answer

A Service of type ClusterIP exposes the Pods on a stable internal IP address that is only reachable within the cluster. This is the default Service type and is ideal for internal communication between components, such as a frontend being accessed by a backend, without exposing the service outside the cluster.

Exam trap

The trap here is that candidates often confuse 'exposing internally' with 'exposing externally' and choose NodePort or LoadBalancer, forgetting that ClusterIP is the default and correct choice for internal-only stable IP access.

How to eliminate wrong answers

Option A is wrong because a NodePort Service exposes the Pods on a static port on each Node's IP address, making it accessible from outside the cluster, which is unnecessary and insecure for internal-only access. Option B is wrong because a LoadBalancer Service provisions an external load balancer (e.g., from a cloud provider) to expose the service to the internet, which is overkill and violates the requirement for internal-only exposure. Option D is wrong because an Ingress resource is not a Service; it provides HTTP/HTTPS routing rules to Services (typically ClusterIP) and is used for external traffic management, not for providing a stable internal IP directly.

141
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.

142
Multi-Selecthard

Which TWO of the following are valid reasons for using a startup probe?

Select 2 answers
A.To monitor the health of a container after it has started
B.To prevent unnecessary restarts during initial startup
C.To provide additional logging for the container
D.To replace the need for a readiness probe
E.To delay the start of liveness and readiness probes for slow-starting containers
AnswersB, E

During the startup phase, the liveness probe is suppressed until the startup probe succeeds, so a slow-initializing container will not be prematurely killed. By configuring a generous failureThreshold and periodSeconds, the startup probe gives the container a controlled window to become ready. This prevents a crash-looping cycle that would otherwise occur when a liveness check fires before the application is fully operational.

Why this answer

A startup probe is specifically designed to address containers that require a longer initialization time before they are ready to handle traffic or respond to health checks. By delaying the start of liveness and readiness probes until the startup probe succeeds, it prevents the kubelet from prematurely restarting the container due to failed liveness checks during its slow startup phase. This is the primary reason for using a startup probe: to avoid unnecessary restarts during initial startup.

Exam trap

The trap here is that candidates confuse the startup probe with a readiness probe, thinking it controls traffic routing, when in fact it only controls the activation timing of liveness and readiness probes.

143
MCQmedium

A Service named `api` in namespace `default` has multiple endpoints. You run `kubectl get endpoints api` and see no IPs. What is the most likely cause?

A.The Service type is ExternalName
B.The namespace has a NetworkPolicy blocking traffic
C.The Service has a clusterIP of None
D.The Service selector does not match any pods
AnswerD

The endpoints controller watches Services and Pods in the same namespace and creates an Endpoints object only when the Service's selector matches at least one ready pod. If no pod carries all of the label keys and values specified in the Service's selector, the controller will not create an Endpoints object; this is the most common cause of a Service with no endpoints. You can verify this by running kubectl describe service api to see the selector and then checking whether any pods in the namespace have those exact labels.

Why this answer

The most likely cause is that the Service's selector does not match any pods. A Service uses its label selector to identify pods and automatically populate its endpoints. If no pods match the selector, the endpoints list will be empty, resulting in no IPs shown by `kubectl get endpoints api`.

Exam trap

The trap here is that candidates often confuse a headless Service (clusterIP: None) with a Service that has no endpoints, but a headless Service still has endpoints if its selector matches pods.

How to eliminate wrong answers

Option A is wrong because an ExternalName Service does not have selectors or endpoints; it returns a CNAME record, but `kubectl get endpoints` would show an empty list or an error, not simply no IPs. Option B is wrong because a NetworkPolicy controls traffic flow to/from pods, not the population of endpoints; endpoints are managed by the control plane based on pod selectors, independent of network policies. Option C is wrong because a headless Service (clusterIP: None) still has endpoints if its selector matches pods; it simply does not have a cluster IP for load balancing, but endpoints are still populated.

144
MCQhard

A container image requires running as UID 0 but you need to comply with a 'restricted' Pod Security Admission policy. Which SecurityContext setting allows this while still passing the policy?

A.Set securityContext: { allowPrivilegeEscalation: true }
B.No SecurityContext setting allows running as UID 0 under the restricted policy.
C.Set securityContext: { runAsNonRoot: true, capabilities: { add: ['SYS_ADMIN'] } }
D.Set runAsUser: 0 and runAsNonRoot: false
AnswerB

Under the restricted Pod Security Standard, runAsNonRoot must be true, which enforces that the container's primary process runs as a non-root user (UID != 0). There is no securityContext setting that can override this; any attempt to set runAsUser: 0 would be invalidated by admission control. The only solution is to modify the container image to use a non-root user or to run under a different Pod Security Standard. Thus no SecurityContext field permits UID 0.

Why this answer

The 'restricted' Pod Security Admission policy requires that containers run as non-root (runAsNonRoot: true) and prohibits setting runAsUser to 0. Since the image requires UID 0, no SecurityContext setting can override this policy constraint; the only way to comply is to modify the image to run as a non-root user. Therefore, option B is correct.

Exam trap

The trap here is that candidates assume they can override the restricted policy with a SecurityContext setting like runAsUser: 0, not realizing that the restricted policy explicitly forbids UID 0 and enforces runAsNonRoot: true, making any such override invalid.

How to eliminate wrong answers

Option A is wrong because allowPrivilegeEscalation: true is actually prohibited by the restricted policy (it must be false), and it does not address the UID 0 requirement. Option C is wrong because runAsNonRoot: true conflicts with running as UID 0, and adding SYS_ADMIN capability is forbidden by the restricted policy (only NET_BIND_SERVICE is allowed). Option D is wrong because runAsUser: 0 with runAsNonRoot: false explicitly violates the restricted policy's requirement that runAsNonRoot must be true and runAsUser must not be 0.

145
MCQeasy

A developer wants to inject database credentials into a pod as environment variables. The credentials are stored in a Kubernetes Secret named 'db-creds' with keys 'username' and 'password'. Which pod spec snippet correctly injects both values as environment variables?

A.env: - name: username valueFrom: secretKeyRef: name: db-creds key: username
B.envFrom: - configMapRef: name: db-creds
C.envFrom: - secretRef: name: db-creds
D.envFrom: - secretKeyRef: name: db-creds
AnswerC

The `envFrom` block with `secretRef` is the recommended way to inject all key-value pairs from a Secret as environment variables in one go. Each key in the Secret becomes an environment variable name, and the corresponding value is the decoded Secret data. This automatically provides both `username` and `password` (or any other keys) to the pod without listing them individually.

Why this answer

`envFrom` with `secretRef` injects all key-value pairs from a Secret as environment variables into the pod. This directly satisfies the requirement to inject both 'username' and 'password' from the 'db-creds' Secret without needing to specify each key individually.

Exam trap

The trap here is that candidates often confuse `envFrom` with `env` and use `secretKeyRef` under `envFrom` (Option D) or mistakenly use `configMapRef` for secrets (Option B), failing to recognize that `envFrom` requires `secretRef` to inject all keys from a Secret.

How to eliminate wrong answers

Option A is wrong because it only injects a single key ('username') as an environment variable, missing the 'password' key; it uses `env` with `secretKeyRef` for one value, not `envFrom` for all values. Option B is wrong because `configMapRef` references a ConfigMap, not a Secret; ConfigMaps are for non-sensitive data, while database credentials require a Secret. Option D is wrong because `secretKeyRef` is not a valid field under `envFrom`; `envFrom` uses `secretRef` to reference the entire Secret, while `secretKeyRef` is used under `env` for individual key references.

146
MCQeasy

A developer creates a Secret named 'db-secret' with key 'password'. They want to expose the password as an environment variable DB_PASSWORD in a Pod. Which of the following is the correct way to achieve this?

A.Set env: - name: DB_PASSWORD valueFrom: secretKeyRef: name: db-secret key: password
B.Set env: - name: DB_PASSWORD valueFrom: configMapKeyRef: name: db-secret key: password
C.Use envFrom: - secretRef: name: db-secret
D.Set env: - name: DB_PASSWORD secretRef: name: db-secret key: password
AnswerA

This is the correct form: the env entry declares the environment variable DB_PASSWORD, and valueFrom.secretKeyRef tells Kubernetes to retrieve the value of the key 'password' from the Secret named 'db-secret'. Because the secretKeyRef object is nested under valueFrom, the API server knows to fetch the key and inject it as an environment variable. This syntax provides an explicit one-to-one mapping between a specific secret key and a custom container environment variable name.

Why this answer

It uses the `valueFrom.secretKeyRef` field to reference a specific key (`password`) from the Secret named `db-secret` and expose it as the environment variable `DB_PASSWORD`. This is the standard Kubernetes syntax for injecting a single Secret key into a Pod's environment variable.

Exam trap

The trap here is that candidates often confuse `secretKeyRef` with `configMapKeyRef` or incorrectly use `secretRef` directly under `env`, forgetting that `secretKeyRef` must be nested under `valueFrom`.

How to eliminate wrong answers

Option B is wrong because `configMapKeyRef` is used to reference keys from a ConfigMap, not a Secret; using it with a Secret name would fail to resolve the value. Option C is wrong because `envFrom` with `secretRef` injects all keys from the Secret as environment variables, but the developer specifically wants only the `password` key exposed as `DB_PASSWORD`, not all keys. Option D is wrong because `secretRef` is not a valid field under `env`; the correct field is `valueFrom.secretKeyRef`, and the syntax shown is incomplete and invalid.

147
MCQeasy

A pod is in CrashLoopBackOff state. You need to view the last few lines of its logs to understand why it is crashing. Which command is most appropriate?

A.kubectl logs -f my-pod
B.kubectl logs my-pod
C.kubectl logs my-pod --tail=20
D.kubectl get events --field-selector involvedObject.name=my-pod
AnswerC

The --tail=20 flag instructs kubectl to print only the last 20 lines of the container's log output. For a pod in CrashLoopBackOff, these final lines almost always contain the exact exception, panic, or error that triggered the latest restart. This targeted snapshot cuts through the noise of earlier failed attempts and gives you the actionable diagnostic information you need immediately.

Why this answer

The `--tail=20` flag limits the output to the last 20 lines of the pod's logs, which is the most efficient way to see the recent crash-related errors without scrolling through the entire log history. In a CrashLoopBackOff state, the pod is repeatedly restarting, so viewing the tail of the logs directly shows the most recent failure messages, which is the standard diagnostic approach.

Exam trap

CNCF often tests the distinction between `kubectl logs` and `kubectl logs -f`, where candidates mistakenly choose the `-f` option thinking it shows 'the last few lines' because of the 'follow' concept, but `-f` actually streams new logs and does not limit output to a specific number of lines.

How to eliminate wrong answers

Option A is wrong because `kubectl logs -f` follows (tails) the log stream continuously, which is useful for real-time monitoring but not for viewing the last few lines of a crashed pod's logs; it will hang waiting for new output that may never come if the pod is not actively logging. Option B is wrong because `kubectl logs my-pod` without `--tail` will output the entire log history, which can be excessively long and inefficient for quickly identifying the crash cause, especially in pods with many restarts. Option D is wrong because `kubectl get events` shows cluster events (e.g., scheduling, pulling images) but does not display the application's stdout/stderr logs; it provides operational context but not the specific error messages from the crashing container.

148
MCQmedium

A ClusterIP service named 'db-service' in namespace 'data' is not reachable from a pod in the same namespace. The pod's /etc/resolv.conf shows 'search data.svc.cluster.local svc.cluster.local cluster.local'. Using the pod, which command tests DNS resolution for the service?

A.dig db-service.data.svc.cluster.local
B.ping db-service
C.nslookup db-service.data.svc.cluster.local
D.curl http://db-service:3306
AnswerC

nslookup explicitly issues a DNS query to the cluster's configured resolvers (CoreDNS) and displays the returned IP address for the full service DNS name db-service.data.svc.cluster.local. It isolates the DNS lookup phase from any application-level connectivity, so a successful response confirms that the service's clusterIP is registered and resolvable. This is the most direct and broadly available diagnostic tool for checking DNS-based service discovery in Kubernetes.

Why this answer

`nslookup` is a standard DNS lookup tool that queries the cluster's DNS server (CoreDNS/kube-dns) for the fully qualified domain name (FQDN) of the service. The FQDN `db-service.data.svc.cluster.local` matches the search domains in the pod's `/etc/resolv.conf`, so `nslookup` will resolve the service's ClusterIP, confirming DNS is working. This directly tests DNS resolution, which is the root cause when a service is unreachable by name.

Exam trap

The trap here is that candidates often choose `ping` (option B) because they assume network connectivity testing is sufficient, but `ping` uses ICMP and does not test DNS resolution, which is the specific problem described in the question.

How to eliminate wrong answers

Option A is wrong because `dig` is not typically installed in minimal container images (e.g., Alpine-based pods) and is not a standard troubleshooting tool in Kubernetes; the question asks for a command that can be used from the pod, and `dig` may not be available. Option B is wrong because `ping` tests ICMP reachability to an IP address, not DNS resolution; it would fail if the service's ClusterIP is not pingable (which is normal for ClusterIP services) and does not verify the service name resolves correctly. Option D is wrong because `curl` tests HTTP connectivity to a specific port (3306), not DNS resolution; it would fail if the service is not listening on HTTP or if the name does not resolve, but it does not isolate the DNS issue.

149
MCQhard

Which of the following is a valid NetworkPolicy that allows ingress traffic only from pods with label 'role: frontend' in any namespace?

A.ingress: - from: - namespaceSelector: {} podSelector: matchLabels: role: frontend
B.ingress: - from: - ipBlock: cidr: 0.0.0.0/0
C.ingress: - from: - podSelector: matchLabels: role: frontend
D.ingress: - from: - namespaceSelector: matchLabels: role: frontend
AnswerA

The empty namespaceSelector {} acts as a wildcard that selects all namespaces in the cluster, and the podSelector restricts the rule to only pods labeled role: frontend. Because the namespace selector and pod selector are both present in a single from entry, they are combined with an AND: allowed sources are frontend pods in any namespace. This correctly implements the requirement to allow only frontend pods across all namespaces, rather than limiting them to the policy's own namespace.

Why this answer

It uses a `namespaceSelector: {}` (which matches all namespaces) combined with a `podSelector` that selects pods with label `role: frontend`. This combination allows ingress traffic from pods with that label in any namespace, which is exactly what the question requires. In Kubernetes NetworkPolicy, when you want to select pods across all namespaces, you must include an empty `namespaceSelector` alongside the `podSelector`.

Exam trap

The trap here is that candidates often forget that a `podSelector` without a `namespaceSelector` only applies to the same namespace, and they may incorrectly choose option C, not realizing that the question explicitly requires traffic from 'any namespace'.

How to eliminate wrong answers

Option B is wrong because it uses an `ipBlock` rule allowing traffic from all IP addresses (0.0.0.0/0), which does not restrict traffic based on pod labels at all. Option C is wrong because it only specifies a `podSelector` without a `namespaceSelector`, which by default restricts the rule to pods in the same namespace as the NetworkPolicy, not any namespace. Option D is wrong because it uses a `namespaceSelector` with a label selector for `role: frontend`, but this selects namespaces (not pods) with that label, and without a `podSelector` it would allow traffic from all pods in those namespaces, not just pods with the label `role: frontend`.

150
MCQmedium

You have a Deployment named 'web-app' with 5 replicas. You run 'kubectl set image deployment/web-app app=nginx:1.21'. What is the effect of this command?

A.It scales the Deployment to 0 replicas and then scales back up.
B.It immediately terminates all running pods and creates new ones with the new image.
C.It creates a new Deployment with the updated image.
D.It updates the image of the container named 'app' to nginx:1.21, triggering a rolling update.
AnswerD

The command kubectl set image deployment/web app=nginx:1.21 targets the existing Deployment and updates the image of the container literally named 'app' in its pod template. This change to the pod template makes the Deployment controller detect a diff and begin a rolling update: it creates a new ReplicaSet with the nginx:1.21 image and progressively replaces old pods, preserving availability according to the rollout strategy. You can watch progress with kubectl rollout status deployment/web, and if needed, the update can be rolled back with kubectl rollout undo.

Why this answer

The `kubectl set image` command updates the container image in the Deployment's pod template. This triggers a rolling update, where the Deployment's ReplicaSet creates new pods with the new image and gradually terminates old pods, ensuring zero downtime. The container name 'app' matches the container in the pod spec, so the image is updated to nginx:1.21.

Exam trap

The trap here is that candidates may confuse `kubectl set image` with `kubectl delete pod` or assume it immediately terminates all pods, but it actually triggers a controlled rolling update that replaces pods gradually.

How to eliminate wrong answers

Option A is wrong because `kubectl set image` does not scale the Deployment to 0 replicas; it only updates the container image, and the rolling update process maintains the desired replica count throughout. Option B is wrong because the command does not immediately terminate all pods; it initiates a rolling update, which replaces pods gradually, not all at once. Option C is wrong because the command does not create a new Deployment; it modifies the existing Deployment's pod template, which triggers an update to the existing ReplicaSet.

Page 1

Page 2 of 12

Page 3