CKAD Exam Preparation 1/4 - Cross Cutting Aspects

▶️ Introduction

This part covers cross-cutting aspects to be known in order to pass the CKAD Certification Exam. To learn more about the CKAD exam please read this overview.

About this Series

During this blog series I summarize the main “study hooks” in order to be successful with your exam, as I was. The series is composed by the following articles:

All the examples have been developed using minikube on macOS Catalina with VirtualBox.

🧭 Environment Setup



During the exam you will be allowed to open only one browser tab pointing to the K8s documentation Web site. The main links to remember are below, namely the concepts one, as it will allow you to copy and paste certain object manifests easily, for instance PersistentVolume or PersistentVolumeClaim.

kubectl is ready to enable autocomplete and that can save you precious time. I found kubectl autocomplete enabled during my exam but in any case you can find how to enable it in the cheat sheet.

To remember the syntax and structure of YAML object manifests kubectl explain will be your best ally. Just using the syntax <object_name>.<property> you can get the corresponding documentation without going to documentation web pages. Remember that any K8s object has four main fields: apiVersion, kind, metadata and spec and the meaty part is at spec.

kubectl explain pod.spec.containers --recursive
kubectl explain deployment.spec

At any time you can get detailed kubectl command syntax. The nice thing about --help is that it is available at any nesting level, for instance:

kubectl --help
kubectl create --help
kubectl create deployment --help

Complementary Tools

If you are going to use nano as editor you must configure it properly in order to deal with YAML edition. Edit a file named $HOME/.nanorc

set tabsize 4
set tabstospaces

You may also need (actually I did not use it) to use a term multiplexing solution such as tmux.

apt-get install tmux

With tmux you can

  • Ctrl + b + “ → Split horizontally and create a new horizontal pane
  • Ctrl + b + cursor up / cursor down → Move between panes
  • Ctrl + b + x → Kill pane

More information on how to use tmux can be found at:

Configuration and Namespaces


Your exam is going to be conducted (from a base node) in different K8s Clusters and Namespaces. kubectl allows you to work against different Clusters provided you have set the proper Configuration Context.

To view your Configuration:

kubectl config view
apiVersion: v1
- cluster:
    certificate-authority: /Users/jmcf/.minikube/ca.crt
  name: minikube
- context:
    cluster: minikube
    namespace: jmcf
    user: minikube
  name: c2
- context:
    cluster: minikube
    user: minikube
  name: minikube
current-context: minikube
kind: Config
preferences: {}
- name: minikube
    client-certificate: /Users/jmcf/.minikube/profiles/minikube/client.crt
    client-key: /Users/jmcf/.minikube/profiles/minikube/client.key

📌  Remember the structure of Configurations and Contexts:

Config = { Users, Clusters, Contexts, Current-Context }
Context = ( Cluster, User, Namespace )
Cluster = ( K8s-API-Server-endpoint )
User = ( Private-Key, Certificate )

If you want to set up a new Context with a particular User, Cluster and Namespace:

kubectl config set-context <CONTEXT_NAME> --namespace=<NAMESPACE_NAME> 
--user <USER_NAME> --cluster <CLUSTER_NAME>
kubectl config use-context <CONTEXT_NAME> 

If your Context is not pointing to the Namespace you want to work with you can specify it:

kubectl -n  <NAMESPACE>
kubectl --namespace=<NAMESPACE>

To refer to all Cluster Namespaces:

kubectl -A
kubectl --all-namespaces

📌  A Namespace can also be referenced at the metadata level of an object manifest.

Resource Quotas


Create a new Namespace:

kubectl create namespace ex-ns

Defining a Resource Quota for a Namespace:

kind: ResourceQuota
apiVersion: v1
  name: ex-resource-quota
  namespace: ex-ns
    pods: 5
    "requests.cpu": "2"
    "requests.memory": 1024Mi
    "limits.cpu": "4"
    "limits.memory": 2048Mi
kubectl get ResourceQuota -n ex-ns
NAME                AGE     REQUEST                                                LIMIT
ex-resource-quota   2m40s   pods: 0/5, requests.cpu: 0/2, requests.memory: 0/1Gi   limits.cpu: 0/4, limits.memory: 0/2Gi

📌  Once a Namespace defines Resource Quotas, an object must request its minimum resource requirements. If there are not sufficient available resources in the Namespace based on the request an object may not run or may be killed.

Name resolution


The dnsutils Pod can be used to check that DNS resolutions are working properly.

kubectl exec -it dnsutils -- nslookup my-service

✂️ Generic Operations

Create an object:

kubectl create -f <manifest.yaml>

Apply an object manifest:

kubectl apply -f <manifest.yaml>

📌  Some objects do not admit overriding certain fields.

Delete an object:

kubectl delete -f <manifest.yaml>
kubectl delete pods/mypod --grace-period=1

Edit an object:

kubectl edit -f <manifest.yaml>
kubectl edit deployments my-deployment

Patch (update) an object using JSON/YAML Patch:


kubectl patch -f <manifest.yaml> --patch='<JSON_PATCH>'
kubectl patch -f <manifest.yaml> --patch=$'<YAML_PATCH>'

Patch example: Changing a Pod’s image:

kubectl run --image=busybox my-pod -- sh -c 'sleep 3600'
kubectl patch pod my-pod --patch='{"spec":{"containers":[{"name":"my-pod","image":"alpine"}]}}'

📌  You need to provide a merge key. In the example above is

📌  There are three types of patches in K8s: json (RFC 6902), merge (RFC 7386) and strategic (K8s specified). strategicis the default.

📌  With a strategic merge patch, a list is either replaced or merged depending on its patch strategy defined by the K8s API.

📌  With a JSON merge patch, if you want to update a list, you have to specify the entire new list. And the new list completely replaces the existing list.

Get detailed information about an object. describe provides long descriptions:

kubectl get -f <manifest.yaml> -o=wide
kubectl get pods/mypod -o=yaml
kubectl describe -f <manifest.yaml>

📌  A get command does not display labels by default. --show-labels will do the trick.

📌  The -w option allows to watch what is happening with a certain object.

Use JSON Path to filter fields of an object descriptor (manifest):

kubectl get pod nginx -o jsonpath='{.metadata.annotations}{"\n"}'

To re-label an object (--overwrite has to be used if we are updating an existing label):

kubectl label pods foo 'status=unhealthy' --overwrite

Remove labels from a set of objects (Appending a dash to the label name i.e. <label>-):

kubectl label pods --selector='app=v1' app-

📌  --selector or -l is intended to select the concerned objects by matching labels.

Reference several objects, for instance annotate a set of Pods:

kubectl annotate pods nginx1 nginx2 nginx3 'description=a description'

📟 Monitoring


Display resource consumption of Pods:

kubectl top pods -n <NAMESPACE>
NAME                     CPU(cores)   MEMORY(bytes)
depl1-77f99c5854-mcvpf   0m           3Mi
depl1-77f99c5854-pbdhl   0m           4Mi
depl1-77f99c5854-swc4g   0m           3Mi
ex1-79c777cf98-hs4q9     0m           2Mi
ex1-79c777cf98-r9w77     0m           2Mi
ex1-79c777cf98-vrrb6     0m           2Mi
pod-with-pvc             0m           1Mi

📌  Application monitoring does not depend on a single monitoring solution.metrics-server is a lightweight monitoring solution that can be easily enabled on minikube.

Display resource usage of each K8s Node:

kubectl top nodes
NAME       CPU(cores)   CPU%   MEMORY(bytes)   MEMORY%
minikube   346m         17%    2737Mi          71%

More detailed information about a Node can be obtained by:

kubectl describe nodes

⏭️ Next in this series

Pods and Jobs

🗒️ Feedback