Managing Persistent Volumes in Deployment | Kubernetes

Managing Persistent Volumes in Deployment | Kubernetes

·

6 min read

In my previous blog, I discussed how to master ConfigMaps and Secrets. In this blog, let's learn how to manage Persistent Volumes in Kubernetes!

Volumes in Kubernetes is a directory, possibly with some data in it, which is accessible to the containers in a pod. The way a directory is created, the medium it is stored on, and what it contains all depend on the type of volume that is used.

Different types of volumes supported in Kubernetes are configMap, emptyDir, hostPath, persistentVolumeClaim, etc.

Let's discuss more about Persistent Volumes and Persistent Volume Claims in Kubernetes.

Persistent Volumes

A PersistentVolume (PV) is a piece of storage that is managed by Kubernetes. It can be provisioned by an administrator or dynamically provisioned using Storage Classes. PVs are used to store data that needs to be persistent, such as databases or logs.

There are two types of PVs: Static (Static PVs are created by an administrator and are always available) and Dynamic (Dynamic PVs are created on demand and are destroyed when they are no longer needed).

Pods can access PVs through PersistentVolumeClaims (PVCs). I will discuss PVC in detail in the next section.

PV is a resource in the cluster just like a node is a cluster resource. PVs are volume plugins like Volumes but have a lifecycle independent of any individual Pod that uses the PV.

There are three Volume Access Modes:

  1. RWO(ReadWriteOnce)

  2. ROX(ReadOnlyMany)

  3. RWX(ReadWriteMany)

Persistent Volume Claims

PVC is a request for storage made by a pod in Kubernetes. When a pod is created, it will try to claim a PVC that matches its requirements. If a matching PVC is available, the pod will be assigned the storage.

PVCs are used to provide persistent storage for pods. This allows pods to store data that will not be lost when the pod is restarted or deleted.

PV's are high level and they represent storage in kubernetes.

PVC's are tickets that grants a pod access to PV.

SC(StorageClasses) are used to store the data on exteranl storage making PV dynamic.

In today's example, I will use Local Storage for the PV and PVC.

Benefits of PV and PVC

  • Data stored on a PV will not be lost when the pod is restarted or deleted. This is essential for applications that need to store data permanently, such as databases and logging systems.

  • Each pod can have its own PV, which isolates its data from other pods. This is important for security and performance reasons.

  • PVs can be dynamically provisioned, which allows pods to scale up or down as needed. This is important for applications that need to be able to handle fluctuating loads.

  • PVs and PVCs are easy to use and manage. They can be created and managed using the Kubernetes API or the kubectl command-line tool.

Lifecycle of Volume and Claim

The lifecycle of volume and claim involves the following:

  1. Provisioning: A PersistentVolume (PV) is provisioned. This can be done manually by an administrator or dynamically using a Storage Class.

  2. Binding: A PersistentVolumeClaim (PVC) is created. This specifies the type of storage that is needed, as well as the access mode.

  3. Using: A pod is created that uses the PVC. The pod will be assigned the storage that is specified in the PVC.

  4. Releasing: The pod is deleted. The PVC is released and the storage is made available for other pods.

  5. Reclaiming: The PV is deleted. This can be done manually by an administrator or automatically by Kubernetes.

The lifecycle of Volume is forever. It needs to be deleted manually.

Tasks

Task 1: Add a Persistent Volume to your Deployment todo app.

Heads-Up: I am using the directory /app to mount the volume.

I struggled the whole day to troubleshoot an issue: I was not able to mount the PV and PVC was failing. I figured out that, in the DockerFile the WORKDIR was set to /data and had to be set to /app.

If you are using the repository I have used, make sure you include the following in your dockerfile and build the image again:

RUN mkdir -p /app

WORKDIR /app

Let's create a Persistent Volume named pv.yml.

apiVersion: v1
kind: PersistentVolume
metadata:
  name: persistent-volume-todop
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  hostPath:
    path: "/tmp/data"

Let us create the Persistent Volume Claims named pvc.yml.

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: persistent-volume-claims-todo
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 500Mi

Let's update the deployment.yml file to include the Persistent Volume Claims.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-django-application
  namespace: deploy1
spec:
  replicas: 3
  selector:
    matchLabels:
      app: django-todo-app
  template:
    metadata:
      labels:
        app: django-todo-app
    spec:
      containers:
        - name: todo-app
          image: snehaks/django-todo:latest
          ports:
            - containerPort: 8000
          volumeMounts:
            - name: volume-todo-app-data
              mountPath: /app
      volumes:
        - name: volume-todo-app-data
          persistentVolumeClaim:
            claimName: persistent-volume-claims-todo

Let's apply all the above definitions one by one.

kubectl apply -f pv.yml 
kubectl apply -f pvc.yml
kubectl apply -f deployment.yml -n <namespace>

Let's check if the Persistent Volume has been added to my deployment by checking the status of the Pods and Persistent Volumes in my cluster.

kubectl get pv
kubectl get pvc
kubectl describe pvc <name>

And Yay! We have created PV and applied the PVC.

Task 2: Access the data in the Persistent Volume.

Let's connect to any pod in the cluster using:

kubectl exec -it <Pod_name> -n <namespace> -- /bin/bash

Now enter the /app directory, create a file, and exit the terminal.

cd /app
echo "hello" > test.txt

Let us delete this pod, so the K8s cluster will create a new pod using its auto-healing feature.

kubectl delete pods <pod_name> -n <namespace>

We can see that a new pod has got created before 15s:

Now make note of the Pod name. Go to the worker node and copy the corresponding container ID of the pod that just got created. Also, go to the /app directory to check if the volume is mounted or not.

docker ps -it <container_id> /bin/bash
cd /app
ls

And yay, the volume is mounted! That means I can access the data stored in the Persistent Volume from within the Pod.

As an alternative, we can use Storage Classes to mount the volume externally. I will try to get that as a separate blog explaining the same.


In this blog, I have discussed how to manage persistent volumes in our deployments in Kubernetes. If you have any questions or would like to share your experiences, feel free to leave a comment below. Don't forget to read my blogs and connect with me on LinkedIn and let's have a conversation.

To help me improve my blog and correct my mistakes, I am available on LinkedIn as Sneha K S. Do reach me and I am open to suggestions and corrections.

#Day36 #90daysofdevops

Did you find this article valuable?

Support Sneha K S by becoming a sponsor. Any amount is appreciated!