Volumes
Volumes are needed to store data within a container or share data among other containers.
All volumes requested by a Pod must be mounted before the containers within the Pod are started. This applies also to secrets and configmaps.
Shared Volume
Below you can find a sample of how to create a shared volume.
But be aware that one container can overwrite the data that from the other container.
You can use locking or versioning to overcome this topic.
containers:
- name: firstcontainer
image: busybox
volumeMounts:
- mountPath: /firstdir
name: sharevol
- name: secondcontainer
image: busybox
volumeMounts:
- mountPath: /seconddir
name: sharevol
volumes:
- name: sharevol
emptyDir: {}
$ kubectl exec -ti example -c secondcontainer -- touch /seconddir/bla
$ kubectl exec -ti example -c firstcontainer -- ls -l /firstdir
Persistent Volume - PV
This is a storage abstraction used to keep data even if the Pods is killed. In the Pods you define a volume of that type.
kubectl get pv
Sample of a PV with hostPath Type
kind: PersistentVolume
apiVersion: v1
metadata:
name: 10Gpv01
labels:
type: local
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/somepath/data01"
Persistent Volume Claim - PVC
With the PVC volumes can be accessed by multiple pods and allow state persistency.
The cluster attaches the Persistent Volume.
There is no concurrency checking, so data corruption is probable unless locking takes place outside.
There are 3 access modes for the PVC:
- RWO - ReadWriteOnce by a single node
- ROX - ReadOnlyMany by multiple nodes
- RWX - ReadWriteMany by many nodes
kubectl get pvc
Phases to persistent storage
- Provisioning: Can be done in advance, ie resources from a cloud provider
- Binding: Once a watch loop on master notices a PVC it requests the access.
- Using: The volume is mounted to the Pod and can now be used.
- Releasing: When the pod is down, the PVC is deleted. The resident data remains depending on the
persitenVolumReclaimPolicy
- Reclaiming: You have three options: Retain, Delete, Recycle
Empty Dir
The kubelet creates an emptyDir
. It will create the directory in the container but not mount any storage. The data written to that storage is not persistent, as it will be deleted when the Pod is deleted.
apiVersion: v1
kind: Pod
metadata:
name: sample
namespace: default
spec:
containers:
- image: sample
name: sample
command:
- sleep
- "3600"
volumeMounts:
- mountPath: /sample-mount
name: sample-volume
volumes:
- name: sample-volume
emptyDir: {}
Other Volume types
GCEpersistenDisk and awsElsaticBlockStore
You can mount your GCE or your EBS into your Pods.
hostPath
This mounts a resource from the host node filesystem. The resource must be already in advance in order to be used.
- DirectoryOrCreate
- FileOrCreate
and many more
NFS - Network File System
iSCSI - Internet Small Computer System Interface
RBD (RADOS Block Device) - RBD is a block storage device that runs on top of the Ceph distributed storage system. It allows you to create block devices that can be mounted and used like a regular disk. RBD is often used in virtualization environments, providing storage for virtual machines.
CephFS - CephFS is a distributed file system built on top of the Ceph storage system.
GlusterFS - open-source, distributed file system that can scale out to petabytes of storage. It works by aggregating various storage resources across nodes into a single, global namespace.
Dynamic Provisioning
With the kind StorageClass, a user can request a claim, which the API Server fills via auto-provisioning. Common choices for dynamic storage are AWS and GCE.
Sample for gce:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: you-name-it
provisioner: kubernetes.io/gce-pd
parameters:
type: pd-ssd
ConfigMaps
This kind of storage is used to store sensitive data, that does not need to be encoded, but should not be stored within the application itself.
Using configmaps we can decouple the container image from the configuration artifacts.
If configmaps are marked as "optional" they don't need to be mounted before a pod wants to use them.
They can be consumed in various ways:
- Pod environmental variables from single or multiple ConfigMaps
- Use ConfigMap values in Pod commands
- Populate Volume from ConfigMap
- Add ConfigMap data to a specific path in Volume
- Set file names and access mode in Volume from ConfigMap data
- Can be used by system components and controllers.
Create a Configmap from literal:
kubectl create cm yourcm --from-literal yoursecret=topsecret
Create a Configmap from a file:
kubectl -f your-cm.yaml create
Sample ConfigMap:
apiVersion: v1
data:
yoursecret: topsecret
level: "3"
kind: ConfigMap
metadata:
name: yourcm
read the configmap
kubectl get configmap yourcm -o yaml
Secrets
This kind of storage is used to store sensitive data, that needs to be encoded.
A Secret in Kubernetes is base64-encoded by default.
If you want to encrypt secrets, you have to create a EncryptionConfiguration.
There is no limit to the number of secrets, but there is a 1MB limit to their size.
Secrets are stored in the tmpfs storage on the host node and are only sent to the host running Pod.
Secret as an environmental variable
kubectl get secrets
kubectl create secret generic --help
kubectl create secret generic mysecret --from-literal=password=supersecret
spec:
containers:
-image: yourimage
name: yourcontainername
env:
- name: ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: yoursecret
key: password
Mounting secrets as volumes
spec:
containers:
- image: busybox
name: busy
command:
- sleep
- "3600"
volumeMounts:
- mountPath: /mysqlpassword
name: mysql
volumes:
- name: mysql
secret:
secretName: mysql
Verify that the secret is available in thte container:
kubectl exec -ti busybox -- cat /mysqlpassword/password
Further reading:
https://trainingportal.linuxfoundation.org/learn/course/kubernetes-for-developers-lfd259/
Volumes on Kubernetes: https://kubernetes.io/docs/concepts/storage/volumes/
Ceph: https://ubuntu.com/ceph/what-is-ceph
Top comments (0)