In this article, we are going to explain Kubernetes Persistent Volume in very simple words and clarify your Kubernetes concepts.
In general, a volume is a place or directory or a filesystem where data is stored or saved. Now, this volume can be ephemeral which means data in the volume is lost or it can be a persistent volume where data is still present even if the mount point, server, or container is deleted.
In Kubernetes, a volume is a way to store data outside of a container’s file system. Some volumes allow you to persist data even if the container is deleted or recreated. There are different types of volumes, such as hostPath, emptyDir, and configMap, which allow you to store data on the host’s file system, in memory, or as configuration data, respectively.
But this article will explain “Kubernetes persistent volume” and why it is needed in detail and with examples. If you would like to know more about or difference between emptyDir, hostPath or any other volume, just let us know through comments.
Table of Contents
Why Kubernetes Persistent Volume is Required?
In very simple words, you require Kubernetes persistent volume to have Kubernetes containers access to persistent data all the time.
You might be knowing, in Docker or Kubernetes, containers restart all the time, so just think of a time when a critical application is running on a container and the container just restarts due to an error.
If the container does not have a persistent volume, the data will be lost and you won’t be able to bring your application back until you have the backup. That is why you need persistent volume in Kubernetes or any other DevOps tool.
What is Kubernetes Persistent Volume?
As you know Kubernetes destroys ephemeral volumes such as emptyDir, To address these limitations, Kubernetes has a concept called Persistent Volumes (PVs).
Kubernetes does not destroy persistent volumes and data is preserved across container restarts.
A Persistent Volume is a piece of storage in your cluster that has been provisioned by an administrator or dynamically provisioned by a cloud provider. The administrator creates a Persistent Volume Claim (PVC), which requests a specific amount of storage and access mode (e.g., read/write).
The Kubernetes scheduler then matches the PVC to a PV that satisfies the claim’s requirements.
Simple Example of Kubernetes Persistent Volume
Now let’s look at a very simple example of a Persistent volume. For this example, we are going to use “hostPath PersistentVolume“. It is not recommended to use hostPath for various reasons though.
In this example, we will just mount a local directory “/var/data” on the container at “/app-logs” to store some data.
Below is the sample configuration file, which will create a pod name “webserver” with a container name “web” and will use the image “nginx”. For mounting a local directory, we are going to use the volume option as you can see in the below config file.
Save this file as web.yaml and run the kubectl command “kubectl apply -f web.yaml“.
apiVersion: v1 kind: Pod metadata: name: webserver spec: containers: - image: nginx name: web volumeMounts: - mountPath: /app-logs name: log-vol volumes: - name: log-vol hostPath: # directory location on the host path: /var/data
Once you have applied the config, you can check the pod status and then “exec” to the container to create some files.
controlplane ~ kubectl exec webserver -it -- bash [email protected]:/# echo "hi" > /app-logs/hi.txt [email protected]:/# echo "hello" > /app-logs/hello.txt
Once files are created, you can exit the container and check the local system for the files. Even if you delete the pod now, those files will still exist on the local system.
controlplane ~ ls /var/data hello.txt hi.txt
Advance Example of Kubernetes Persistent Volume
Here’s an example to illustrate how PVs and PVCs work together.
Let’s say you have an application that requires 1G of disk space. You would create a PVC that requests 1G of storage with a specific access mode.
The Kubernetes scheduler would then match the PVC to a PV that provides 1G of storage with the same access mode. The pod that runs your application would then mount the PV as a volume, allowing the application to persist data even if the pod is deleted or recreated.
Sample Persistent Volume Configuration Example:
apiVersion: v1 kind: PersistentVolume metadata: name: pv-vol labels: type: local spec: storageClassName: manual capacity: storage: 1Gi accessModes: - ReadWriteOnce hostPath: path: "/var/data"
To create Persistent Volume (PV) from this configuration, save it as a YAML file and run “kubectl apply” command
controlplane ~ ➜ kubectl apply -f pv.yaml persistentvolume/pv-vol created
Now to check created Kubernetes Persistent Volume, run the command “kubectl get pv“.
controlplane ~ kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pv-vol 1Gi RWO Retain Available manual 7s
Now, create a Persistent volume claim (PVC) using the above PV. Use the below sample configuration file for PVC, save it as pvc.yaml, and run “kubectl apply -f pvc.yaml”.
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: pv-vol spec: storageClassName: manual accessModes: - ReadWriteOnce resources: requests: storage: 1Gi
Note: Please make sure the name field under metadata is the same as Persistent volume, else it will not be bound.
Once PVC is created, run the below commands to check that Persistent Volume Claim (pvc) is created and it has bound with Persistent volume (pv).
controlplane ~ kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE pv-vol Bound pv-vol 1Gi RWO manual 64s controlplane ~ kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pv-vol 1Gi RWO Retain Bound default/pv-vol manual 4m3s
Now, once PV and PVC are created, use PersistentVolumeClaim (PVC) in a pod to mount a Persistent volume.
Below is the sample configuration file for the pod.
apiVersion: v1 kind: Pod metadata: name: webserver spec: volumes: - name: storage-vol persistentVolumeClaim: claimName: pv-vol containers: - name: webserver image: nginx ports: - containerPort: 80 name: "http-server" volumeMounts: - mountPath: "/usr/share/nginx/html" name: storage-vol
Now to test that our volume is currently mounted and working fine, just create an index.html file in the local directory and as it is mounted in the container we should be able to successfully test our nginx webserver.
echo 'Persistent Volume Mount is Success' > /var/data/index.html
Now just log in to the Kubernetes container using the “kubectl exec” command and curl localhost. If you see the message present in the index.html file, it means we have successfully mounted the local directory to the container.
controlplane ~ ➜ kubectl exec webserver -it -- bash [email protected]:/# curl localhost Persistent Volume Mount is Success [email protected]:/#
So this is how you can use Kubernetes Persistent volume and save container data across reboots.
We hope that now the Persistent volume concept is clear to you and you can easily use it in your applications. If you like the tutorial, please consider sharing the article and join our free newsletter for more such Kubernetes tutorials.