Articles

Kubernetes PV vs PVC: Persistent Storage Explained

A Kubernetes PersistentVolume is real storage; a PersistentVolumeClaim is a pod's request for it. How the two connect and why they're separate.

Chisato Chisato · · 5 min read
Abstract illustration representing Kubernetes

A Kubernetes PersistentVolume (PV) is a piece of actual storage provisioned in the cluster — a disk, an NFS share, a cloud block volume — while a PersistentVolumeClaim (PVC) is a request from a pod for storage matching certain criteria, such as size and access mode. The split exists so that pods never have to know the details of the underlying storage system; they ask for “10Gi, read-write by one node” and Kubernetes matches that request to a suitable volume.

Why storage needed its own abstraction

By default, anything a container writes to its own filesystem disappears the moment the container is replaced — a crash, a redeploy, or a routine rescheduling to a different node all wipe the container’s writable layer. That’s fine for stateless workloads, but a database, a message queue, or any service with data to keep needs storage that survives pod restarts and can potentially move with the pod between nodes.

Kubernetes could have made pods reference specific disks directly, but that would tightly couple application manifests to whatever storage infrastructure happened to back a particular cluster — an EBS volume ID here, an NFS server address there. The PV/PVC split decouples the two: application authors write PVCs describing what they need in abstract terms, and cluster operators (or a storage driver) worry about what PVs actually satisfy those requests.

PersistentVolume: the supply side

A PV is a cluster-scoped resource representing a concrete unit of storage, along with its capacity, access modes, and the underlying storage system it maps to:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-data-01
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  csi:
    driver: ebs.csi.aws.com
    volumeHandle: vol-0123456789abcdef0

PVs can be created manually by a cluster operator (static provisioning) or, far more commonly in practice, created automatically on demand by a StorageClass when a PVC requests storage that doesn’t yet exist (dynamic provisioning). Dynamic provisioning is the default in most managed Kubernetes offerings — the underlying cloud provider’s CSI (Container Storage Interface) driver creates a real disk behind the scenes the moment a matching PVC shows up.

PersistentVolumeClaim: the demand side

A PVC is a namespaced resource — living inside an application’s namespace, unlike the cluster-scoped PV — that describes what a pod needs from storage:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: data-claim
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  storageClassName: fast-ssd

A pod references the PVC by name in its volume list, not the PV directly:

spec:
  containers:
    - name: app
      volumeMounts:
        - mountPath: /data
          name: storage
  volumes:
    - name: storage
      persistentVolumeClaim:
        claimName: data-claim

Kubernetes binds this PVC to a PV that satisfies its capacity and access mode requirements — either an existing PV waiting to be claimed, or a newly provisioned one if a StorageClass is set. Once bound, that PV/PVC pair is exclusive: no other PVC can bind to the same PV while the binding exists.

Access modes

Access modes describe how many nodes can mount the volume simultaneously, and how:

  • ReadWriteOnce (RWO) — mountable read-write by a single node at a time. The most common mode, used for most block storage (EBS, most cloud disks).
  • ReadOnlyMany (ROX) — mountable read-only by many nodes simultaneously. Useful for shared reference data.
  • ReadWriteMany (RWX) — mountable read-write by many nodes simultaneously. Requires storage that supports concurrent access, such as NFS or a distributed filesystem — most block storage cannot do this.
  • ReadWriteOncePod (RWOP) — a newer, stricter mode limiting the volume to a single pod (not just a single node), useful for workloads that must never risk two pods writing to the same volume at once.

Choosing the wrong access mode is a common source of confusion: a StatefulSet running multiple replicas with an RWO volume type will fail to schedule additional pods onto other nodes that need write access to the same claim, since RWO only permits one node at a time.

Reclaim policy: what happens when a claim is deleted

When a PVC is deleted, the persistentVolumeReclaimPolicy on its bound PV decides the PV’s fate: Retain keeps the PV and its data around (unbound, requiring manual cleanup or reuse), Delete removes both the PV and the underlying storage entirely, and the now-deprecated Recycle used to wipe and reuse the volume. Dynamically provisioned PVs typically default to Delete, which is convenient but means deleting a PVC by mistake can permanently destroy data — a policy worth explicitly setting to Retain for anything holding data you can’t afford to lose.

PV/PVC vs other Kubernetes storage concepts

PersistentVolumePersistentVolumeClaimemptyDir volume
ScopeCluster-wideNamespacedPod-local
Survives pod deletionYesYes (until the PVC itself is deleted)No
Who creates itOperator or dynamic provisionerApplication authorPod spec, automatically
Typical useBacking real storageRequesting storage in a pod specScratch space, cache

This is distinct from a ConfigMap or Secret, which also mount into a pod as a volume but hold configuration data rather than persistent application state, and it’s a different concern from the namespace a PVC lives in, which scopes visibility rather than storage lifecycle. Statefulness built on PVCs is why StatefulSets exist as a distinct workload type from plain Deployments — a StatefulSet gives each replica its own stable PVC rather than sharing one across pods that come and go. The choice between block storage (what most PVs back) and shared file or object storage is covered in more depth in object storage vs block storage vs file storage, which matters when deciding whether RWX is even an option for a given backend.

The takeaway

A PV is the actual storage; a PVC is a pod’s abstract request for storage matching certain criteria, and Kubernetes handles matching the two together — provisioning a new PV on demand if a StorageClass is configured. Get the access mode right for how many pods need to write concurrently, set the reclaim policy deliberately rather than trusting the default, and remember that deleting a PVC can delete real data depending on that policy.

Chisato Chisato · · 4 min read

Kubernetes Init Containers Explained

Init containers run to completion before a pod's main containers start, making them the standard way to handle setup steps and startup ordering.

#Kubernetes #DevOps #Cloud
Chisato Chisato · · 4 min read

Helm vs Kustomize for Kubernetes Config

Helm templates and packages Kubernetes manifests with a templating language; Kustomize patches plain YAML declaratively, with no templates at all.

#Kubernetes #DevOps #Cloud