Video Thumbnail for Lesson
4.13: PersistentVolume & PersistentVolumeClaim

PersistentVolume & PersistentVolumeClaim

In Kubernetes, pods are ephemeral and their files disappear when the pod is rescheduled. PersistentVolumes (PV) and PersistentVolumeClaims (PVC) provide a way to attach durable storage so data can survive container restarts.

A PV represents a piece of storage within the cluster. A PVC is a request for that storage by a user or application. PVCs are typically fulfilled automatically using a StorageClass, which defines how the storage should be provisioned.

Common access modes include:

  • ReadWriteOnce (RWO) – mounted as read-write by a single node.
  • ReadWriteOncePod (RWO-Pod) – mounted as read-write by a single pod even if multiple pods share the node.
  • ReadOnlyMany (ROX) – mounted read‑only by many pods.
  • ReadWriteMany (RWX) – mounted read‑write by many pods across nodes.

A StorageClass can also define a reclaim policy. Retain keeps the underlying volume when the PVC is deleted (you must clean it up manually). Delete removes the volume automatically when its claim is removed.

For StatefulSets, a PVC retention policy controls what happens when replicas are scaled down or the StatefulSet is deleted. The default is to retain the PVCs, but you can choose to delete them automatically.

Hands-On: Working with PersistentVolumes

The accompanying repository contains examples for multiple clusters: a local kind cluster and managed clusters on Civo and GKE. Each example has tasks defined in a Taskfile.

1. Create a Namespace

# task 01-create-namespace
# - Create a namespace for these examples and set as default
kubectl apply -f Namespace.yaml
kubens 04--persistentvolume

2. Manually Provision a PV and PVC (kind)

This example shows a hostPath volume pre-created on a specific node. The pod mounts the PVC at /some/mount/path.

# task 02-apply-manual-pv-pvc-pod-kind
# - Apply the configuration for a manually provisioned local PVC and a pod to consume it
kubectl apply -f kind/PersistentVolume.manual-kind.yaml
kubectl apply -f kind/PersistentVolumeClaim.manual-pv-kind.yaml
kubectl apply -f kind/Pod.manual-pv-and-pvc-kind.yaml

3. Dynamically Provision a PVC Used by a Deployment (kind)

Here Kubernetes creates the backing volume automatically using the standard StorageClass.

# task 03-apply-dynamic-pv-pvc-deployment-kind
# - Apply the configuration for a dynamically provisioned local PVC and a deployment to consume it
kubectl apply -f kind/PersistentVolumeClaim.dynamic-pv-kind.yaml
kubectl apply -f kind/Deployment.shared-pvc-kind.yaml

4. StatefulSet with VolumeClaimTemplates (kind)

Each replica in the StatefulSet gets its own PVC created from the template.

# task 04-apply-dynamic-pv-pvc-statefulset-kind
# - Apply the configuration for a StatefulSet which provisions PVCs from a template
kubectl apply -f kind/StatefulSet.individual-pvcs-kind.yaml

5. Deploy the StatefulSet on Civo

# task 05-apply-dynamic-pv-pvc-statefulset-civo
# - Apply the configuration for a StatefulSet which provisions PVCs from a template (Civo)
kubectl apply -f civo/StatefulSet.individual-pvcs-civo.yaml

6. Deploy the StatefulSet on GKE

# task 06-apply-dynamic-pv-pvc-statefulset-gke
# - Apply the configuration for a StatefulSet which provisions PVCs from a template (GKE)
kubectl apply -f gke/StatefulSet.individual-pvcs-gke.yaml

7. Delete the Namespace to Clean Up

Deleting the namespace removes the PVs, PVCs and pods created for these examples.

# task 07-delete-namespace
# - Delete the namespace to clean up
kubectl delete -f Namespace.yaml