Think of the relationship between a PersistentVolume (PV) and a PersistentVolumeClaim (PVC) like a Job Posting and a Resume. One is the resource available, and the other is the request for that resource.
In Kubernetes, this system allows developers to request storage without needing to know the messy details of the underlying infrastructure (like AWS EBS IDs or NFS IP addresses).
The Breakdown
1. PersistentVolume (PV)
A PV is a piece of storage in the cluster that has been provisioned by an administrator or dynamically provisioned using Storage Classes. It is a cluster-level resource, meaning it exists independently of any individual Pod.
- Analogy: A physical hard drive sitting on a shelf.
- Scope: Cluster-wide (not tied to a namespace).
- Details: Defines the capacity, access modes (ReadWriteOnce, ReadOnlyMany), and the actual storage backend (NFS, Cloud Disk, local path).
2. PersistentVolumeClaim (PVC)
A PVC is a request for storage by a user. It’s the “ticket” a developer uses to get a slice of storage for their application.
- Analogy: A requisition form saying, “I need 5GB of space with fast read/write access.”
- Scope: Namespace-specific (tied to where your Pod lives).
- Details: Defines how much storage is needed and the required access mode.
How They Work Together
The interaction follows a specific lifecycle:
| Phase | Description |
| Provisioning | Storage is created. Static: Admin creates PVs manually. Dynamic: A StorageClass creates a PV automatically when a PVC is made. |
| Binding | The control plane looks for a PV that matches the PVC’s requirements. Once found, they are “bound” together in a 1-to-1 mapping. |
| Using | The Pod uses the PVC as a volume. The cluster looks up the bound PV and mounts it into the container. |
| Reclaiming | When a user is done, the Reclaim Policy (Retain, Recycle, or Delete) determines what happens to the data on the PV. |
Key Differences at a Glance
| Feature | PersistentVolume (PV) | PersistentVolumeClaim (PVC) |
| Role | The actual storage “provider.” | The storage “consumer.” |
| Responsibility | Usually managed by Cluster Admins. | Usually created by Developers. |
| Lifecycle | Exists until manually deleted. | Exists until the application is deleted. |
| Level | Cluster-scoped. | Namespace-scoped. |
The YAML Link
In your Pod definition, you don’t point to the PV. You point to the PVC.
YAML
volumes: - name: my-data persistentVolumeClaim: claimName: my-pvc-request # The Pod asks for the claim, not the disk!
Pro Tip: If you delete a PVC, the fate of the PV depends on the
reclaimPolicy. If it’s set toRetain, the PV stays around but is marked “Released,” meaning no other PVC can use it until an admin manually scrubs it.
# Please edit the object below. Lines beginning with a ‘#’ will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: v1
kind: PersistentVolume
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{“apiVersion”:”v1″,”kind”:”PersistentVolume”,”metadata”:{“annotations”:{},”labels”:{“com.rbccm.appcode”:”ovi”},”name”:”ovi-dev2-phoenix”,”namespace”:””},”spec”:{“accessModes”:[“ReadWriteMany”],”capacity”:{“storage”:”50Gi”},”mountOptions”:[“nfsvers=3″],”nfs”:{“path”:”/ovi/kube/dev2″,”server”:”nfs.server.com”},”persistentVolumeReclaimPolicy”:”Retain”,”storageClassName”:”ovi”}}
pv.kubernetes.io/bound-by-controller: “yes”
creationTimestamp: 2019-05-02T21:34:10Z
finalizers:
– kubernetes.io/pv-protection
labels:
com.ovi.appcode: ovi
name: ovi-dev2-phoenix
resourceVersion: “203315676”
selfLink: /api/v1/persistentvolumes/ovi-dev2-phoenix
uid: 05de00f4-6d22-11e9-a8b7-0242ac11yyy
spec:
accessModes:
– ReadWriteMany
capacity:
storage: 50Gi
claimRef: ———– >>>> if PVC is deleted —remove this part in spec ( PV is in released Status )
apiVersion: v1
kind: PersistentVolumeClaim
name: ovi-dev2-phoenix
namespace: te20-dev2
resourceVersion: “203305105”
uid: 7a0cbf09-fa8b-11e9-a244-0242ac11yyy
mountOptions:
– nfsvers=3
nfs:
path: /ovi/kube/dev2
server: nfs.server.com
persistentVolumeReclaimPolicy: Retain
storageClassName: ovi
status:
phase: Bound
in GCP
Static provisioning
gcloud beta compute disks create –size \
–size 1GB
–region us-east1
ovi-disk