Kubernetes Persistent Volumes and Persistent Volume Claim
A persistent volume (PV) is a piece of storage in the Kubernetes cluster, while a persistent volume claim (PVC) is a request for storage.
Persistent volume (PV) is a piece of storage provided by an administrator in a Kubernetes cluster. When a developer needs persistent storage for an application in the cluster, they request that storage by creating a persistent volume claim (PVC) and then mounting the volume to a path in the pod. Once that is done, the pod claims any volume that matches its requirements (such as size, access mode, and so on). An administrator can create multiple PVs with different capacities and configurations. It is up to the developer to provide a PVC for storage, and then Kubernetes matches a suitable PV with the PVC. If there is no PV to match the PVC, the StorageClass dynamically creates a PV and binds it to the PVC.
Kubernetes(k8s) is a container orchestrator tool for deploying and managing containerized applications. Applications deployed on Kubernetes are often stateless, meaning that the applications do not rely on any previously saved data in the cluster to function properly. However, there are scenarios where you need to deploy applications that collect and store data that must be always available, even when you terminate the pod. This is where Kubernetes’ persistent volumes come in.
It is important to note that Kubernetes does not restrict PVs to a namespace, which means that a pod in any namespace can claim a PV for storage.
Understanding Persistent Volumes (PV)
Below is an example of a PersistentVolume YAML file used for creating persistent volume storage:
apiVersion: v1
kind: PersistentVolume
metadata:
name: persistent-volume
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/mnt/data"
storageClassName: slow
Now, let’s talk about the specifications of this YAML file.
Capacity
When creating a PV, you indicate its storage size in the Capacity attribute. In the example above, you are creating a PV of 10 gibibytes.
Access Modes
There are currently four access modes for PVs in Kubernetes:
- ReadWriteOnce: This allows only a single node to access the volume in read-write mode. Furthermore, all pods in that single node can read and write to such volumes.
- ReadWriteMany: Multiple nodes can read and write to the volume.
- ReadOnlyMany: This means that the volume will be in a read-only mode and accessible by multiple nodes.
- ReadWriteOncePod: Only a single pod can gain access to the volume.
Note: However, not all storage providers support the four access modes, so the available mode will vary.
StorageClassName
The storageClassName is the name of the storage class that will bind the PV to the user’s PVC. When a developer needs storage, they request it by creating a PVC.
The following is an example of a StorageClass manifest file used in creating a Storage Class:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: standard
provisioner: kubernetes.io/aws-ebs
parameters:
type: gp2
reclaimPolicy: Retain
allowVolumeExpansion: true
mountOptions:
- hard
volumeBindingMode: Immediate
We can better understand the above manifest file by explaining some of its keys.
Provisioner
The provisioner determines the volume plug-in used by the storageClass. Several plug-ins such as AWS EBS and GCE PD are available for different storage providers.
Parameters
Parameters contain available configurations accepted by the provisioner.
Allow Volume Expansion
When you set the allowVolumeExpansion value to true, the Storage Class can expand the PVs attached to it. To expand a PV, edit the configuration of the PVC` to the new capacity you need.
It is important to note that AllowVolumeExpansion is only used for volume expansion and not for shrinking.
Mount Options
The value specified in the MountOptions key will be used when creating dynamic PVs.
Persistent Volume Claims
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. Pods can request specific levels of resources (CPU and Memory). Claims can request specific size and access modes (e.g., they can be mounted ReadWriteOnce, ReadOnlyMany or ReadWriteMany.
Here is an example of a persistent volume claim manifest file:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: backend-claim
spec:
accessModes:
- ReadWriteOnce
volumeMode: Filesystem
resources:
requests:
storage: 10Gi
storageClassName: slow
Lifecycle of Persistent Volume and Volume Claim
Now since you have a decent understanding of persistent volumes and persistent volume claims, we can have a look at the interaction between PVs and PVCs.
Provisioning
There are two ways of provisioning PVs in a k8s/ocp cluster, static and dynamic.
Statically provisioned volumes is the process where cluster administrators create several persistent volumes for consumption, which carry the details of the storage to be used in the cluster using a PV manifest file.
Dynamically provisioned volumes are dynamically created when a StorageClass provisions a dynamic PV for the PVC because none of the PVs created by the cluster administrator match the PVC requirements.
Binding
When you create a new PVC, you specify the amount of storage your application needs. There is a control loop in the master plane that watches for new PVCs . Once this loop detects a new PVC, it automatically finds a PV that matches the PVC requests and binds the two. However, if an appropriate PV for the PVC does not exist, the StorageClass dynamically creates the PV for the PVC.
In some scenarios, a PVC can remain indefinitely unbound because a matching PV does not exist or the associated StorageClass cannot create the PV. For example, a cluster provisioned with many 50Gi PVs would not match a PVC requesting 100Gi. The PVC can be bound when a 100Gi PV is added to the cluster.
Using
You configure your application pod to use the PVC as a volume. Once you deploy the pod, Cluster looks for the PV associated with the PVC and mounts it to the pod. Once the claim is bound, the PV belongs to you as long as you need it, and no other developer in the cluster can use it. Users schedule application pods and access their claimed PVs by including a persistentVolumeClaim
section in a Pod's volumes
block.
Storage Object in Use Protection
The cluster uses this protection to ensure that the system does not delete PVs and PVCs currently being used by a pod. For instance, if you accidentally delete a PVC while a pod is still using it, the system won’t remove it until it’s no longer in use by the pod. Likewise, if a cluster administrator deletes a PV that is already bound to a PVC, the system won’t delete the PV until Kubernetes unbinds the PVC from the PV.
You can see that a PVC is protected when the PVC’s status is Terminating
and the Finalizers
list includes kubernetes.io/pvc-protection
:
kubectl describe pvc hostpath
Name: hostpath
Namespace: default
StorageClass: example-hostpath
Status: Terminating
Volume:
Labels: <none>
Annotations: volume.beta.kubernetes.io/storage-class=example-hostpath
volume.beta.kubernetes.io/storage-provisioner=example.com/hostpath
Finalizers: [kubernetes.io/pvc-protection]
...
You can see below that a PV is protected when the PV’s status is Terminating
and the Finalizers
list includes kubernetes.io/pv-protection
too:
kubectl describe pv task-pv-volume
Name: task-pv-volume
Labels: type=local
Annotations: <none>
Finalizers: [kubernetes.io/pv-protection]
StorageClass: standard
Status: Terminating
Claim:
Reclaim Policy: Delete
Access Modes: RWO
Capacity: 1Gi
Message:
Source:
Type: HostPath (bare host directory volume)
Path: /tmp/data
HostPathType:
Events: <none>
Reclaiming
Once you are done with a PV usage, you can free it up for other developers in the cluster to use by deleting the PVC object. The reclaim policy defined in the PV informs the cluster of what to do after Kubernetes unbinds it from a PVC. The retain policy attribute can have one of the following values: Retained, Recycled, or Deleted.
Expanding Persistent Volumes Claims
There might be an scenarios where your application might require a larger volume, especially when it already exceeds the capacity limit. To increase the storage, edit the PVC object and specify a larger capacity than you need.
It is important to note that you shouldn’t directly edit the capacity of the PV, but rather the PVC. Furthermore, if you edit both the capacity of the PV and PVC to have the same size, the Kubernetes control plane will assume that the backing volume size has been manually increased and that it doesn’t need to resize it.
Thanks for reading…
Happy Learning… If you find this helpful please do clap and follow my blog..