# Volumes

- Storage is important and requires a careful selection

- There are two types of storage:

  - ephemeral

  - persistant

---

## Ephemeral storage

- There are several types:

  - emptyDir: empty at Pod startup, with storage coming locally from the kubelet base directory (usually the root disk) or RAM

  - configMap, downwardAPI, secret: inject different kinds of Kubernetes data into a Pod

  - CSI ephemeral volumes: similar to the previous volume kinds, but provided by special CSI drivers which specifically support this feature

  - generic ephemeral volumes, which can be provided by all storage drivers that also support persistent volumes

---

## emptyDir

.small[

```yaml
apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: registry.k8s.io/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /cache
      name: cache-volume
  volumes:
  - name: cache-volume
    emptyDir:
      sizeLimit: 500Mi
```

]

---

## configMap

.small[

```yaml
apiVersion: v1
kind: Pod
metadata:
  name: configmap-pod
spec:
  containers:
    - name: test
      image: "busybox:1.28"
      volumeMounts:
        - name: config-vol
          mountPath: /etc/config
  volumes:
    - name: config-vol
      configMap:
        name: log-config
        items:
          - key: log_level
            path: log_level
```

]

---

## secret

.small[

```yaml
apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
  - name: mypod
    image: redis
    volumeMounts:
    - name: foo
      mountPath: "/etc/foo"
      readOnly: true
  volumes:
  - name: foo
    secret:
      secretName: mysecret
      optional: true
```

]

---

## Persistent Storage

- There are several ways to persist data

  - Use storage directly from Pod

    - nfs

    - hostPath

  - Indirect using a PVC and PV

---

## nfs example

.small[

```yaml
apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: registry.k8s.io/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /my-nfs-data
      name: test-volume
  volumes:
  - name: test-volume
    nfs:
      server: my-nfs-server.example.com
      path: /my-nfs-volume
      readOnly: true
```

]

---

## PV's and PVC's

- PV's are Persistent Volumes and actually store data

- PVC's are Persisten Volume Claims and is a request for storage within a PV

- Often PVC's claim storage by indirect reference known as storageClass

---

## PV and PVC

.small[

```yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: task-pv-volume
  labels:
    type: local
spec:
  storageClassName: manual
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/mnt/data"
```

]

.small[

```yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: task-pv-claim
spec:
  storageClassName: manual
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 3Gi
```

]

---

## Pod using PVC

.small[

```yaml
apiVersion: v1
kind: Pod
metadata:
  name: task-pv-pod
spec:
  volumes:
    - name: task-pv-storage
      persistentVolumeClaim:
        claimName: task-pv-claim
  containers:
    - name: task-pv-container
      image: nginx
      ports:
        - containerPort: 80
          name: "http-server"
      volumeMounts:
        - mountPath: "/usr/share/nginx/html"
          name: task-pv-storage
```

]

---

## How does the StorageClass work

- It is the driver behind a PV and configures this driver

- There are many provisioners which can be used.

- They are not all equal

  - Some can resize, others can not

  - Some are block devices others are filesystems


---

## Provisioners

- Some provisioners are internal (K3s has removed most of them)

- Other requires an external provisioner

  - [NFS subdir external provisioner](https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner) is used often to have something at least...

---

## Access Modes

- Currently there are 3 access modes

- A fourth is in beta in Kubernetes 1.27

- They are know as:

    RWO - ReadWriteOnce

    ROX - ReadOnlyMany

    RWX - ReadWriteMany

    RWOP - ReadWriteOncePod

---

## Access Modes and upgrade strategies

- RWO mode is useful for statefulsets

  - The update strategy first stops a pod and then starts a new one

  - This way there are never two pods writing at the same time

  - It blocks rolling updates for regular deployments

- RWX is needed for rolling updates
