What's the difference between a PersistentVolume and a PersistentVolumeClaim?

7 minintermediatepersistentvolumepersistentvolumeclaimstorage

Quick Answer

A PersistentVolume (PV) represents an actual piece of storage in the cluster, like a cloud disk or an NFS share, provisioned either manually by an administrator or dynamically via a StorageClass. A PersistentVolumeClaim (PVC) is a request for storage made by a Pod's owner/developer, specifying how much space and what access mode is needed, without needing to know or care about the underlying storage implementation. Kubernetes binds a PVC to a matching PV, and the Pod simply references the PVC. This separation lets application developers request storage abstractly, while cluster operators, or dynamic provisioning, handle the actual storage infrastructure.

Detailed Answer

The separation of concerns: PV (supply) vs. PVC (demand)

# PersistentVolume: an actual piece of storage, typically created by an admin
# or dynamically by a StorageClass provisioner -- represents SUPPLY
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-database-1
spec:
  capacity:
    storage: 20Gi
  accessModes:
    - ReadWriteOnce
  awsElasticBlockStore:
    volumeID: vol-0abc123
# PersistentVolumeClaim: a request for storage, created by an application
# developer -- represents DEMAND, with no knowledge of the underlying implementation
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: database-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 20Gi
# The Pod only references the PVC by name -- never the PV directly
spec:
  containers:
    - name: db
      volumeMounts:
        - name: data
          mountPath: /var/lib/data
  volumes:
    - name: data
      persistentVolumeClaim:
        claimName: database-pvc

Kubernetes's PV controller binds the PVC to a PV that satisfies its requested size and access mode — in this example, pv-database-1 matches database-pvc's request exactly. Once bound, that specific PV is reserved exclusively for that PVC and can't be claimed by any other PVC.

Why this indirection is genuinely useful

An application developer writing a Deployment or StatefulSet manifest shouldn't need to know, or care, whether the underlying storage is an AWS EBS volume, a GCP persistent disk, or an on-prem NFS share. They just declare "I need 20Gi, ReadWriteOnce" via a PVC, and the actual storage implementation is handled entirely by whoever manages PVs — or, far more commonly today, by dynamic provisioning via a StorageClass (see that question). This mirrors the same "declare what you want, let something else figure out how" philosophy that runs through Kubernetes generally (see the reconciliation-loop question).

Static vs. dynamic provisioning

  • Static provisioning: a cluster administrator manually creates PV objects ahead of time, representing real storage they've already set up, and PVCs bind to whichever pre-existing PV matches.
  • Dynamic provisioning (the overwhelmingly more common approach today): a PVC references a StorageClass, and if no existing PV matches, the StorageClass's provisioner automatically creates a brand-new PV — and the underlying real storage, actually calling the cloud API to create an EBS volume — on demand, with no administrator needing to pre-provision anything.

The lifecycle and reclaim policy

When a PVC is deleted, what happens to its bound PV, and the real underlying storage, depends on the PV's reclaim policy: Delete (the PV and underlying storage are deleted too — common for dynamically-provisioned PVs) or Retain (the PV and its data survive, but move to a "released" state, no longer available to be bound automatically, requiring manual admin action to reuse or clean it up). Check this deliberately for any PV holding genuinely important data, since the default behavior for dynamically-provisioned volumes is frequently Delete — a nasty surprise if a PVC is deleted accidentally.

A strong answer emphasizes the separation of concerns this design achieves: developers declare storage needs abstractly via PVCs, while the actual storage implementation — PVs, and typically dynamic provisioning via StorageClasses — is a cluster/infrastructure-level concern. That's more useful than just describing PV and PVC as two similarly-named objects without explaining why the split exists.