CKAD - Deployment Configuration Notes
Tags: kubernetes, docker, linux, devops
Published: 2020-01-01 21:32:30

# Deployment Configuration

## Volumes

* a volume is a directory (possibly pre-populated) made available to containers in a Pod

* a [Kubernetes volume](https://kubernetes.io/docs/concepts/storage/persistent-volumes/#persistentvolumeclaims) shares at least the Pod lifetime, not the container within

* if you want your storage lifetime to be distinct from a Pod, use Persistent Volumes. These allow for volumes to be claimed by a Pod using *PersistentVolumeClaims*.

* a volume can persist longer than a pod, and can be accessed by multiple pods using **PersistentVolumeClaims**. This allows for state persistency

* a volume can be made available to multiple pods, with each given an **access mode** to write

* we can pass **encoded** data to a pod using **Secrets** and **non-encoded** data using a **ConfigMap** - we can pass things like SSH keys, passwords etc...

* **there is no concurrency checking, which means data corruption is probable unless outside locking takes place**

* examples of volume types: 
    * [rbd](https://docs.ceph.com/docs/master/rbd/)
    * NFS
    * [gcePersistentDisk](https://kubernetes.io/docs/concepts/storage/volumes/)

There are three access modes for volumes:

* **RWO(ReadWriteOnce)** - allows read-write by a single node
* **ROX(ReadOnlyMany)** - allow read-only by multiple nodes
* **RWX(ReadWriteMany)** - allows read-write by multiple nodes

When a volume is requested, the local **kubelet** uses the **kubelet_pods.go** script to:

* map raw devices
* determine and make mount point for container
* create symbolic link on the host filesystem to associate the storage with the container

If no particular **StorageClass** was requested, only *access_mode* and *size* are used as params to create a volume.

## Volume types

There are many different types of volumes such as **GCEpersistentDisk** or **awsElasticBlockStore** (GCE and EBS respectively)

* An **emptyDir** volume is first created when a Pod is assigned to a Node, and exists as long as that Pod is running on that node. As the name says, it is initially empty. Containers in the Pod can all read and write the same files in the emptyDir volume, though that volume can be mounted at the same or different paths in each Container. **When a Pod is removed from a node for any reason, the data in the emptyDir is deleted forever.**

* A **hostPath** volume mounts a file or directory from the host node’s filesystem into your Pod. This is not something that most Pods will need, but it offers a powerful escape hatch for some applications.

## Secrets

Secrets in kubernetes are not encrypted by default - only **base64** encoded.

## Config Maps

Data in ConfigMaps in kubernetes is not encoded or encrypted and contains *key-value* pairs or plain configuration files in any format.

Here are a few uses of ConfigMaps:

* Pod env vars from single or multiple ConfigMaps
* Use ConfigMap values in Pod commands
* Populate Volume from ConfigMap
* Add ConfigMap data to specific path in Volume
* Set file names and access mode in Volume from ConfigMap data
* Can be used by system components and controllers.


### Creating ConfigMaps

ConfigMaps can be created in one of the three following ways:

```
kubectl create configmap myconfigmap \
--from-literal=city=London \             
--from-file=./myconfigmapfile.txt \
--from-file=./myconfigmapdirectory/
```
which results in the following ConfigMap:
```
k get configmap myconfigmap -o yaml

apiVersion: v1
data:
  city: London
kind: ConfigMap
metadata:
  creationTimestamp: "2020-01-12T11:22:43Z"
  name: myconfigmap
  namespace: default
  ...
```

## Scaling and Rolling Update

To scale a deployment we can use

```
kubectl scale deploy/mydeployment --replicas=4
```

and then to downscale

```
kubectl scale deploy/mydeployment --replicas=1
```

## Deployment rollbacks

Let's say we want to update a container's image using the following command

```
kubectl set image deployment/test nginx=nginx:0.9 --record
```

Let's say we now want to update to an even newer version of nginx using the following command

```
kubectl set image deployment/test nginx=nginx:66.6 --record
```

If you now run `kubectl get pods` you will see that the pod is stuck in `ImagePullBackoff` state so we want to immediately rollback the changes to a previously working version. We can do this using the following command

```
kubectl rollout undo deployment/test
```

To view a history of all events we can run

```
kubectl rollout history deployment/test
```

which shows the following output:
```
deployment.apps/test 
REVISION  CHANGE-CAUSE
1         kubectl set image deploy/test test=nginx --record=true
4         kubectl set image deployments/test nginx=nginx:0.8 --record=true
5         kubectl set image deployments/test nginx=nginx:0.9 --record=true
6         kubectl set image deployments/test nginx=nginx:0.66 --record=true
7         kubectl set image deployments/test nginx=nginx:66.66 --record=true
8         kubectl set image deployments/test nginx=nginx:66.66 --record=true
```