Skip to main content
RunBook Academy

KubernetesXLIX · VolumesVolumes

Persistent volumes introduction — PVs, PVCs, and the binding contract

Advanced⏱ ~16 minkubectl

What you'll learn

  • Describe what a PersistentVolume is and what it represents
  • Describe what a PersistentVolumeClaim is and how it differs from a PV
  • Trace the binding contract between PV and PVC
  • Identify the lifecycle states of a PV

Prerequisites

Verified against Kubernetes 1.34.x · kubeadm 1.34.x · kubectl 1.34.x · etcd 3.6.x · CoreDNS 1.11.x · containerd 1.7.x / 2.x · 2026-08-16

Not yet marked complete on this device.

The PersistentVolume (PV) and PersistentVolumeClaim (PVC) are the two halves of Kubernetes’ persistent storage contract. The PV is the actual storage; the PVC is the request; the binding controller matches them. This lesson walks the contract and the lifecycle.

The PV-PVC contract

flowchart LR
    A[User: PVC manifest] --> B[API server: PVC persisted]
    B --> C[Binding controller]
    D[StorageClass provisioner] --> E[PV created]
    E --> C
    F[Existing PV] --> C
    C --> G[PV bound to PVC]
    G --> H[Pod mounts PVC]

The contract:

  • PVC: a request for storage. The user specifies the size, the access mode, and (optionally) the StorageClass.
  • PV: the actual storage. The PV has a capacity, an access mode, a reclaim policy, and a reference to the StorageClass.
  • Binding: the binding controller matches a PVC to a PV. The match is by capacity (PV >= PVC), access mode (PV must support at least one of PVC’s modes), and StorageClass (must match).
  • Mount: the Pod’s volumes reference the PVC by name; the kubelet mounts the bound PV into the Pod.

What a PersistentVolume is

A PersistentVolume is a cluster-scoped object that represents a piece of storage:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-001
spec:
  capacity:
    storage: 100Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: ssd
  hostPath:
    path: /data/pv-001

The PV’s spec describes:

  • capacity: the size of the volume.
  • accessModes: the mount modes the volume supports.
  • persistentVolumeReclaimPolicy: what happens to the PV when the PVC is deleted.
  • storageClassName: the StorageClass the PV belongs to.
  • volume source: the actual storage (hostPath, NFS, CSI, etc.).

A PV is cluster-scoped, not namespace-scoped. It is a piece of storage that exists independently of any PVC.

What a PersistentVolumeClaim is

A PersistentVolumeClaim is a namespace-scoped object that represents a request for storage:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: data
  namespace: production
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 100Gi
  storageClassName: ssd

The PVC’s spec describes:

  • accessModes: the mount modes the request needs.
  • resources.requests.storage: the minimum capacity.
  • storageClassName: the StorageClass to provision from (or to match against existing PVs).
  • selector: optional label selector for matching existing PVs.
  • volumeName: optional explicit PV to bind to.

A PVC is namespace-scoped. It is a request that lives until it is bound and the bound PV is released.

Lifecycle states

A PV has lifecycle states:

StateMeaning
AvailableThe PV is not yet bound to a PVC; it is available for binding.
BoundThe PV is bound to a PVC; the PVC references it.
ReleasedThe PVC was deleted; the PV is awaiting reclamation.
FailedThe PV failed to be reclaimed (e.g., the provisioner could not delete the underlying storage).
stateDiagram-v2
    [*] --> Available: PV created
    Available --> Bound: PVC binds
    Bound --> Released: PVC deleted
    Released --> Available: reclaim succeeds (Retain: manual)
    Released --> [*]: reclaim succeeds (Delete)
    Released --> Failed: reclaim fails
    Failed --> [*]: manual intervention

The transition depends on the reclaim policy:

  • Retain: Released -> manual cleanup -> Available.
  • Delete: Released -> automatic cleanup -> (PV deleted).

Dynamic provisioning

Most production clusters use dynamic provisioning: the PVC’s StorageClass triggers the provisioner to create a PV when the PVC is submitted:

sequenceDiagram
    participant U as User
    participant API as API server
    participant SC as StorageClass
    participant CSI as CSI provisioner
    participant N as Storage backend
    U->>API: create PVC
    API->>SC: look up provisioner
    SC->>CSI: provision volume
    CSI->>N: create backend storage
    N->>CSI: volumeHandle
    CSI->>API: create PV
    API->>U: PVC bound to PV

The user sees only the PVC; the PV is created automatically by the provisioner. The provisioner is the CSI driver.

Static provisioning

For pre-existing volumes (e.g., a manually-created NFS export), the cluster operator creates the PV manually:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs-pv-001
spec:
  capacity:
    storage: 1Ti
  accessModes:
    - ReadWriteMany
  storageClassName: nfs
  nfs:
    server: nfs.prod.example.com
    path: /exports/data

The PVC is submitted with storageClassName: nfs; the binding controller matches the PVC to the manually-created PV.

Quiz

Knowledge check · 4 questions

  1. Q1. A PV is in the `Released` state. What does this mean?

  2. Q2. A PersistentVolume is namespace-scoped.

  3. Q3. Your team submits a PVC with 100 GB request and StorageClass `ssd`. The provisioner creates a PV with 100 GB capacity. Walk through the binding and lifecycle.

    Cluster uses dynamic provisioning. PVC submitted with storageClassName: ssd, 100 GB, ReadWriteOnce. The StorageClass's provisioner is ebs.csi.aws.com.

  4. Q4. Explain the difference between dynamic and static provisioning, and when each is appropriate.

Passing score: 75%. Answers are checked in this browser.

Production discipline

  • PVC is the user’s request; PV is the implementation. The user writes a PVC; the system provides a PV.
  • Dynamic provisioning is the default. The provisioner is the CSI driver.
  • Static provisioning is for pre-existing volumes. The operator creates the PV manually.
  • PV lifecycle states are diagnostic. Available, Bound, Released, Failed — each tells a story.
  • Released PVs are a smell. Audit regularly; remediate based on the reclaim policy.