Skip to content

Persistent Volume vs Persistent Volume Claim

Mental model

PV = a disk on the shelf. PVC = a requisition form for a disk.

What it looks like

Two objects for one piece of storage seems redundant.

What it really is

PV (PersistentVolume): a piece of storage provisioned by an admin or dynamically by a StorageClass. Represents the actual storage resource (NFS share, EBS volume, local disk, etc.).

PVC (PersistentVolumeClaim): a request for storage by a user or pod. Specifies size and access mode. Kubernetes binds it to a matching PV automatically.

Why it seems confusing

Two objects for one disk. But the split separates concerns: admins provision and manage storage (PVs), users request it (PVCs) without knowing the underlying implementation.

What actually matters

  • Pod references the PVC, not the PV directly.
  • StorageClass enables dynamic provisioning: creating a PVC triggers automatic PV creation. No admin intervention.
  • Access modes: ReadWriteOnce (single node), ReadOnlyMany (many nodes read), ReadWriteMany (many nodes read/write).
  • Reclaim policies: Retain (keep data after PVC deleted), Delete (destroy storage with PVC).
  • Binding is 1:1. One PVC binds to exactly one PV.

Common mistakes

  • Requesting ReadWriteMany on storage that only supports ReadWriteOnce (e.g., most cloud block storage).
  • Forgetting reclaim policy. Delete is the default for dynamic provisioning — data is gone when PVC is deleted.
  • Creating PVs manually when a StorageClass would handle it automatically.

Small examples

# Static PV
apiVersion: v1
kind: PersistentVolume
metadata:
  name: data-pv
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: /mnt/data

# PVC that binds to it
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: data-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi

# Pod referencing the PVC
apiVersion: v1
kind: Pod
metadata:
  name: app
spec:
  containers:
    - name: app
      image: myapp:1.0
      volumeMounts:
        - mountPath: /data
          name: storage
  volumes:
    - name: storage
      persistentVolumeClaim:
        claimName: data-pvc

Dynamic provisioning with StorageClass skips the manual PV step entirely. The PVC triggers PV creation on demand.

One-line summary

A PV is provisioned storage; a PVC is a request that binds to a PV, separating storage management from consumption.