Kubernetes allows using compute volumes as persistent storage for pods. Persistent volumes (PV) exist independently of pods, meaning that such a volume persists after the pod it is mounted to is deleted. This PV can be mounted to other pods for accessing data stored on it. You can provision PVs dynamically, without having to create them manually, or statically, using volumes that exist in the compute cluster.
Creating storage classes
In LS Cloud, storage classes map to compute storage policies defined in the admin panel. Creating a storage class is required for all storage operations in a Kubernetes cluster.
To create a storage class
Сlick + Create on the Kubernetes dashboard and specify a YAML file that defines this object. For example:
apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: mysc provisioner: cinder.csi.openstack.org parameters: type: default
This manifest describes the storage class mysc
with the storage policy default
. The storage policy must exist in the compute cluster and be specified in the storage quotas to the current project.
Dynamically provisioning persistent volumes
Persistent volumes can be dynamically provisioned via persistent volume claims (PVC). A PVC requests for a PV of a specific storage class, access mode, and size. If a suitable PV exists in the cluster, it is bound to the claim. If suitable PVs do not exist but can be provisioned, a new volume is created and bound to the claim. Kubernetes uses a PVC to obtain the PV backing it and mounts it to the pod.
Prerequisites
- A pod and the persistent volume claim it uses must exist in the same namespace.
To dynamically provision a PV to a pod
- Access the Kubernetes cluster via the dashboard. Click Kubernetes access for instructions.
- On the Kubernetes dashboard, create a storage class, as described in Creating storage classes.
- Create a persistent volume claim. To do it, click + Create and specify the following YAML file:
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: mypvc spec: accessModes: - ReadWriteOnce resources: requests: storage: 10Gi storageClassName: mysc
This manifest specifies the persistent volume claim mypvc
that requests from the storage class mysc
a volume of at least 10 GiB that can be mounted in the read/write mode by a single node.
Creation of the PVC triggers dynamic provisioning of a persistent volume that satisfies the claim’s requirements. Kubernetes then binds it to the claim.
- Create a pod and specify the PVC as its volume. To do it, click + Create and enter the following YAML file:
apiVersion: v1 kind: Pod metadata: name: nginx spec: containers: - image: nginx imagePullPolicy: IfNotPresent name: nginx ports: - containerPort: 80 protocol: TCP volumeMounts: - mountPath: /var/lib/www/html name: mydisk volumes: - name: mydisk persistentVolumeClaim: claimName: mypvc readOnly: false
This configuration file describes the pod nginx
that uses the persistent volume claim mypvc
. The persistent volume bound to the claim will be accessible at /var/lib/www/html inside the nginx
container.
Statically provisioning persistent volumes
You can mount existing compute volumes to pods using static provisioning of persistent volumes.
To mount a compute volume
- In the self-service panel, obtain the ID of the desired volume.
- Access the Kubernetes cluster via the dashboard. Click Kubernetes access for instructions.
- On the Kubernetes dashboard, create a storage class, as described in Creating storage classes.
- Create a persistent volume. To do it, click + Create and specify the following YAML file:
apiVersion: v1 kind: PersistentVolume metadata: annotations: pv.kubernetes.io/provisioned-by: cinder.csi.openstack.org name: mypv spec: accessModes: - ReadWriteOnce capacity: storage: 10Gi csi: driver: cinder.csi.openstack.org fsType: ext4 volumeHandle: c5850e42-4f9d-42b5-9bee-8809dedae424 persistentVolumeReclaimPolicy: Delete storageClassName: mysc
This manifest specifies the persistent volume mypv
from the storage class mysc
that has 10 GiB of storage and access mode that allows it to be mounted in the read/write mode by a single node. The PV mypv
uses the compute volume with the ID c5850e42-4f9d-42b5-9bee-8809dedae424
as backing storage.
- Create a persistent volume claim. Before you define the PVC, make sure the PV is created and has the status “Available”. The existing PV must meet the claim’s requirements to storage size, access mode and storage class. Click + Create and specify the following YAML file:
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: mypvc spec: accessModes: - ReadWriteOnce resources: requests: storage: 10Gi storageClassName: mysc
Once the persistent volume claim mypvc
is created, the volume mypv
is bound to it.
- Create a pod and specify the PVC as its volume. Use the example from Step 4 in Dynamically provisioning persistent volumes.
In the self-service panel, the compute volume will be mounted to the virtual machine running the Kubernetes pod.
Making Kubernetes deployments highly available
If a node that hosts a Kubernetes pod fails or becomes unreachable over the network, the pod is stuck in a transitional state. In this case, the pod's persistent volumes are not automatically detached, and it prevents the pod redeployment on another worker node. To make your Kubernetes applications highly available, you need to enforce the pod termination in the event of node failure by adding rules to the pod deployment.
To terminate a stuck pod
Add the following lines to the spec
section of the deployment configuration file:
terminationGracePeriodSeconds: 0 tolerations: - effect: NoExecute key: node.kubernetes.io/unreachable operator: Exists tolerationSeconds: 2 - effect: NoExecute key: node.kubernetes.io/not-ready operator: Exists tolerationSeconds: 2
If the node's state changes to “NotReady” or “Unreachable”, the pod will be automatically terminated in 2 seconds.
The entire YAML file of a deployment may look as follows:
apiVersion: apps/v1 kind: Deployment metadata: name: nginx spec: replicas: 1 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: terminationGracePeriodSeconds: 0 tolerations: - effect: NoExecute key: node.kubernetes.io/unreachable operator: Exists tolerationSeconds: 2 - effect: NoExecute key: node.kubernetes.io/not-ready operator: Exists tolerationSeconds: 2 containers: - image: nginx imagePullPolicy: IfNotPresent name: nginx ports: - containerPort: 80 protocol: TCP volumeMounts: - mountPath: /var/lib/www/html name: mydisk volumes: - name: mydisk persistentVolumeClaim: claimName: mypvc
The manifest above describes the deployment nginx with one pod that uses the persistent volume claim mypvc and will be automatically terminated in 2 seconds in the event of node failure.