Kubernetes ContainerDevOps AutomationDevOps GuidesKubernetes Guide

Article & Tutorial

Kubernetes Volumes, PersistentVolumes and PVC Explained

Learn Kubernetes storage with Volumes, PersistentVolumes, PersistentVolumeClaims, StorageClasses, access modes, reclaim policies, dynamic provisioning,…

Kubernetes volumes, PersistentVolumes and PersistentVolumeClaims workflow
Kubernetes volumes, PersistentVolumes and PersistentVolumeClaims workflow
Contents

Kubernetes Volumes, PV and PVC Explained

Learn how Kubernetes keeps application data beyond Pod restarts using Volumes, PersistentVolumes, PersistentVolumeClaims and StorageClasses.

Why Kubernetes storage is different

Containers and Pods are replaceable. A container filesystem normally disappears when the container is recreated. A Pod may also move to another node during rescheduling. Persistent storage separates application data from the lifecycle of a specific container or Pod.

Ephemeral data

Temporary files, caches and scratch space that may disappear with the Pod.

Persistent data

Database files, uploaded documents and application state that must survive Pod replacement.

External storage

Cloud disks, network filesystems, CSI-backed storage and other systems mounted into workloads.

The storage relationship

Volume, PV, PVC and StorageClass

  • Object — Purpose — Managed by
  • Volume — Makes storage available inside a Pod. — Workload author
  • PersistentVolume — Represents cluster storage with capacity and access rules. — Administrator or dynamic provisioner
  • PersistentVolumeClaim — Requests storage with a size, access mode and optional StorageClass. — Application team
  • StorageClass — Defines how storage is dynamically provisioned. — Cluster or platform team

Common volume types

  • emptyDir : temporary storage shared by containers in one Pod.
  • configMap and secret : mount configuration data as files.
  • persistentVolumeClaim : attach persistent storage requested through a PVC.
  • hostPath : mounts a node path and should generally be avoided for portable production workloads.
  • CSI volumes: storage supplied through a Container Storage Interface driver.

Example: emptyDir for temporary shared files

apiVersion: v1 kind: Pod metadata: name: shared-cache spec: containers: - name: writer image: busybox command: ["sh", "-c", "echo hello > /cache/message; sleep 3600"] volumeMounts: - name: cache mountPath: /cache - name: reader image: busybox command: ["sh", "-c", "cat /cache/message; sleep 3600"] volumeMounts: - name: cache mountPath: /cache volumes: - name: cache emptyDir: {}

The data survives individual container restarts inside that Pod, but it disappears when the Pod is removed.

Static PersistentVolume example

apiVersion: v1 kind: PersistentVolume metadata: name: app-pv spec: capacity: storage: 10Gi accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Retain storageClassName: manual hostPath: path: /data/app

PersistentVolumeClaim example

apiVersion: v1 kind: PersistentVolumeClaim metadata: name: app-data namespace: dev spec: accessModes: - ReadWriteOnce storageClassName: manual resources: requests: storage: 5Gi

Kubernetes attempts to bind this claim to a compatible PV. Capacity, access mode, StorageClass and other constraints must match.

Use the PVC in a Deployment

apiVersion: apps/v1 kind: Deployment metadata: name: web namespace: dev spec: replicas: 1 selector: matchLabels: app: web template: metadata: labels: app: web spec: containers: - name: nginx image: nginx:1.27 volumeMounts: - name: data mountPath: /usr/share/nginx/html volumes: - name: data persistentVolumeClaim: claimName: app-data

Access modes explained

  • Mode — Meaning — Typical use
  • ReadWriteOnce (RWO) — Read-write by a single node. — Cloud block disks and many databases.
  • ReadOnlyMany (ROX) — Read-only by multiple nodes. — Shared read-only content.
  • ReadWriteMany (RWX) — Read-write by multiple nodes. — Shared network filesystems.
  • ReadWriteOncePod (RWOP) — Read-write by a single Pod where supported. — Strict single-writer workloads.

Dynamic provisioning with StorageClass

Dynamic provisioning removes the need to create each PV manually. When a PVC references a StorageClass, the CSI provisioner creates suitable storage automatically.

apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: fast-storage provisioner: example.csi.driver reclaimPolicy: Delete allowVolumeExpansion: true volumeBindingMode: WaitForFirstConsumer

apiVersion: v1 kind: PersistentVolumeClaim metadata: name: database-data spec: storageClassName: fast-storage accessModes: - ReadWriteOnce resources: requests: storage: 20Gi

Immediate versus WaitForFirstConsumer

Immediate provisions storage as soon as the claim is created. WaitForFirstConsumer delays binding until a Pod uses the claim, allowing Kubernetes to consider node topology and availability zones before selecting storage.

PV and PVC lifecycle

  1. A PVC is created and enters Pending .
  2. Kubernetes finds or provisions a compatible PV.
  3. The PV and PVC become Bound .
  4. A Pod mounts the claim.
  5. When the claim is deleted, the reclaim policy determines what happens to the underlying storage.

Reclaim policies

  • Policy — Behavior after PVC deletion — Use carefully because
  • Retain — The PV and underlying data are kept for manual recovery or cleanup. — An administrator must deliberately reclaim or delete the data.
  • Delete — The provisioned storage is normally deleted with the PV. — Deleting a PVC may permanently delete the underlying data.

Expand a PersistentVolumeClaim

Expansion works only when the StorageClass and CSI driver support it.

kubectl patch pvc database-data \ -p '{"spec":{"resources":{"requests":{"storage":"30Gi"}}}}' kubectl get pvc database-data kubectl describe pvc database-data

StatefulSets and storage

StatefulSets are often used for databases and clustered stateful applications because they provide stable Pod identities and can create one PVC per replica through volumeClaimTemplates .

volumeClaimTemplates: - metadata: name: data spec: accessModes: ["ReadWriteOnce"] storageClassName: fast-storage resources: requests: storage: 20Gi

Useful storage commands

kubectl get pv kubectl get pvc -A kubectl describe pvc app-data -n dev kubectl describe pv app-pv kubectl get storageclass kubectl get events -n dev --sort-by=.lastTimestamp kubectl get pod web-POD -n dev -o yaml

Why is my PVC Pending?

  • Cause — What to inspect — Typical correction
  • No matching PV — Requested size, access mode and StorageClass — Create a compatible PV or use dynamic provisioning.
  • StorageClass missing — kubectl get storageclass — Use an available class or configure a default class.
  • CSI provisioner failure — Events and CSI controller logs — Fix driver credentials, permissions, topology or quotas.
  • Topology conflict — Node zone and volume zone — Use WaitForFirstConsumer where suitable.
  • Insufficient capacity — PV capacities and backend limits — Request a supported size or add storage capacity.

Troubleshoot mount failures

kubectl describe pod APP_POD -n dev kubectl get events -n dev --sort-by=.lastTimestamp kubectl describe pvc app-data -n dev kubectl describe pv PV_NAME kubectl get volumeattachments

Common messages include FailedMount , FailedAttachVolume , multi-attach errors, missing CSI drivers and permission problems inside the mounted filesystem.

Backups and snapshots

A PV is not a backup. Protect important data using application-aware backups, database dumps, replication and CSI VolumeSnapshots where supported. Test restores regularly; a backup that has never been restored is only an assumption.

Common mistakes

  • Running a database only on the container filesystem.
  • Assuming all StorageClasses support RWX or volume expansion.
  • Deleting a PVC without checking the reclaim policy.
  • Using hostPath for production data that must survive node failure.
  • Creating multiple replicas that all expect exclusive write access to one RWO volume.
  • Treating snapshots as the only backup strategy.
  • Ignoring storage capacity and inode monitoring.

Production best practices

  • Use a supported CSI driver and documented StorageClasses.
  • Choose access modes based on the storage backend and application design.
  • Prefer WaitForFirstConsumer for topology-aware block storage.
  • Use dedicated PVCs for important stateful workloads.
  • Encrypt storage and protect backup credentials.
  • Monitor capacity, latency, IOPS, filesystem usage and failed mount events.
  • Document reclaim policies and deletion procedures.
  • Test failover, backup and restore before production incidents.

Hands-on practice lab

kubectl create namespace storage-lab kubectl apply -f pv.yaml kubectl apply -f pvc.yaml kubectl get pv,pvc -n storage-lab kubectl apply -f pod.yaml kubectl exec -n storage-lab storage-pod -- sh -c 'echo persistent > /data/test.txt' kubectl delete pod storage-pod -n storage-lab kubectl apply -f pod.yaml kubectl exec -n storage-lab storage-pod -- cat /data/test.txt

The final command demonstrates that the file remains when a new Pod mounts the same claim.

Frequently asked questions

No. A PVC is a request and reference. The data is stored in the underlying volume represented by the bound PV.

It depends on the access mode and storage backend. RWX supports multiple-node read-write mounting, while many block volumes provide RWO.

Yes, when the Pod uses persistent storage and the PVC/PV remain available.

That depends on the PV reclaim policy and storage provider. With Delete, the underlying storage may be removed.

No. Stateless services and temporary caches may not need persistent storage. Use PVCs when data must survive workload replacement.

Related Melochip guides

  • Kubernetes Learning Path
  • Kubernetes Pods Explained
  • Kubernetes Deployments and ReplicaSets
  • Docker Volumes Explained
  • Kubernetes Troubleshooting Guide

Official references

  • Kubernetes Persistent Volumes documentation
  • Kubernetes StorageClasses documentation

Did this help?

Yes No

Join the discussion

0 Comments

Ask questions, add context, or share what worked.

Sign in to join the discussion

No comments yet. Start the discussion.

More from Melochip Editorial

Related articles

Stay in the loop. Get new Melochip articles

Receive Melochip article updates when new articles are available. Explicit opt-in only.

No pre-checked boxes. Unsubscribe support is part of the subscriber foundation.