CKAD — Mock Exam Part 1

5 minute read

Mock Exam Strategy

Before the Exam

  1. Practice with killer.sh — You get 2 free sessions with your exam purchase. Use them 1-2 weeks before the exam.
  2. Practice with kubectl — Build muscle memory. You should be able to create Pods, Deployments, Services, ConfigMaps, and Secrets without thinking.
  3. Time yourself — Practice completing questions in under 7 minutes each.
  4. Know the docs — Practice navigating kubernetes.io/docs. Know where to find:
    • NetworkPolicy examples
    • Ingress configuration
    • SecurityContext fields
    • PersistentVolumeClaim spec

During the Exam

  1. Read the question completely
  2. Note the namespace and context
  3. Switch to the correct context/namespace
  4. Use imperative commands when possible
  5. Generate YAML with --dry-run=client -o yaml for complex resources
  6. Verify your work before moving on
  7. Flag difficult questions and come back

Scenario-Based Practice Questions (1-9)

These questions cover all CKAD domains. Try to solve each one in under 7 minutes.

Question 1: Pod with Resource Limits

Create a Pod named resource-pod in the dev namespace using the nginx:1.27 image. Set CPU request to 100m, CPU limit to 250m, memory request to 64Mi, memory limit to 128Mi.

Show Answer ```bash kubectl create namespace dev kubectl run resource-pod -n dev --image=nginx:1.27 \ --dry-run=client -o yaml > q1.yaml ``` Edit `q1.yaml` to add resources: ```yaml apiVersion: v1 kind: Pod metadata: name: resource-pod namespace: dev spec: containers: - name: resource-pod image: nginx:1.27 resources: requests: cpu: 100m memory: 64Mi limits: cpu: 250m memory: 128Mi ``` ```bash kubectl apply -f q1.yaml kubectl get pod resource-pod -n dev ```

Question 2: Multi-Container Pod

Create a Pod named sidecar-pod with two containers:

  • Main container: app using nginx:1.27, port 80
  • Sidecar container: logger using busybox:1.36, running tail -f /var/log/nginx/access.log

Both containers should share a volume mounted at /var/log/nginx.

Show Answer ```yaml apiVersion: v1 kind: Pod metadata: name: sidecar-pod spec: containers: - name: app image: nginx:1.27 ports: - containerPort: 80 volumeMounts: - name: logs mountPath: /var/log/nginx - name: logger image: busybox:1.36 command: ["/bin/sh", "-c", "tail -f /var/log/nginx/access.log"] volumeMounts: - name: logs mountPath: /var/log/nginx volumes: - name: logs emptyDir: {} ``` ```bash kubectl apply -f sidecar-pod.yaml kubectl get pod sidecar-pod kubectl logs sidecar-pod -c logger ```

Question 3: CronJob

Create a CronJob named cleanup that runs every day at 3 AM. It should use the busybox:1.36 image and run echo "Cleanup complete". Set the following: keep 3 successful history, keep 1 failed history, 30-second deadline.

Show Answer ```yaml apiVersion: batch/v1 kind: CronJob metadata: name: cleanup spec: schedule: "0 3 * * *" successfulJobsHistoryLimit: 3 failedJobsHistoryLimit: 1 startingDeadlineSeconds: 30 jobTemplate: spec: template: spec: restartPolicy: OnFailure containers: - name: cleanup image: busybox:1.36 command: ["/bin/sh", "-c", "echo Cleanup complete"] ``` ```bash kubectl apply -f cleanup.yaml kubectl get cronjob cleanup ```

Question 4: Deployment with Rolling Update

Create a Deployment named webapp with 4 replicas using nginx:1.26. Configure the rolling update strategy: maxSurge 1, maxUnavailable 0. Then update the image to nginx:1.27 and verify the rollout.

Show Answer ```bash kubectl create deployment webapp --image=nginx:1.26 --replicas=4 \ --dry-run=client -o yaml > q4.yaml ``` Edit to add strategy: ```yaml apiVersion: apps/v1 kind: Deployment metadata: name: webapp spec: replicas: 4 selector: matchLabels: app: webapp strategy: type: RollingUpdate rollingUpdate: maxSurge: 1 maxUnavailable: 0 template: metadata: labels: app: webapp spec: containers: - name: nginx image: nginx:1.26 ``` ```bash kubectl apply -f q4.yaml kubectl set image deployment/webapp nginx=nginx:1.27 kubectl rollout status deployment/webapp kubectl rollout history deployment/webapp ```

Question 5: ConfigMap and Secret

Create a ConfigMap named app-config with APP_ENV=production and LOG_LEVEL=info. Create a Secret named db-secret with DB_PASSWORD=s3cur3p@ss. Create a Pod named config-pod that uses both as environment variables.

Show Answer ```bash kubectl create configmap app-config --from-literal=APP_ENV=production --from-literal=LOG_LEVEL=info kubectl create secret generic db-secret --from-literal=DB_PASSWORD=s3cur3p@ss ``` ```yaml apiVersion: v1 kind: Pod metadata: name: config-pod spec: containers: - name: app image: busybox:1.36 command: ["/bin/sh", "-c", "env | grep -E 'APP_|DB_|LOG_' && sleep 3600"] envFrom: - configMapRef: name: app-config - secretRef: name: db-secret ``` ```bash kubectl apply -f config-pod.yaml kubectl logs config-pod # Expected: APP_ENV=production, LOG_LEVEL=info, DB_PASSWORD=s3cur3p@ss ```

Question 6: Probes

Create a Deployment named health-app with nginx:1.27. Add:

  • A liveness probe that checks HTTP GET on / port 80, initial delay 5s, period 10s
  • A readiness probe that checks HTTP GET on / port 80, initial delay 3s, period 5s
Show Answer ```yaml apiVersion: apps/v1 kind: Deployment metadata: name: health-app spec: replicas: 1 selector: matchLabels: app: health-app template: metadata: labels: app: health-app spec: containers: - name: nginx image: nginx:1.27 ports: - containerPort: 80 livenessProbe: httpGet: path: / port: 80 initialDelaySeconds: 5 periodSeconds: 10 readinessProbe: httpGet: path: / port: 80 initialDelaySeconds: 3 periodSeconds: 5 ``` ```bash kubectl apply -f health-app.yaml kubectl describe deployment health-app ```

Question 7: NetworkPolicy

In the secure namespace, create a NetworkPolicy named db-policy that:

  • Applies to Pods labeled role=db
  • Allows ingress only from Pods labeled role=api on port 3306
  • Allows egress only to DNS (port 53)
Show Answer ```bash kubectl create namespace secure ``` ```yaml apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: db-policy namespace: secure spec: podSelector: matchLabels: role: db policyTypes: - Ingress - Egress ingress: - from: - podSelector: matchLabels: role: api ports: - protocol: TCP port: 3306 egress: - to: [] ports: - protocol: UDP port: 53 - protocol: TCP port: 53 ```

Question 8: Ingress

Create an Ingress named app-ingress with class nginx that:

  • Routes shop.example.com/ to frontend-svc on port 80
  • Routes shop.example.com/api to api-svc on port 8080
  • Uses TLS with a Secret named shop-tls
Show Answer ```yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: app-ingress annotations: nginx.ingress.kubernetes.io/rewrite-target: / spec: ingressClassName: nginx tls: - hosts: - shop.example.com secretName: shop-tls rules: - host: shop.example.com http: paths: - path: /api pathType: Prefix backend: service: name: api-svc port: number: 8080 - path: / pathType: Prefix backend: service: name: frontend-svc port: number: 80 ```

Question 9: Security Context

Create a Pod named secure-app that:

  • Runs as user 1000, group 2000
  • Has a read-only root filesystem
  • Drops all capabilities except NET_BIND_SERVICE
  • Does not allow privilege escalation
  • Uses ServiceAccount app-sa with token auto-mount disabled
Show Answer ```bash kubectl create serviceaccount app-sa ``` ```yaml apiVersion: v1 kind: Pod metadata: name: secure-app spec: serviceAccountName: app-sa automountServiceAccountToken: false securityContext: runAsUser: 1000 runAsGroup: 2000 runAsNonRoot: true containers: - name: app image: nginx:1.27 securityContext: readOnlyRootFilesystem: true allowPrivilegeEscalation: false capabilities: drop: - ALL add: - NET_BIND_SERVICE volumeMounts: - name: tmp mountPath: /tmp - name: cache mountPath: /var/cache/nginx - name: run mountPath: /var/run volumes: - name: tmp emptyDir: {} - name: cache emptyDir: {} - name: run emptyDir: {} ```

Next: Mock Exam — Part 2 →

Updated: