This is a compilation of preparation questions for the CKAD certification. See this as merely a practice, so don’t look at the answers straight away, try and practice first, and then compare with my answers. There’s not much concept explainations here, so the intent here is to mainly practice the exercises in order to achieve speed and confidence to try the CKAD cert, so try to use more imperative commands then edit yamls. This is valid until the year of 2023/2024 when I did the certification, but some changes in resources / commands might have occured. The exercises itself were written by me to train in the past, but some were gathered from diverse simulators and other sources I’ve used for my test preparation.

Environment for testing the commands

As an environment to test all commands I would suggest minikube for the your local setup: Minikube installation.

Some pre-steps might be required to have minikube working like have podman, docker or some other vm compatible with it.

You can create mode nodes on minikube as well, just bear in mind the resources, as when you create / start the cluster this resource is for both nodes:

minikube start --driver=podman --memory=2GB --nodes=2

This creates a 2 node minikube, each node with 2GB memory, node minikube (control-plane) and minikube-m02.

podman ps
CONTAINER ID  IMAGE                                COMMAND     CREATED      STATUS        PORTS                                                                                                                                 NAMES
42bf1e93aa64  gcr.io/k8s-minikube/kicbase:v0.0.46              12 days ago  Up 4 minutes  127.0.0.1:38169->22/tcp, 127.0.0.1:33297->2376/tcp, 127.0.0.1:39261->5000/tcp, 127.0.0.1:45399->8443/tcp, 127.0.0.1:36739->32443/tcp  minikube
b91bcf58cadc  gcr.io/k8s-minikube/kicbase:v0.0.46              12 days ago  Up 4 minutes  127.0.0.1:40085->22/tcp, 127.0.0.1:44135->2376/tcp, 127.0.0.1:45359->5000/tcp, 127.0.0.1:43023->8443/tcp, 127.0.0.1:34383->32443/tcp  minikube-m02

You can add other options for network cni, container runtime resolution on minikube, integration with cloud authentication and much more, so just check the documentation for further options.

minikube start --container-runtime=containerd --cni=cilium --nodes=2 --memory=2G --driver=podman

I have added an alias for kubectl as a command to be just k, so to just not have to even tab for autocomplete, I sugest you fo the same:

alias k="kubectl"
alias kx="kubectx"
alias kn="kubens"

Install as well kubectx, for switching and changing contexts and kubens, but those you won’t be able to install during the test: https://github.com/ahmetb/kubectx.

You can set your .vimrc as well with the following sets for tabs as well in order to edit a bit easier the yaml files:

cat ~/.vimrc
:set relativenumber
:set et
:set sw=2 ts=2 sts=2

Another nice tool to install to debug pods is jq: https://jqlang.org/download/.

PS: minikube is more intended to local development, not a box or installation for production environments as it does not implement HA and other features only present on more robust setups as kubeadm.

PS: Don’t do any CLEAN UP procedure during the certification unless explicitly requested in the question. I’m just doing the clean ups here to not keep resources up, as in some cases resource names are reused on some questions, and cleaning up avoids any confusion about the resources being created for the question.

Questions

  1. Create a new pod with the nginx image.Solution
  2. Create a new pod with the name redis and with the image redis:1.99.Solution
    1. Identify the problem with the pod.
    2. Rectify the problem with the pod and wait until the pod is ready and healthy.
  3. Create a new replicaset rs-1 using image nginx with labels tier:frontend and selectors as tier:frontend. Create 3 replicas for the same. Scale the above replicaset to 5 replicas.Solution
    1. Update the image of the above replicaset to use nginx:alpine image.
    2. Scale down the replicaset to 2 replicas.
  4. Create a new deployment deploy-1 using image busybox with 3 replicas and command sleep 3600.Solution
    1. Update the image of the above deployment with image ubuntu.
  5. Create a namespace finance.Solution
    1. Create a pod redis01 using image redis in the finance namespace.
  6. Deploy a redis02 pod using the redis:alpine image with the labels set to tier=db.Solution
    1. Create a service redis-service to expose the redis02 application within the cluster on port 6379.
  7. Create a new pod called custom-nginx using the nginx image and expose it on container port 80, but service should expose 8080.Solution
  8. Create a pod called httpd using the image httpd:alpine in the default namespace. Next, create a service of type ClusterIP by the same name (httpd). The target port for the service should be 80.Solution
  9. Create a pod with the ubuntu image to run a container to sleep for 5000 seconds.Solution
  10. Create a new ConfigMap webapp-color. Set key-value pairs as COLOR=blue.Solution
  11. Create a deployment nginx01 using nginx image, which has environment variable CREATED_BY with value octocat.Solution
    1. Verify the environment variable in the containers of the above deployment.
  12. Create a new config map db-config with key-value pairs as:Solution
    1. db-host = “localhost.example.com”
    2. db-port = 3306
    3. db-name = “kubernetes-objects”
    4. Mount the config map db-config in the deployment ubuntu01 with image ubuntu which has 2 replicas.
    5. check if the mount works and check the config file values.
  13. Create a deployment named multi-con-01, which has two containers, one container uses nginx image and has port 80 exposed. Mount the config map db-config as environment variable. Create the second container in the same deployment with image ubuntu, keep the container alive using the command sleep 5000 and mount the config map in db-config with different keys where the new keys are mapped as:Solution
    1. db-host –> DB_URL
    2. db-port –> DB_PORT
    3. db-name –> DB_NAME
  14. Create an opaque secret named db-creds with following key value pairs:Solution
    1. db_user=root
    2. db_password=pass404
    3. db_role=admin
  15. Mount the secret db-creds in the deployment multi-con-01 [created in (23)] as environment variables on both containers with the same keys as mentioned in the secret.Solution
  16. Create a pod ubuntu02 with image ubuntu and run the command sleep 3400 as user 1001.Solution
  17. Create a pod ubuntu03 with image ubuntu and add capabilities for SYS_TIME to each container. Run the command date -s ‘01JAN 2020 10:00:00’ to verify if it is successful.Solution
  18. Taint one of the worker nodes in your cluster with the following property, mode=maintenance:NoSchedule. Create a pod nginx02 with image nginx:alpine and ensure the pod runs on the tainted node as above. Hint: You might want to use tolerations and nodeselectors both in case you have multiple worker nodes.Solution
  19. Create a pod box0 with image busybox and command sleep 30; touch /tmp/debug; sleep 30; rm /tmp/debug. The pod should not be ready until the file /tmp/debug is available in the pod. If the file doesn’t exist, the pod must restart.Solution
  20. Create a pod nginx03 with image nginx, make sure the server is up and running every 10 seconds. The nginx server ideally takes 30 seconds to warm up so ensure that there are no false negatives when reporting the health of the pod. Note: Nginx runs on port 80.Solution
  21. This is a multistage problem:Solution
    1. Create a deployment deploy01 with image nginx with port 80 exposed.
    2. Update the deployment with image nginx:dev and make sure you record the execution of this action.
    3. If the deployment in step b is unsuccessful, rollback the deployment to the previous state by setting any fields explicitly.
    4. If the nginx deployment is in a healthy state, scale the deployment to run 3 replicas, also record this execution for audit-keeping.
    5. Display the history of deployment deploy-01 and store it in file /tmp/21.txt
  22. Create a job that will roll a dice using image kodekloud/throw-dice. The image generates a random number between 1 and 6 and exits. It is a success only if it is a 6 else it is a failure. Check how many times it takes the job to trigger to get a successful outcome.Solution
  23. Create a job with the above image to generate 8 successful outcomes. Also, ensure that the job will attempt no more than 15 attempts and see if the job is successful. You can add an element of 3 parallel executions if required.Solution
  24. Create a scheduled job such that it runs every minute. Use the image kodekloud/throw-dice to check the outcome.Solution
  25. Create a Persistent Volume deploy-history which makes the storage available on each worker nodes at /tmp/deployment. Make sure it has the default provisioner of your cluster assigned. Label the Persistent Volume with audit: true, tier: middleware. The persistent volume must have a capacity of 2 GB.Solution
  26. Create a Persistent Volume persistent-data which uses a storage class name persistent, label persistent=”true” and is of type hostPath which stores the data on /tmp/persistent on worker nodes. The persistent volume must have a capacity of 2 GB.Solution
  27. Create a Persistent Volume my-personal-data which uses a storage class name persistent and is of type hostPath which stores the data on /tmp/pii on worker nodes. The persistent volume must have a capacity of 2 GB. Since this will store personal data, make sure you can identify the persistent volume using the labels security: high, type: pii, audit: true.Solution
  28. Create a Persistent Volume Claim to bind to persistent volume which uses storage class persistent and requests 2 GB capacity.Solution
  29. Create a Persistent Volume Claim to bind to a PV which ensures that the personal and private data is secure. Ensure that this PVC will bind to a PV of type pii.Solution
  30. Create a PVC such that it will bind to a PV that is qualified for middleware applications.Solution
  31. Create a deployment deploy02 with image busybox, mount one of the PVC from above such that it will store logs in the /tmp/deployment directory. The containers of the deployment must:Solution
    1. Create a file in /tmp/deployment with the same name as the pod name with .txt extension.
    2. Run the command i=0; while true; do echo "$i $(date)"; sleep 60; i=$((i+1)); done >> /tmp/deployment/${POD_NAME}.txt to the log file. Hint: You can use init-containers, environment variables to achieve this.
    3. Ensure there are 5 replicas of the deployment.
    4. Ensure you can see the log files created and populated with data in /tmp/deployment directory on the scheduled worker nodes.
  32. Create two deployments i.e. nginx04 and redis04 using images nginx and redis respectively with 3 replicas. Your goal is to ensure that:Solution
    1. each worker node must not have 2 or more nginx04 pods.
    2. each worker node that has a nginx04 pod must have a redis04 pod scheduled on the same node. Hint: Use pod affinity and anti-affinity to ensure the above scenario.
  33. Create 3 pods nginx05, redis05, and httpd05 with images nginx, redis, and httpd respectively. Attach a sidecar debug container of image docker.io/subfuzion/netcat to each of them, or any other image that you can test the connectivy. The security team has enforced the application team to limit the communication between unnecessary pods. Ensure that only the following communication is allowed between pods:Solution
    1. Allow:
      1. nginx05 <–> redis05
      2. nginx05 <–> httpd05
    2. Deny:
      1. httpd05 <-/-> redis05
      2. redis05 <-/-> rest of the world
      3. nginx05 <-/-> the rest of the world
    3. Consider the following ports for the pods as:
      1. nginx05 : 80
      2. httpd05 : 80
      3. redis05 : 6379
    4. Identify a possible information flow in this system. Write the information flow in the format End-User::Pod1::Pod2::Pod3.
  34. A developer started a pod calculus with image busybox which performs the calculation i=0; while true; do a=$(( i*i+i )); echo $a; i=$(( i+1 )); done. But later realized that this is not a reliable way to start a calculation-intensive pod. The developer decided to use a replicaset instead. But with the current pod running it would ruin all the calculations done so far. Can you help the developer to ensure that a replicaset can be created and the existing pod can become a part of this replicaset without any downtime. Store the manifest file of the replica set in /opt/34_rs.yaml and at the beginning add a comment describing in one line what strategy was implemented to achieve this.Solution

  35. Create a deployment deploy03 that uses image nginx:v2. The container name must be nginx. Check if the deployment is successful. Now delete the deployment. Get the events associated with the deployment deploy03 and pods created by the deployment and store them in a file located at 35_events.txt.Solution

  36. Create a configmap devconfig that has configuration data as follows:Solution

    sdk.cfg:
        path: /etc/sdk/
        version: v2
        auth: token
    language:
        golang: 1.15
    

    Ps: create the cm keys for the data as sdk.cfg and language, as otherwise mounting it separately for the next question it will be a bit challinging.

  37. Create a pod devbox with image busybox such that it projects the contents in devconfig. Project sdk.cfg on path /var/dev-sdk/config/sdk.cfg and language on path /var/dev-sdk/lang/golang/version/value.txt.Solution

  38. create a pod pod01 with image busybox such that it requests for 100m of cpu and 50mi of memory and the resources allocated are expandable to a limit of 200m of cpu and 250 mi of memory. try to create a pod using imperative command only.Solution

  39. A stateful-set problem:Solution
    1. Create a stateful set for a middleware application named middleware that uses image nginx. Ensure that the stateful set has 3 replicas and has a persistent storage such that it uses PVC with a storage of 1 Gi mounted on worker nodes host path at /tmp/middleware/storage. Mount the storage on /var/www/html. Create a init-container in the stateful set with image busybox to create an index.html at /var/www/html. The contents of the index.html can be generated using the command echo “From middleware application” > /var/www/html/index.html. Expose the stateful set through a headless service middleware-svc.
    2. Create a temporary pod with image busybox to check if you can access nginx service. Try accessing the service with the headless service and pod names (not ips).
  40. Create a deployment stressor with image polinux/stress. Execute the deployment with command stress and arguments --cpu 6 --timeout 180. Let’s add some limits as well to the pod like: cpu 0.2ms. Enable autoscaling for this deployment with a cpu limit of 75%. Get the autoscale management object and store it in 40_autoscale.yaml file.Solution

Updated: