Kubernetes volumes and workload portability

Gopi Narayanaswamy
5 min readJun 12, 2020

--

Kubernetes volumes are accessed by all containers running in a POD and volumes are maintained with the principle of workload portability. A kubernetes volume lives beyond the pods life cycle, the data in the volume persistent across container restart.

Persistent volumes are long-term storage in your Kubernetes cluster. Persistent volumes exist beyond containers, pods, and nodes.

There are types of volumes available are

local types such as emptyDir or hostPath

file-sharing types such as nfs

cloud volume types like awsElasticBlockStore, azureDisk, or gcePersistentDisk

distributed file system types, for example glusterfs , cephfs, Portworx

special-purpose types like secret, gitRepo

Kubernetes supports Ephemeral storage

The cluster stores temporary information that does not need to persist in the ephemeral storage. This improves performance and helps to reduce the load on the persistent storage.

Ephemeral storage must be a locally attached volume on each node.

Built of top the EmptyDir

Secrect volume, ConfigMap volume, cache are use cases of EmptyDir

Yaml manifest for EmptyDir

apiVersion: v1kind: Podmetadata:name: app1spec:containers:- image: k8s.gcr.io/test-webservername: web-containervolumeMounts:- mountPath: /cachename: cache-volumevolumes:- name: cache-volumeemptyDir: {}

By default, emptyDir volumes are stored on whatever medium is backing the node — that might be disk or SSD or network storage, depending on the environment. The pod created and use local disk and /cache directory

If you need more performance, you can modify the above definition so that the cache is served from the node’s memory:

apiVersion: v1kind: Podmetadata:name: app1spec:containers:- image: k8s.gcr.io/test-webservername: web-containervolumeMounts:- mountPath: /cachename: cache-volumevolumes:- name: cache-volumeemptyDir:medium: Memory

Remote Storage

Typically remote storage from Cloud Volumes or on prem storage iSCSI or NFS. Data persists beyond lifecycle of any POD, referenced in a POD either in-line or via PV/PVC.

Kubernetes automatically attach volume to Node and mount volume to POD

A PersistentVolume (PV) is a piece of storage in the cluster that has been provisioned by an administrator or dynamically provisioned using Storage Classes.

It is a resource in the cluster just like a node is a cluster resource.

PVs are volume plugins like Volumes, but have a lifecycle independent of any individual Pod that uses the PV.

The PV is not backed by locally-attached storage on a worker node but by remote storage

A PersistentVolumeClaim (PVC) is a request for storage by a user. It is similar to a Pod. Pods consume node resources and PVCs consume PV resources.

PersistentVolumeClaim objects request a specific size, access mode, and StorageClass for the PersistentVolume. If a PersistentVolume that satisfies the request exists or can be provisioned, the PersistentVolumeClaim is bound to that PersistentVolume.

PersistentVolumes support the following access modes:

ReadWriteOnce: The volume can be mounted as read-write by a single node.

ReadOnlyMany: The volume can be mounted read-only by many nodes.

ReadWriteMany: The volume can be mounted as read-write by many nodes.

Why PV and PVC are introduced?

Workload portability is to abstract away cluster details and decouples apps from infrastructure, enable user to write or implement an application once and run the application anywhere through workload portability

Kubernetes workload can be portable to any cloud or on prem

Kubernetes with workload portability

Portability is another advantage of using PersistentVolumes and PersistentVolumeClaims. You can easily use the same Pod specification across different clusters and environments because PersistentVolume is an interface to the actual backing storage.

Portability, How is it possible?

Below PV and PVC will determine the portability in the volume configuration

Create a pv001.yaml file

apiVersion:  v1kind: PersistentVolumemetadata:name: pv001spec:capacity:storage: 10GiaccessModes:- ReadWriteOncepersistentVolumeReclaimPolicy: RetaingcePersistentDisk:fsType: ext4pdName: disk1

Create PVC with pvc01.yaml

apiVersion: v1kind: PersistentVolumeClaimmetadata:  name: pvc001namespace: App-space spec:  accessModes:    - ReadWriteOnce  resources:    requests:      storage: 10Gi

$ kubectl create –f pv001.yaml

Persistentvolume “pv001” created

$ kubectl create –f pvc01.yaml

Persistentvolumeclaim “pvc001” created

Now create a pod

apiVersion: v1kind: Podmetadata:name: task-pv-podspec:volumes:- name: task-pv-storagepersistentVolumeClaim:claimName: pvc001containers:- name: task-pv-containerimage: nginxports:- containerPort: 80name: "http-server"volumeMounts:- mountPath: "/usr/share/nginx/html"name: task-pv-storage

The volume referenced via PVC and pod yaml is portable across clusters

Dynamic provisioning

There are some drawbacks in above PV creation, the volume may sometime pre-provisioned for future use, cluster administrators have to manually make calls to their cloud or storage provider to create new storage volumes, and then create PersistentVolume objects to represent them in Kubernetes.

Dynamic provisioning creates new volumes on-demand and dynamic provisioning enabled by creating storage class. StorageClass objects define which provisioner should be used and what parameters should be passed to that provisioner when dynamic provisioning is invoked.

The following manifest creates a storage class “slow” which provisions standard disk-like persistent disks.

apiVersion: storage.k8s.io/v1kind: StorageClassmetadata:name: slowprovisioner: kubernetes.io/gce-pdparameters:type: pd-standard

The following manifest creates a storage class “fast” which provisions SSD-like persistent disks.

apiVersion: storage.k8s.io/v1kind: StorageClassmetadata:name: fastprovisioner: kubernetes.io/gce-pdparameters:type: pd-ssd

To select the “fast” storage class, for example, a user would create the following PersistentVolumeClaim:

apiVersion: v1kind: PersistentVolumeClaimmetadata:name: claim1spec:accessModes:- ReadWriteOncestorageClassName: fastresources:requests:storage: 30Gi

Now create a pod

apiVersion: v1kind: Podmetadata:name: task-pv-podspec:volumes:- name: datapersistentVolumeClaim:claimName: cliam1containers:- name: task-pv-containerimage: nginxports:- containerPort: 80name: "http-server"volumeMounts:- mountPath: "/usr/share/nginx/html"name: data

Underlying volume data need to be migrated to target environment using storage provider tools or any migration tool. Kubernetes is having the provision of the application running in the pod created easily once data migrated

hostPath

A hostPath volume mounts a file or directory from the host node’s filesystem into the pod. For example, some uses for a hostPath are:

o running a container that needs access to Docker internals; use a hostPath of /var/lib/docker

o running cAdvisor in a container; use a hostPath of /dev/cgroups

Local Persistent Volume

Expose a local block or file as a persistent volume and useful for high performance caching. Referenced via PV/PVC so work load portability is maintained

--

--