Tips for CKAD Exam
Tags: ckad, kubernetes
Published: 2021-08-15 18:22:27

In the last post I talked about [How to prepare for CKAD exam](https://dev.to/adityakanekar/how-to-prepare-for-ckad-exam-3a85). In this post we will talk about tips and tricks for passing the CKAD exam.

## Setup your Kubernetes environment

Before starting the exam, spend few mins to setup the environment which will help you save time later. 

### Setup autocompletion
Ref - https://kubernetes.io/docs/reference/kubectl/cheatsheet/

Run following statements on the shell to setup autocompletion for kubectl commands,

```
source <(kubectl completion bash) 

# Only if you want to add this to your bashrc profile
echo "source <(kubectl completion bash)" >> ~/.bashrc

alias k=kubectl
complete -F __start_kubectl k
```

Now you can execute commands on shell using alias **k** instead of **kubectl** e.g.

```
k get pods
```
Also you can now press tab after writing first 2-3 letters of your sub commands to complete the command. This will save you sometime in the exam, remember the time is limited and saving time typing each command will add up to a significant saving in time.

### Setup alias for frequently used commands
Setup alias or environment variables for frequently used commands, I personally used following alias's and environment variables.

```
alias kg='k get po -o wide --show-labels'
```

Environment variables
```
dr='--dry-run=client -o yaml'
fd='--force --grace-period=0'
```

The first command can be used with **k run** command to generate yaml definition like,

```
k run nginx --image=nginx $dr > nginx.yaml
```

The second command can be used with **k delete po** to delete pod's quickly. As part of the exams, there will be lot of questions which will require to create/delete pods. To delete pod quickly you can use the second environment variable like,

```
k delete po nginx $fd 
```


## Use imperative commands

It's difficult to create the YAML definition files required for deploying resources like PODs, Deployments, ReplicaSets etc. by creating YAML definition files manually. Copying the files manually from the Kubernetes documentation is one way, but its time consuming and exam time is limited. 

There is a better way for creating these complex YAML definition files using kubectl imperative commands. I am listing down few commands for creating resources like POD, Deployments, Service etc.

### Create POD
Ref - https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#run
Use the below command to generate the Pod definition file,

```
k run <pod-name> --image=<image-name> --dry-run=client -o yaml > <file-name>.yaml

#or if you setup the environment variable simply run

k run <pod-name> --image=<image-name> $dr > <file-name>.yaml
```

Following command demonstrates how you can use different option to quickly create a Pod or YAML definition file without creating the YAML file at all,

```
k run nginx --image=nginx --labels tier=webserver --env="key=value" --port=8080 --requests="cpu=200m,memory=256Mi" --limits="cpu=250m,memory=512Mi" --command -- echo "test" 

# If you want to save the definition to a file then use
k run nginx --image=nginx --dry-run=client -o yaml --labels tier=webserver --env="key=value" --port=8080 --requests="cpu=200m,memory=256Mi" --limits="cpu=250m,memory=512Mi" --command -- echo "test" > nginx.yaml

k apply -f nginx.yaml
```

Make sure to use '--dry-run=client -o yaml' before command, also you can use the environment variable $dr with this command. Also if you want to expose the pod as a service you can suffix **--expose** to expose the Pod as a service.

### Create Deployment

To create deployment definition or deployment run command below,

```
k create deploy <deployment-name> --image=<image> --replicas=4  $dr > <filename>.yaml

# Nginx deployment sample
k create deploy nginx --image=nginx --replicas=4 $dr > nginx.yaml

k apply -f nginx.yaml
```

### Exposing Service
To expose the deployment as a service run below command,

```
k expose deployment nginx --image=nginx --replicas=4 --port=8080 --target-port=8080 --name=nginx-service --type=ClusterIP $dr > service.yaml

# for pod
k expose pod nginx --image=nginx --replicas=4 --port=8080 --target-port=8080 --name=nginx-service --type=ClusterIP $dr > service.yaml

```

To create a NodePort service however you will have to run the above command and add nodePort in the YAML file. 

## Small but significant things

### Testing your deployments

Always make sure to test the deployments, to be sure to not miss on any requirements. To test the deployments you can run temporary pods by running below command,

```
k run temp --image=nginx:alpine --restart=Never --rm -i -- curl -m 5 nginx-service:8080

```

If the service is in a different namespace you can specify namespace like,

```
k run temp --image=nginx:alpine --restart=Never --rm -i -- curl -m 5 nginx-service:8080 -n 
<namespace>
```
Or specify the name as <svc_name>.<namespace> like,

```
k run temp --image=nginx:alpine --restart=Never --rm -i -- curl -m 5 nginx-service.<namespace>:8080
```

### Get CPU/Memory usage for node/pod

To get the CPU/Memory usage by node/pod run,

```
k top node

#for pods run
k top pod
```

### Using Init Containers
Init containers run un before the app containers are started. You can learn more about Init Containers [here](https://kubernetes.io/docs/concepts/workloads/pods/init-containers/)

### Multi-Container Pod or Sidecar 
Multi-container POD is simply a mode with more than one containers. Following YAML shows example of a multi-container POD also called as Sidecar,
Ref - https://kubernetes.io/docs/tasks/access-application-cluster/communicate-containers-same-pod-shared-volume/
```
apiVersion: v1
kind: Pod
metadata:
  name: two-containers
spec:

  restartPolicy: Never

  volumes:
  - name: shared-data
    emptyDir: {}

  containers:

  - name: nginx-container
    image: nginx
    volumeMounts:
    - name: shared-data
      mountPath: /usr/share/nginx/html

  - name: debian-container
    image: debian
    volumeMounts:
    - name: shared-data
      mountPath: /pod-data
    command: ["/bin/sh"]
    args: ["-c", "echo Hello from the debian container > /pod-data/index.html"]
```

## Reading logs from Pod

To read logs from POD run,

```
k logs <pod_name>
```

To see running logs run,
```
k logs -f <pod_name>
```

To read logs from multi-container Pod,

```
k logs -f <pod_name> -c <container_name>
```

## Making changes to the existing deployments

You can make changes to the existing deployments by simply editing them like,

```
k edit pod <pod_name>
```

This will open the Pod definition (YAML) in Vim editor. Some changes can be done without recreating the pod but changes like changing the image name for example, requires you to delete and recreate the Pod. The trick to make such changes are to edit the Pod and try to save the changes, this will prompt you to create a new temporary file, just hit ':wq' to save the changes to the file. You can then delete the old pod and use this temporary file to apply the changes. The trick here is to save as much time as possible to cover all the questions.

So thats it for this post, I will keep updating this post with more information. Till then, happy practicing!