Storage in Kubernetes


Using Pod Volumes

  • Pod Volumes are a part of the Pod specification and have the storage reference hard coded in the Pod manifest
  • This is not bad, but it doesn’t allow for flexible storage allocation
  • Pod Volumes can be used for any storage type
  • Also, the ConfigMap can be used to mount Pod Volumes

Example how simple share storage .


Managing Persistent Volumes

  • PersistentVolumes (PV) are an API resource that represents specific storage
  • PVs can be created manually, or automatically using StorageClass and storage provisioners
  • Pods do not connect to PVs directly, but indirectly using PersistentVolumeClaim (PVC)


Configuring PersistentVolumeClaim

  • PVCs allows Pods to connect to any type of storage that is provided at a
    specific site
  • Site-specific storage needs to be created as a PersistentVolume, either manually or automatically using StorageClass
  • Behind StorageClass a storage provisioner is required

Now let’s use pv in the pod:



  • StorageClass is an API resource that allows storage to be automatically
  • StorageClass can also be used as a property that connects PVC and PV without using an actual StorageClass resource
  • Multiple StorageClass resources can co-exist in the same cluster to provide access to different types of storage
  • For automatic working, one StorageClass must be set as default
    • kubectl patch storageclass mysc -p '{"metadata": {"annotations":{"":"true"}}}'

Using StorageClass

  • To enable automatic provisioning, StorageClass needs a backing storage provisioner
  • In the PV and PVC definition, a storageClass property can be set to connect to a specific StorageClass which is useful if multiple StorageClass resources are available
  • If the storageClass property is not set, the PVC will get storage from the default StorageClass
  • If also no default StorageClass is set, the PVC will get stuck in a status of Pending

Using an NFS Storage Provisioner

  • The Storage Provisioner works with a StorageClass to automatically provide storage
  • It runs as a Pod in the Kubernetes cluster, provided with access control configured through Roles, RoleBindings, and ServiceAccounts
  • Once operational, you don’t have to manually create PersistentVolumes anymore


  • To create a storage provisioner, access permissions to the API are required
  • Roles and RoleBindings are created to provide these permissions
  • A ServiceAccount is created to connect the Pod to the appropriate RoleBinding

Configuring a Storage Provisioner

  • On control:
    • Ubuntu: sudo apt install -y nfs-server
    • RHEL/Centos: sudo dnf install -y nfs-utils
  • On other nodes:
    • Debian/Ubuntu: sudo apt install nfs-client
    • RHEL/Centos:  sudo dnf install nfs-utils nfs4-acl-tools 
  • On control:
    • sudo mkdir /nfsexport
    • sudo sh -c 'echo "/nfsexport *(rw,no_root_squash)" > /etc/exports'
    • sudo systemctl restart nfs-server
  • On other nodes: showmount -e control



  • A ConfigMap is an API resource used to store site-specific data
  • A Secret is a base64 encoded ConfigMap
  • ConfigMaps are used to store either environment variables, startup parameters or configuration files
  • When a Configuration File is used in a ConfigMap or Secret, it is mounted as a volume to provide access to its contents

Creating a ConfigMap

  • echo "hello world" > index.html
  • kubectl create cm webindex --from-file=index.html
  • kubectl describe cm webindex
  • kubectl create deploy webserver --image=nginx
  • kubectl edit deploy webserver

Let’s checkout how to use ConfigMap as a volume.

Now edit the deployment webserver and  add volume in the spec section in the same level as container section:

Let’s test it:

That proves that ConfigMap has sucessfully been mounted.

Lab: Setting up Storage

  • Create a PersistentVolume, using the HostPath storage type to access the directory/storage
  • Create a file /storage/index.html, containing the text "hello lab4"
  • Run a Pod that uses an Nginx image and mounts the HostPath storage on the directory /usr/share/nginx/html
  • On the running Pod, use kubectl exec to verify the existence of the file /usr/share/nginx/html


The example yaml files you can find in the kubernetes documentation: -> persistent volume -> Configure a Pod to Use a PersistentVolume for Storage