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).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 namedpv-todo-app
to bind to.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 thenode-todo-app
image. The container exposes port 8000 and mounts a volume namedpv-todo-app
at/app
path. The volume uses the PVC namedpvc-todo-app
to claim the PV namedpv-todo-app
.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 labelapp:todo-app
. This service allows us to access our app from outside the cluster.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
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! ๐ฅณ๐