In Kubernetes, Pods use an ephemeral local storage strategy as default. But if you need to make your date outlive the pod or share it across workloads, you can define a volume in the pod specification, that can be shared among containers.
If you need to retain the data in case the pods are killed, you need a persistent volume, that refers to an external storage.
Several types of volumes are supported by Kubernetes:
- emptyDir
- hostPath
- azureDisk (for Microsoft Azure)
- awsElastickBlockstore (for Amazon Web Services)
- gcePersistenceDisk (for Google cloud)
- etc.
Emptydir
The type “emptyDir” can be used in a pod specification to create and empty directory and mount it to one or more containers. This gives you the opportunity to vastly create an ephemeral file system to use in your pod.
You can specify a volume in the spec sectuin as “volumes” and the add a “volumeMount” in each container section:
spec: containers: - image: g1g1/hue-global-listener:1.0 name: hue-global-listener volumeMounts: - mountPath: /notifications name: shared-volume - image: g1g1/hue-job-scheduler:1,0 name: hue-job-scheduler volumeMounts: - mountPath: /incoming name: shared-volume volumes: - name: shared-volume emptyDir: medium: Memory
HostPath
Sometimes, you want your pods to get access to some host information (for example, the Docker daemon) or you want pods on the same node to communicate with each other. That´s why you might need HostPath volumes.
HostPath volumes persist on the original node and are intended or intra-node communication.
If a pod is restarted on a different node, it can’t access the HostPath volume from its previous node.
The containers that access host directories must have a security context with privileged set to true or, on the host side, you need to change the permissions to allow writing.
An example of of HostPath volume used by a container.
apiVersion: v1
kind: Pod
metadata:
name: hue-coupon-hunter
spec:
containers:
- image: busybox
name: hue-coupon-hunter
volumeMounts:
- mountPath: /coupons
name: coupons-volume
securityContext:
privileged: true
volumes:
- name: coupons-volume
host-path:
path: /etc/hue/data/coupons
The “securityContext” section is mandatatory to make it work!
Local volumes
Local volumes are similar to HostPath
, but they persist across pod restarts and node restarts.
The purpose of local volumes is to support StatefulSets where specific pods need to be scheduled on nodes that contain specific storage volumes.
We need to define a storage class for using local volumes. For example:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
$ kubectl create -f local-storage-class.yaml
storageclass.storage.k8s.io/local-storage created
Now, we can create a persistent volume using the storage class that will persist even after the pod that’s using it is terminated:
apiVersion: v1
kind: PersistentVolume
metadata:
name: local-pv
labels:
release: stable
capacity: 1Gi
spec:
capacity:
storage: 1Gi
volumeMode: Filesystem
persistentVolumeReclaimPolicy: Delete
storageClassName: local-storage
local:
path: /mnt/disks/disk-1
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- minikube
As we are defining it as a local volume, we can´t omit the nodeAffinity.
To assign a volume to a Container, you need to define a persistence volume claim, that claims the same storage size.
Persistence volume claims represent a request of storage, by specifying the size and the type of volume you need.
For example:
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: local-pvc
spec:
storageClassName: local-storage
volumeName: local-pv
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
Once the PVC is bound to a volume, the volume is available to the pods.
Run “kubectl get pv,pvc” and make sure that the pvc is bound:
Kubernetes looks for a pv that matches the volume claim requirements.
Once you have a persistence volume claim, you can add the dependency of the persistence volume in your Pod:
apiVersion: v1 kind: Pod metadata: name: random-generator spec: containers: - image: k8spatterns/random-generator:1.0 name: random-generator volumeMounts: - mountPath: "/logs" name: log-volume volumes: - name: log-volume persistentVolumeClaim:
claimName: local-pvc
If storageClassName is not specified in the PVC, the default storage class will be used for provisioning.
For more infos check:
https://kubernetes.io/blog/2017/03/dynamic-provisioning-and-storage-classes-kubernetes/