Published 2 November 2026 · Published by Zoorik

Short answer. A persistent volume (PV) is a piece of cluster storage whose lifecycle is independent of any pod that uses it. A PersistentVolumeClaim (PVC) is a request for that storage: it asks for a size and an access mode, and binds to one matching PV. Pods mount the claim, so the data stays when a pod is deleted or replaced.
Why pods need persistent volumes
When a container crashes or stops, the files it created or changed are lost. After a crash, the kubelet restarts it with a clean state.
Ephemeral volumes have a lifetime linked to one pod. Kubernetes destroys them when the pod ceases to exist, but it doesn’t destroy persistent volumes.
A PV is a resource in the cluster, just as a node is. The PV object records the details of the storage behind it, be that NFS, iSCSI or a cloud provider’s storage system.
What a Kubernetes PVC is and how it binds
A PVC is a user’s request for storage. Just as a pod requests CPU and memory from a node, a claim requests a size and access modes from a PV. It usually names a StorageClass too, and it lives in the same namespace as the pods that use it.
A control loop in the control plane watches for new claims and binds each one to a matching PV. The binding is one to one, and no other claim can use that PV. A claim always gets at least the size it asked for, and the PV may be larger.
A claim with no match stays unbound until one appears. In the docs’ example, a cluster with many 50 GiB PVs can’t bind a claim for 100 GiB. It binds once a 100 GiB PV is added.
A PV is always in one of four phases:
Available: free, and not yet bound to a claim.Bound: bound to a claim.Released: the claim was deleted, but the cluster hasn’t reclaimed the storage yet.Failed: its automatic reclamation failed.
Deleting a claim that a pod still uses doesn’t remove it at once, because that could lose data. The claim shows Terminating, with the kubernetes.io/pvc-protection finalizer, until no pod uses it.
Static and dynamic provisioning
A PV is provisioned in one of two ways. Statically, a cluster administrator creates PVs ahead of time, each one pointing at real storage. Dynamically, when no static PV matches a claim, the cluster can create one for it from the claim’s StorageClass.
A claim that names no class gets the cluster’s default StorageClass: the one annotated storageclass.kubernetes.io/is-default-class: "true". A claim with storageClassName: "" binds only to PVs without a class, and dynamic provisioning is off for it.
On AKS, the default class is named default, and it’s the same as managed-csi, one of the built-in AKS storage classes. It creates a Standard SSD managed disk. From Kubernetes 1.29, on clusters deployed across multiple availability zones, that disk is zone-redundant (ZRS) instead of locally redundant (LRS).
On EKS, the Amazon EBS CSI driver, ebs.csi.aws.com, creates EBS volumes for persistent volumes. EKS Auto Mode needs no EBS CSI controller installed. Its storage classes must name its own provisioner, ebs.csi.eks.amazonaws.com.
A class’s volumeBindingMode sets when it makes the volume. Immediate, the default, binds and provisions it as soon as the claim is created, without knowing where its pod will run. For storage that some nodes can’t reach, such as a disk in one zone, that can leave the pod unschedulable.
WaitForFirstConsumer waits for a pod that uses the claim. The volume is then placed to suit the pod’s scheduling constraints, such as the zone it can run in.
Access modes
A claim asks for one or more access modes, and Kubernetes matches it to a PV that offers them:
ReadWriteOnce(RWO): read-write by a single node. Several pods on that node can still use it.ReadOnlyMany(ROX): read-only by many nodes.ReadWriteMany(RWX): read-write by many nodes.ReadWriteOncePod(RWOP): read-write by a single pod in the whole cluster. It works only with CSI volumes, and it’s stable since Kubernetes 1.29.
An Azure disk is mounted as ReadWriteOnce, so only one node can use it. For pods on several nodes at once, Microsoft points to Azure Files. A volume is mounted with only one access mode at a time, even if it supports several.
Reclaim policies
A PV’s reclaim policy decides what happens to it after its claim is deleted:
Retain: the PV stays, Released, with the old data on it. You delete the PV, then clean up or delete the cloud disk yourself.Delete: removes both the PV and the storage behind it, such as the Azure disk or EBS volume.Recycle: deprecated. The docs recommend dynamic provisioning instead.
A dynamically provisioned PV inherits its class’s reclaim policy, and a class that sets none defaults to Delete. AKS’s built-in disk classes delete the Azure disk when its persistent volume is deleted.
A Kubernetes persistent volume example
The claim below asks for 10 GiB, read-write on one node, from AKS’s managed-csi class. On EKS, name a StorageClass that uses the EBS CSI driver instead. The pod after it mounts the claim at /data.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: data
spec:
accessModes:
- ReadWriteOnce
storageClassName: managed-csi
resources:
requests:
storage: 10GiapiVersion: v1
kind: Pod
metadata:
name: web
spec:
containers:
- name: web
image: nginx
volumeMounts:
- mountPath: /data
name: data
volumes:
- name: data
persistentVolumeClaim:
claimName: datakubectl describe pvc data shows the claim’s status and, once it’s bound, the PV behind it. On a class with WaitForFirstConsumer, the claim stays unbound until the pod is created.
Delete the pod and create it again, and the files in /data are still there. The claim and its PV outlive the pod.
A StatefulSet needs no hand-written claim. Each entry in its volumeClaimTemplates gives every pod its own claim, and with it stable storage.
Kubernetes persistent storage on AKS and EKS: what you pay for
EBS charges for the GB you provision each month, until you release the storage. Azure prices a managed disk at the closest size tier that fits it, and charges the same however much of it is used.
So a claim is charged by its size, not by its data. A 128 GiB claim holding 20 GiB is charged for all 128 GiB.
You can resize a PVC to a larger size when its class sets allowVolumeExpansion: true. It can’t shrink, so space you size for later is charged now.
Deleting or scaling down a StatefulSet keeps its claims and their disks by default. Its persistentVolumeClaimRetentionPolicy, stable since Kubernetes 1.32, can delete the claims instead.
Sources: Kubernetes, “Persistent Volumes” (opens in a new tab); Kubernetes, “Storage Classes” (opens in a new tab); Kubernetes, “Volumes” (opens in a new tab); Kubernetes, “StatefulSets” (opens in a new tab); Microsoft Learn, “Concepts - Storage in Azure Kubernetes Service (AKS)” (opens in a new tab); AWS, “Use Kubernetes volume storage with Amazon EBS” (opens in a new tab); AWS, “Amazon EBS pricing” (opens in a new tab); Microsoft Azure, “Managed Disks pricing” (opens in a new tab).