CKAD: 2021 tips, vimrc, bashrc and cheatsheet

You are probably busy studying for you exam right now, so I will try to be brief.

In the following I will share the things that helped me the most in becoming a CKAD, while trying to avoid all generic tips you can find in all the other blog posts like this.

ckad

Tips

  • I only used kubectl apply -f when interacting with yaml files: ignore kubectl create and kubectl replace for simplicity.
  • The exam consists in 2 hours to score 66% on 19 questions, so make sure to flag the most difficult questions, so that you complete them at the end only if you still have time.
  • Make sure to use bookmarks during the exam to be quicker. I used these ones. You can use them in your additional browser tab.
  • Edit the namespace when you copy paste a resource from the docs if it is hardcoded. See network policy for example, which will be applied to the default namespace if you don’t edit it.
  • Learn how to use less. I find very useful to pipe k8s resources into it. For example:
    • You can search by typing / (like vim).
    • You can toggle case sensitive search by typing -i.

.bashrc

You can define aliases in your .bashrc, so that you don’t have to type long commands during the exam.

You can copy-paste the first lines from here at the beginning of your exam. You have to memorize the rest:

# enable autocompletion
source <(kubectl completion bash)

alias k=kubectl
complete -F __start_kubectl k # autocomplete k

# get yaml object instead of applying the changes
alias kd="kubectl --dry-run=client -o yaml"
complete -F __start_kubectl kd

alias ka="kubectl apply -f"

# delete resources immediately
alias kD="kubectl delete --grace-period=0 --force"
complete -F __start_kubectl kD

# delete resources immediately from file
alias kDf="kubectl delete --grace-period=0 --force -f"

# In the following, $1 is the filepath of a yaml k8s object.

# vim apply. edit a file and immediately apply it.
va() {
  vim $1
  ka $1
}

# kubectl edit. Delete the resource of a file, edit and apply it.
ke() {
  kDf $1
  va $1
}

# kubectl replace. Delete and recreate the same resource.
kr() {
  kDf $1
  ka $1
}

After you have edited your .bashrc run the command source ~/.bashrc to apply the changes in your current shell.

.vimrc

At the beginning of your exam, edit your ~/.vimrc file, in order to edit yaml files efficiently:

set nu # set numbers
set tabstop=2 shiftwidth=2 expandtab # use 2 spaces instead of tab
set ai # autoindent: when go to new line keep same indentation

Cheatsheet

Here is a very long list of imperative commands I found useful for the exam.

create a deployment:

k create deploy nginx
  --image nginx:1.16
  --replicas 4
  --port 8080   # container port
  -- ls /home   # command

create a pod:

k run nginx
  --image=nginx
  --restart=Never
  -l="key1=value1,key2=value2"  # multiple labels
  --env="COLOR=blue" --env="KEY3=val3"  # multiple environment variables
  --port=5701  # container port
  --expose  # create a ClusterIP service
  --rm -it  # delete the pod after completed and open a terminal
  -- /bin/sh -c "while true; do date; sleep 10; done"  # command

create a new Service to expose an existing Deployment:

k expose deploy test
  --port=80
  --target-port=8000
  --type NodePort  # optional
  --name my-service

create a new service:

k create svc clusterip pod-name  # service with app=pod-name as label
  --tcp=6379:6379  # <port>:<targetPort>

k create svc nodeport pod-name
  --tcp=80:80  # <port>:<targetPort>
  --node-port=30080

create job:

k create job nginx
  --image=nginx
  -- /bin/sh -c 'counter=0; \
     while [ $counter -lt 3 ]; do counter=$((counter+1)); \
     sleep 3; done;'

create cronjob:

k create cj nginx
  --image=nginx
  --schedule="* * * * *"
  -- /bin/sh -c 'echo "current date: $(date)"'

create configmap:

k create cm app-config
  --from-literal=key123=value123

k create cm app-config
  --from-env-file=config.env  # single file with environment variables

k create cm app-config
  --from-file=config.txt  # single file or directory

create secret:

k create secret generic my-secret
  --from-literal=foo=bar

# you also have the other options as above for the configmap

decode a secret: echo "YmFy" | base64 --decode

create service account:

k create sa my-sa

override the image of a deployment:

k set image deploy my-deployment my-container-name=nginx:1.9.1
  --record # save the "CHANGE-CAUSE" in the deployment history

get pods:

k get po
  -l color=green,app!=my-app     # label equality filter
  -l 'color in (green, red)'     # label set filter
  -l 'color notin (green, red)'  # notin filter
  -l 'color exists'              # exists filter
  --show-labels                  # show all labels

rollouts:

k rollout status deploy nginx

k rollout history deploy nginx
  --revision=1    # specify revision (optional)

k rollout undo deploy nginx
  --to-revision=1  # optional

how to access a pod exposed by a ClusterIp with a timeout of 5 seconds:

k run busybox --image=busybox --restart=Never -it -- /bin/sh
# wget -O- 10.96.32.32:80 -T 5

open pod shell:

k exec -it my-pod -- /bin/sh

create resource quota:

kubectl create quota myrq --hard=cpu=1,memory=1G,pods=2

view docs:

k explain pods.spec

get all the events:

k get events --sort-by=.metadata.creationTimestamp

modify objects label:

k label nodes my-node color=blue  # add a label to node
k label pod my-pod region=eu  # add a label to pod
k label pod my-pod region=us --overwrite  # edit a label
k label pod my-pod region-  # remove a label

modify objects annotations:

k annotate ... # (same usage as k label)

edit namespace for all subsequent kubectl commands in the same context:

k config set-context --current --namespace=core-banking

horizontal pod autoscaler:

k autoscale deploy my-deploy
  --cpu-percent=70   # sum of the cpu percentages used by all the pods that needs to be reached for the hpa to start spinning other pods
  --min=2   # min number of pods
  --max=8   # max number of pods the HPA can scale

k get hpa

taints:

# apply taint
k taint nodes my-node my-key=my-value:NoSchedule

# remove taint
k taint nodes my-node my-key=my-value:NoSchedule-

Theory

I studied for the CKAD by watching the CKAD course by Mumshad Mannambeth, which is simply awesome and it contains very useful labs, too. I also read the CKAD book from O’Reilly, which I recommend if you want a written resource, too.

Practice

This is an hands-on exam, so of course you need to practice a lot. These are some useful resources:

Once you complete these and the labs of the CKAD course you will be probably ready for the exam.

Shortcuts

Time is precious! Use the corresponding shorcut of a k8s resource instead of its fullname.

Fullname Shortcut
configmaps cm
namespaces ns
persistentvolumeclaims pvc
persistentvolumes pv
pods po
serviceaccounts sa
services svc
deployments deploy
replicasets rs
horizontalpodautoscalers hpa
cronjobs cj
jobs
secrets
networkpolicies netpol
resourcequotas quota

Verify your work

After you are done (or when you are short of time) you should verify what you have done.

First of all run k get po --all-namespaces in every context to check that all pods are running.

After that, you can check if every resource was applied successfully:

  • configmaps and secret:

    k exec my-pod -- env
    
  • volumes:

    k exec my-pod -- ls /mount/volume/path
    
  • services:

    k get ep   # endpoints
    

Conclusion

Overall preparing for the certification was really helpful and the exam itself is really practical, so I highly recommend it! 🤓

The most important tip I can give is the following: I probably practiced too much for it, ending up scoring 99%. If the score is not important for you (the score is not written anywhere in the certification) just try it when you feel a little bit confident! Remember: you have two attempts!

Good luck with your exam: keep calm and focus ✌