Managing Persistent Volumes and Claims
Introduction
This tutorial guides you through managing persistent storage in Kubernetes using Persistent Volumes (PVs) and Persistent Volume Claims (PVCs). You will learn how to define, create, and utilize PVs and PVCs to provide persistent storage for your applications. A basic understanding of Kubernetes concepts (Pods, Deployments) is recommended.
Task 1: Understanding Persistent Volumes (PVs)
PVs are cluster-level resources representing a piece of storage in the cluster. They are provisioned by an administrator or dynamically provisioned using StorageClasses.
-
Define a Persistent Volume: Create a file named
pv.yamlwith the following content:NODE_TYPE // yamlapiVersion: v1 kind: PersistentVolume metadata: name: my-pv spec: capacity: storage: 1Gi accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Retain storageClassName: manual hostPath: path: "/mnt/data"hostPathis suitable for development/testing but is NOT recommended for production. In production, use cloud provider volumes (e.g.,awsElasticBlockStore,gcePersistentDisk). -
Explanation of the PV definition:
apiVersion: API version of the Kubernetes resource.kind: Specifies that this is a PersistentVolume.metadata.name: Name of the PV (e.g.,my-pv).spec.capacity.storage: Storage capacity of the volume (e.g.,1Gi).spec.accessModes: How the volume can be accessed:ReadWriteOnce: Can be mounted by a single node for read and write.ReadOnlyMany: Can be mounted by multiple nodes for read-only access.ReadWriteMany: Can be mounted by multiple nodes for read and write.
spec.persistentVolumeReclaimPolicy: What happens to the volume when the PVC is deleted:Retain: The volume remains and data is preserved. Requires manual cleanup.Delete: The volume and data are deleted (if supported by the underlying storage).Recycle: (Deprecated) The volume is scrubbed and made available for reuse.
spec.storageClassName: Name of the StorageClass to use for dynamic provisioning. Set tomanualwhen provisioning PVs directly.spec.hostPath.path: The path on the host node where the volume is located (forhostPathvolumes).
-
Create the Persistent Volume:
NODE_TYPE // bashkubectl apply -f pv.yamlNODE_TYPE // outputpersistentvolume/my-pv created -
Verify the Persistent Volume:
NODE_TYPE // bashkubectl get pv my-pvNODE_TYPE // outputNAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE my-pv 1Gi RWO Retain Available manual 10sTheSTATUSshould beAvailableif the PV is successfully created and not yet bound to a PVC.
Task 2: Understanding Persistent Volume Claims (PVCs)
PVCs are requests for storage by users. They specify the storage size, access modes, and other requirements.
-
Define a Persistent Volume Claim: Create a file named
pvc.yamlwith the following content:NODE_TYPE // yamlapiVersion: v1 kind: PersistentVolumeClaim metadata: name: my-pvc spec: accessModes: - ReadWriteOnce resources: requests: storage: 500Mi storageClassName: manual selector: matchLabels: name: my-pv -
Explanation of the PVC definition:
apiVersion: API version of the Kubernetes resource.kind: Specifies that this is a PersistentVolumeClaim.metadata.name: Name of the PVC (e.g.,my-pvc).spec.accessModes: The access modes required by the application (must be compatible with the PV).spec.resources.requests.storage: The amount of storage requested (e.g.,500Mi).spec.storageClassName: Must match thestorageClassNameof the PV to bind to it.spec.selector: Allows you to select specific PVs.
-
Create the Persistent Volume Claim:
NODE_TYPE // bashkubectl apply -f pvc.yamlNODE_TYPE // outputpersistentvolumeclaim/my-pvc created -
Verify the Persistent Volume Claim:
NODE_TYPE // bashkubectl get pvc my-pvcNODE_TYPE // outputNAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE my-pvc Bound my-pv 1Gi RWO manual 15sTheSTATUSshould beBoundif the PVC has been successfully bound to a PV. TheVOLUMEcolumn shows the name of the bound PV.
Task 3: Using a Persistent Volume Claim in a Pod
Now, let’s create a Pod that uses the PVC to access the persistent storage.
-
Define a Pod that uses the PVC: Create a file named
pod.yamlwith the following content:NODE_TYPE // yamlapiVersion: v1 kind: Pod metadata: name: my-pod spec: volumes: - name: my-volume persistentVolumeClaim: claimName: my-pvc containers: - name: my-container image: busybox:latest command: ["/bin/sh", "-c", "while true; do echo $(date) >> /data/output.txt; sleep 5; done"] volumeMounts: - mountPath: /data name: my-volume -
Explanation of the Pod definition:
apiVersion: API version of the Kubernetes resource.kind: Specifies that this is a Pod.metadata.name: Name of the Pod (e.g.,my-pod).spec.volumes: Defines the volumes to be used by the Pod.name: A name for the volume within the Pod.persistentVolumeClaim.claimName: The name of the PVC to use.
spec.containers: Defines the containers within the Pod.name: Name of the container.image: The container image to use.command: The command to run inside the container. In this example, it writes the current date to a file namedoutput.txtevery 5 seconds.volumeMounts: Specifies where to mount the volume inside the container.mountPath: The path inside the container where the volume will be mounted (e.g.,/data).name: The name of the volume defined inspec.volumes.
-
Create the Pod:
NODE_TYPE // bashkubectl apply -f pod.yamlNODE_TYPE // outputpod/my-pod created -
Verify the Pod:
NODE_TYPE // bashkubectl get pod my-podNODE_TYPE // outputNAME READY STATUS RESTARTS AGE my-pod 1/1 Running 0 20sTheSTATUSshould beRunningif the Pod has been successfully created and is running. -
Check the Data: Exec into the pod
NODE_TYPE // bashkubectl exec -it my-pod -- /bin/sh -
Read the log file
NODE_TYPE // bashcat /data/output.txt -
Example Log file output
NODE_TYPE // outputWed Apr 7 15:00:00 UTC 2026 Wed Apr 7 15:00:05 UTC 2026 Wed Apr 7 15:00:10 UTC 2026 -
Clean up (optional):
NODE_TYPE // bashkubectl delete pod my-pod kubectl delete pvc my-pvc kubectl delete pv my-pv
Conclusion
In this tutorial, you learned how to create and manage persistent storage in Kubernetes using Persistent Volumes and Persistent Volume Claims. You provisioned a PV, created a PVC, and mounted it in a Pod. Remember that hostPath is only suitable for development/testing and should be replaced with appropriate cloud provider storage in production environments.