DEV Community

Cover image for Kubernetes Volumes
Barbara
Barbara

Posted on

Kubernetes Volumes

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: {}  
Enter fullscreen mode Exit fullscreen mode

$ 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"
Enter fullscreen mode Exit fullscreen mode

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:

  1. RWO - ReadWriteOnce by a single node
  2. ROX - ReadOnlyMany by multiple nodes
  3. RWX - ReadWriteMany by many nodes

kubectl get pvc

Phases to persistent storage

  1. Provisioning: Can be done in advance, ie resources from a cloud provider
  2. Binding: Once a watch loop on master notices a PVC it requests the access.
  3. Using: The volume is mounted to the Pod and can now be used.
  4. Releasing: When the pod is down, the PVC is deleted. The resident data remains depending on the persitenVolumReclaimPolicy
  5. 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: {}
Enter fullscreen mode Exit fullscreen mode

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 
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Mounting secrets as volumes

spec:
    containers:
    - image: busybox
      name: busy
      command:
        - sleep
        - "3600"
      volumeMounts:
      - mountPath: /mysqlpassword
        name: mysql
    volumes:
    - name: mysql
      secret:
        secretName: mysql
Enter fullscreen mode Exit fullscreen mode

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)