How to add Cinder as backing storage for persistent volumes

This guide describes how to add Cinder as backing storage for persistent volumes in Kubernetes and how to implement that into a deployment or pod.

Level

ADVANCED

Prerequisites

  • A CityCloud account.
  • A Kubernetes cluster deploy, either through RaaS (Rancher as a Service) or a cluster created by other means.
  • Kubectl software installed.

Overview

In this guide, we will follow the below steps:

  1. Inventory any pre-existing storage classes.
  2. Create a Cinder backed storage class (and make it default).
  3. Create a persistent volume.
  4. Create a persistent storage claim.
  5. Configure a pod to use our volume.

Inventory any pre-existing storage classes.

We need to be aware of any pre-existing storage classes to make a few decisions:

  • Do we make our storage class default instead?
  • Or do we keep the existing one as is and define which class to use later on in our deployment / pod definition?

To check if there are any storage classes in our cluster, we'll run this:

$ kubectl get storageclasses
NAME					PROVISIONER 			RECLAIMPOLICY 	VOLUMEBINDINGMODE 	ALLOWVOLUMEEXPANSION 	AGE
some-class (default)	kubernetes.io/cinder 	Delete 			Immediate 			false 					132d

Create a Cinder backed storage class (and make it default).

We need to let Kubernetes know that there is a Cinder backend and that it should be used as default.

This is not overly complex:

  • Create applicable yaml.
  • Apply to the cluster.

A example yaml :

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  annotations:
    storageclass.beta.kubernetes.io/is-default-class: "true"
    storageclass.kubernetes.io/is-default-class: "true"
  name: cinder
allowVolumeExpansion: false
provisioner: kubernetes.io/cinder
reclaimPolicy: Delete
volumeBindingMode: Immediate

This will create a default storageclass and when creating a persistent volume a volume in the "CityCloud Control Panel" and it'll be attached the appropriate Kubernetes node.

Create a persistent volume.

We will need to create a persistent volume that we'll later claim and attach to our pod.

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv01
spec:
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteOnce
  storageClassName: cinder

This specifies a few important things: capacity, storage class and access modes.

As we created a default storage class earlier, there is no need to specify it. But it is best practise.

The access mode specifies that only one node can allocate and use the volumes.

Create a persistent volume claim.

To be able to assign the created volume to our pod, we'll need to claim it.

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc01
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi
  storageClassName: cinder

Configure pod to use our volume.

The last piece of the puzzle is to actually attach the volume to a pod:

apiVersion: v1
kind: Pod
metadata:
  name: pod01
spec:
  containers:
    - name: nginx
      image: nginx
      volumeMounts:
      - mountPath: "/var/www/html"
        name: volume01
  volumes:
    - name: volume01
      persistentVolumeClaim:
        claimName: pvc01