# Mastering Kubernetes Persistent Volumes: A Guide for Beginners 🚀 | Day 36 of 90DaysOfDevOps

Hi everyone, welcome to my #90DaysOfDevOps blog series where I share my daily learning and progress on DevOps. Today is day 36 and the focus is on understanding and managing Persistent Volumes (PVs) in Kubernetes deployments.

> The goal is to demystify PVs and provide a step-by-step guide on how to incorporate them into a Node Todo app. By the end of this post, you should confidently navigate the world of Kubernetes PVs.

Let's dive in! 🚀

## What are Persistent Volumes?

Persistent Volumes (PVs) in Kubernetes are virtual storage units, like digital hard drives, that enable applications to store and retrieve data. Unlike ephemeral storage, which is tied to the lifecycle of a pod, PVs exist independently of pods and can persist across pod restarts or failures. PVs are useful for applications that need to store stateful data, such as databases, logs, or configuration files.

## How to Add a Persistent Volume to a Node Todo App

In this section, I'll show you how to add a persistent volume to a Node Todo app, which is a simple web application that allows users to create and manage tasks.

We'll create a PV resource and a Persistent Volume Claim (PVC) resource to request and bind the PV. We'll also create a Service resource to expose the deployment pod within the cluster. Here are the steps:

1. Create a file named `pv.yaml` and paste the following content:
    

```yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-todo-app
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  hostPath:
    path: "/tmp/data"
```

This manifest defines a PV resource named `pv-todo-app` with a capacity of 1 GB, an access mode of ReadWriteOnce (which means it can be mounted by only one pod at a time), a reclaim policy of Retain (which means it will not be deleted when unbound), and a hostPath type (which means it will use a directory on the host node as storage).

1. Create another file named `pvc.yaml` and paste the following content:
    

```yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-todo-app
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 500Mi
```

This manifest defines a PVC resource named `pvc-todo-app` that requests 1 GB of storage, an access mode of ReadWriteOnce, no storage class, and a specific PV named `pv-todo-app` to bind to.

1. Create another file named `deployment.yaml` and paste the following content:
    

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: todo-app-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: todo-app
  template:
    metadata:
      labels:
        app: todo-app
    spec:
      containers:
        - name: todo-app
          image: ajitfawade14/node-todo-app
          ports:
            - containerPort: 8000
          volumeMounts:
            - name: pv-todo-app
              mountPath: /app
      volumes:
        - name: pv-todo-app
          persistentVolumeClaim:
            claimName: pvc-todo-app
```

This manifest defines a Deployment resource named `todo-app-deployment` that creates one pod with a container running the `node-todo-app` image. The container exposes port 8000 and mounts a volume named `pv-todo-app` at `/app` path. The volume uses the PVC named `pvc-todo-app` to claim the PV named `pv-todo-app`.

1. Create another file named `todo-svc.yaml` and paste the following content:
    

```yaml
apiVersion: v1
kind: Service
metadata:
  name: todo-app-svc
spec:
  selector:
    app: todo-app
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8000
      nodePort: 30007
  type: NodePort
```

This manifest defines a Service resource named `todo-app-svc` that exposes port 80 and targets the pods with the label `app:todo-app`. This service allows us to access our app from outside the cluster.

1. Apply the manifests to create the resources on the Kubernetes cluster:
    
    ```bash
    kubectl apply -f pv.yaml -f pvc.yaml -f deployment.yaml -f todo-svc.yaml
    ```
    
2. Verify that the resources are created:
    
    ```bash
    kubectl get pv,pvc,deploy,svc
    ```
    

You should see something like this:

```bash
NAME                           CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
persistentvolume/pv-todo-app   1Gi        RWO            Retain           Available                                   8s

NAME                                 STATUS    VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
persistentvolumeclaim/pvc-todo-app   Pending                                      local-path     8s

NAME                                  READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/todo-app-deployment   0/1     1            0           8s

NAME                   TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
service/kubernetes     ClusterIP   10.96.0.1        <none>        443/TCP        39d
service/todo-app-svc   NodePort    10.102.171.108   <none>        80:30007/TCP   8s
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1697137161363/25bfea98-566b-4d41-aa55-dc92c7fdf318.png align="center")

**Congratulations!**

You have successfully added a persistent volume to your Node Todo app.

## Conclusion

In this blog post, I learned how to add a persistent volume to a Node Todo app on Kubernetes. I learned how to create a PV resource, a PVC resource, a Deployment resource, and a Service resource for the Node Todo app. I also learned how to apply the manifests and verify the status of the resources on the Kubernetes cluster.

I hope you found this post useful and informative. If you have any questions or feedback, feel free to leave a comment below or reach out to me on LinkedIn or GitHub.

Thanks for reading and happy coding! 😊

LinkedIn: [https://www.linkedin.com/in/ajitfawade/](https://www.linkedin.com/in/ajitfawade/)

GitHub: [https://github.com/ajitfawade](https://github.com/ajitfawade)
