6.4. Using Persistent Volumes for Kubernetes Pods¶
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.
6.4.1. Creating Storage Classes¶
In Virtuozzo Hybrid 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.
6.4.1.1. Creating 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.
6.4.2. 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.
6.4.2.1. Provisioning PV to Pod Dynamically¶
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 classmysc
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.
6.4.3. Statically Provisioning Persistent Volumes¶
You can mount existing compute volumes to pods using static provisioning of persistent volumes.
6.4.3.1. Mounting 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 classmysc
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 PVmypv
uses the compute volume with the IDc5850e42-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 volumemypv
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.
6.4.4. 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.
6.4.4.1. Terminating 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.