Author: Vaishnavi Shivde
Kubernetes (k8s) is a powerful tool for managing containerized applications, and it comes with a variety of features to manage storage efficiently. Two key components in this storage management are Persistent Volume (PV) and Persistent Volume Claim (PVC). Let’s break these down! 🚀
🏔️ What is a Persistent Volume (PV)?
- Definition: A Persistent Volume (PV) is a piece of storage in the cluster that has been provisioned by an administrator or dynamically provisioned using Storage Classes.
- Lifespan: Exists independently of any individual pod’s lifecycle, providing persistent storage.
- Types of Storage: Can be backed by various storage systems like NFS, iSCSI, cloud providers, etc.
- Management: Managed by the Kubernetes API, offering a uniform API for different storage types.
Key Features:
- Persistent Storage: Ensures data is not lost even if the pod is destroyed.
- Decoupled from Pods: Exists independently of the pods using it.
- Reusability: Can be reused by different pods, maintaining the same data.
📑 What is a Persistent Volume Claim (PVC)?
- Definition: A Persistent Volume Claim (PVC) is a request for storage by a user. It is similar to a pod requesting specific compute resources (CPU and memory).
- Binding: When a PVC is created, Kubernetes looks for a PV that meets the request and binds them together.
- Dynamic Provisioning: If no suitable PV is found, Kubernetes can create a new PV dynamically (if Storage Classes are configured).
Key Features:
- Storage Requests: Users specify the size and access modes (ReadWriteOnce, ReadOnlyMany, ReadWriteMany).
- Binding to PV: Automatically binds to a matching PV, or triggers dynamic provisioning.
- Isolation: Ensures a user gets the storage requested and it is isolated from other users.
🎯 How PV and PVC Work Together
- Request and Provision: Users create a PVC specifying their storage requirements.
- Binding Process: Kubernetes finds a suitable PV and binds it to the PVC.
- Access: The PVC can then be used by pods to mount the storage defined by the PV.
🛠️ Practical Example
- Define a Persistent Volume:
apiVersion: v1
kind: PersistentVolume
metadata:
name: my-pv
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
hostPath:
path: /mnt/data
- Create a Persistent Volume Claim:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
- Use PVC in a Pod:
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-container
image: nginx
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: my-storage
volumes:
- name: my-storage
persistentVolumeClaim:
claimName: my-pvc
🔑 Key Benefits
- Persistence: Ensures data remains intact even if the pod is restarted or rescheduled.
- Flexibility: Decouples storage from pod lifecycle, enabling better management.
- Scalability: Supports dynamic provisioning, scaling storage needs on-demand.
Task: How to Add a Persistent Volume to a Node Todo App
- Create a Persistent Volume pv.yaml using a file on your node.
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).
2. Create a Persistent Volume Claim pvc.yaml that references the Persistent Volume.
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.
3. Update your deployment.yml file to include the Persistent Volume Claim. After Applying pv.yml pvc.yml your deployment file look like:
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: rishikeshops/todo-app
ports:
- containerPort: 8000
volumeMounts:
- name: todo-app-data
mountPath: /app
volumes:
- name: todo-app-data
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
.
4. Create service.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.
5. Apply the manifests to create the resources on the K8s cluster:
kubectl apply -f pv.yaml -f pvc.yaml -f deployment.yaml -f service.yaml
6. Verify that the resources are created:
kubectl get pv,pvc,deploy,svc
You should see something like this:Congratulations!
You have successfully added a persistent volume to your Node Todo app.
🚀 Conclusion
Understanding PVs and PVCs is crucial for efficient storage management in Kubernetes. By leveraging these components, you can ensure your applications have reliable and persistent storage, making your deployments more robust and scalable. Happy Kubernetes-ing! 🥳🎉
Author: Vaishnavi Shivde