DevOps Peach

Docker & Kubernetes · Kubernetes Storage and Configuration – Volumes, PV/PVC, ConfigMaps, Secrets · Lesson 2 of 4

PersistentVolumes and PersistentVolumeClaims

A PV is cluster storage, a PVC is an app's request for storage; pods use PVCs, never PVs directly.

Practice interactively →

flowchart LR
  P["Pod"] -- "claimName: data" --> C["PVC data<br/>(namespace dev, 3Gi RWO)"]
  C -- "bound" --> V["PV pv-0042<br/>(cluster-scoped)"]
  V --> B[("EBS / NFS / CSI")]
apiVersion: v1
kind: PersistentVolumeClaim
metadata: { name: data, namespace: dev }
spec:
  accessModes: [ReadWriteOnce]
  resources: { requests: { storage: 3Gi } }
---
# in the Pod
volumes:
- name: data
  persistentVolumeClaim: { claimName: data }

Access modes

Mode Meaning
ReadWriteOnce (RWO) Read-write by one node (several pods on that node can still use it)
ReadOnlyMany (ROX) Read-only by many nodes
ReadWriteMany (RWX) Read-write by many nodes (NFS, EFS, Azure Files…)
ReadWriteOncePod (RWOP) Read-write by exactly one pod (CSI only)

volumeMode: Filesystem (default) or Block (a raw block device).

A PVC stays Pending when no PV matches its size/access mode/selector and no StorageClass can provision one. EBS only supports RWO and must be in the same AZ as the node.

Command Meaning
kubectl get pv,pvc -n dev STATUS Bound means matched
kubectl describe pvc data -n dev Events while a PVC is Pending

PV lifecycle

PV phase Meaning
Available Free, not bound to a claim
Bound Bound to exactly one PVC
Released Its PVC was deleted; data still there, not reusable automatically
Failed Automatic reclamation failed

Binding is one-to-one: a 3Gi request may bind to a 10Gi PV if that is the closest match, and the rest is unused. A Released PV with policy Retain keeps the data until an admin cleans it up or rebinds it by removing the old claimRef.

A static PV

apiVersion: v1
kind: PersistentVolume
metadata: { name: pv-nfs-01 }
spec:
  capacity: { storage: 10Gi }
  accessModes: [ReadWriteMany]
  persistentVolumeReclaimPolicy: Retain
  nfs: { server: 192.0.2.30, path: /exports/data }

Static PVs suit existing storage you want to expose, such as an NFS share. A PVC can target it with storageClassName: "" and a label selector.

Growing a volume

If the StorageClass has allowVolumeExpansion: true, edit the PVC's resources.requests.storage to a larger value and the CSI driver resizes the disk, often while the pod is running. Volumes can grow but never shrink.

Protection and debugging

Kubernetes adds a kubernetes.io/pvc-protection finalizer: a PVC in use by a pod stays Terminating until the pod is gone, so data is not ripped away from a running app. When a pod waits on storage, kubectl describe pod shows events such as FailedAttachVolume (the disk is still attached to another node or is in another zone) or FailedMount.

Choosing access modes

Most databases need ReadWriteOnce block storage. Shared uploads or content used by several replicas need ReadWriteMany file storage such as NFS, Amazon EFS, or Azure Files. Using RWO for a Deployment with several replicas across nodes makes extra pods hang in ContainerCreating.

Practice interactively →