Namespace-scoped resource that defines the desired charactersistics of the storage
Size
Access modes
ReadWriteOnce (RWO): one node mounted read/write.
ReadOnlyMany (ROX): multiple nodes, read-only.
ReadWriteMany (RWX)L multiple nodes, read/write.
Storage Class (optional)
Kubernetes attempts to bind a PVC to an available PV that satisfies its requirements.
Workflow
Administartors provisions PVs or defines Storage Classes
Users/applications create PVC
Kubernetes binds PVC to PV
Pods mounts PVC as per manifest.
Reclaim Policies
Retain
PV is not deleted; data remains intact.
Storage asset is orphaned until an admin manually reclaims it (by wiping or reassigning).
Best for sensitive data (databases, regulated workloads).
Example Use Case: Production database volumes (Postgres, MySQL, MongoDB) where accidental data loss must be avoided.
Delete
Both the PV object and the underlying storage asset (e.g., AWS EBS volume, GCP PD, Ceph RBD) are deleted.
Fully automated cleanup.
Data is lost once PVC is deleted.
Example Use Case: Scratch workloads, CI/CD environments, development namespaces, or any scenario where ephemeral but persistent-like storage is needed.admin manually reclaims.
Diagram
flowchart TD
subgraph NodeLocal["Node-local Storage"]
A["emptyDir (ephemeral)"]
B["hostPath (node filesystem)"]
end
subgraph ClusterStorage["Cluster / External Storage"]
C["Physical backend (NFS, EBS, Ceph, Longhorn, etc.)"]
D["PersistentVolume (PV)"]
end
E["PersistentVolumeClaim (PVC)"]
F["Pod"]
%% relationships
A --> F
B --> F
C --> D
D --> E
E --> F
Key Point
Volumes are not tied to containers, but to pods
Data is preserved across container restarts but not across pod rescheduling, unless backed by PV/PVC.
PV on multi-node cluster
Details
A Persistent Volume (PV) is a cluster-wide resource.
However, the actual storage backend dictates whether a pod scheduled on another node can still access that PV.
hostPath-backed PV
hostPath ties the PV to a directory on a specific node.
If the pod is scheduled elsewhere, the mount fails.
The pod may go ContainerCreating with volume mount errors.
hostPath is not recommended for production or multi-node clusters.
Local Path provisioner (per-node local disks)
Same limitation: bound to the node where it was created.
The provisioner usually pins the pod to the node with the volume (via node affinity).
Good for dev/test clusters, but limited for failover.
Needed for shared workloads (like WordPress + PHP pods writing to the same files).
ReadOnlyMany (ROX): multiple pods/nodes can read concurrently, but no writes.
Scheduling awareness
When a pod requests a PVC
Kubernetes binds PVC to PV.
If the PV backend is node-local, the scheduler will add node affinity so the pod only runs on that node.
If the PV backend is networked, the pod can run on any node and the volume follows.
Diagram
flowchart TD
subgraph Cluster["Kubernetes Cluster"]
N1["Node 1"]
N2["Node 2"]
N3["Node 3"]
N4["Node 4"]
end
subgraph Storage["Storage Backend"]
H["hostPath (Node-local)"]
E["EBS / NFS / Ceph / Longhorn (Networked)"]
end
PV1["PV (hostPath)"] --> H
PV2["PV (Networked)"] --> E
N1 -. can use .-> PV1
N2 -. cannot use .-> PV1
N3 -. cannot use .-> PV1
N4 -. cannot use .-> PV1
N1 -- can mount --> PV2
N2 -- can mount --> PV2
N3 -- can mount --> PV2
N4 -- can mount --> PV2