Why Kubernetes Introduced Volumes, PVs, and StorageClasses: A Deep Dive
This article explains the origins and purposes of Kubernetes Volume, PersistentVolume (PV), PersistentVolumeClaim (PVC), and StorageClass, compares them with Docker volumes, details static and dynamic provisioning, and walks through configuration examples, illustrating the storage architecture and workflow within a Kubernetes cluster.
Origin of Volume, PV, PVC, and StorageClass
Why does Kubernetes introduce the concept of a Volume? To achieve data persistence that outlives the container lifecycle.
The answer is simple: data must survive container termination.
Before Kubernetes Volume, Docker provides two common volume types: volumes (managed under /var/lib/docker/volumes) and bind mounts (mount host directories into containers).
Although Docker has volumes, Kubernetes defines its own Volume not because it is fundamentally different, but because its lifecycle aligns with a Pod rather than a container. When a pod is deleted, the associated volume is cleaned up, unless the volume type (e.g., emptyDir) dictates otherwise. Kubernetes supports about 20 volume types.
In a pod’s YAML you can declare a volume, for example an NFS volume:
....
volumes:
- name: static-nfs
nfs:
server: 12.18.17.240
path: /nfs/data/staticIf you use Ceph as the storage plugin, the YAML looks like:
volumes:
- name: ceph-vol
cephfs:
monitors:
- 12.18.17.241:6789
- 12.18.17.242:6789
user: admin
secretRef:
name: ceph-secret
readOnly: trueAfter defining a volume, the next step is to understand PersistentVolume (PV) and PersistentVolumeClaim (PVC).
A PV describes a persistent storage resource.
A PV is usually pre‑created by an administrator:
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfs
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteMany
nfs:
server: 10.244.1.4
path: "/nfs"A PVC describes the desired size, access mode, etc.
Developers create a PVC:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nfs
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 10GiThe PVC must bind to a matching PV; the PV’s spec must satisfy the PVC’s requirements. Once bound, the pod can reference the PVC in its YAML.
apiVersion: v1
kind: Pod
metadata:
labels:
role: web
spec:
containers:
- name: web
image: nginx
ports:
- name: web
containerPort: 80
volumeMounts:
- name: nfs
mountPath: "/usr/share/nginx/html"
volumes:
- name: nfs
persistentVolumeClaim:
claimName: nfsStatic provisioning requires administrators to pre‑allocate PVs, which can be inefficient. Dynamic provisioning automates PV creation based on a StorageClass template.
Static provisioning flow: administrators pre‑create PVs, users submit PVCs, the controller binds them, and pods use the storage.
Dynamic provisioning flow: users only create a PVC; the controller reads the StorageClass and creates a PV on‑the‑fly.
# Install NFS
yum -y install nfs-utils rpcbind
systemctl enable rpcbind nfs-server
echo "/nfs/data *(rw,no_root_squash,sync)" > /etc/exportsDeploy the NFS provisioner:
apiVersion: v1
kind: ServiceAccount
metadata:
name: nfs-provisioner
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: nfs-provisioner-runner
rules:
- apiGroups: [""]
resources: ["persistentvolumes"]
verbs: ["get","list","watch","create","delete"]
- apiGroups: [""]
resources: ["persistentvolumeclaims"]
verbs: ["get","list","watch","update"]
- apiGroups: ["storage.k8s.io"]
resources: ["storageclasses"]
verbs: ["get","list","watch"]
- apiGroups: [""]
resources: ["events"]
verbs: ["watch","create","update","patch"]
- apiGroups: [""]
resources: ["services","endpoints"]
verbs: ["get","create","list","watch","update"]
- apiGroups: ["extensions"]
resources: ["podsecuritypolicies"]
resourceNames: ["nfs-provisioner"]
verbs: ["use"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: run-nfs-provisioner
subjects:
- kind: ServiceAccount
name: nfs-provisioner
namespace: logging
roleRef:
kind: ClusterRole
name: nfs-provisioner-runner
apiGroup: rbac.authorization.k8s.io
---
kind: Deployment
apiVersion: apps/v1
metadata:
name: nfs-client-provisioner
spec:
selector:
matchLabels:
app: nfs-client-provisioner
replicas: 1
strategy:
type: Recreate
template:
metadata:
labels:
app: nfs-client-provisioner
spec:
serviceAccount: nfs-provisioner
containers:
- name: nfs-client-provisioner
image: quay.io/external_storage/nfs-client-provisioner:latest
imagePullPolicy: IfNotPresent
volumeMounts:
- name: nfs-client
mountPath: /persistentvolumes
env:
- name: PROVISIONER_NAME
value: fuseim.pri/ifs
- name: NFS_SERVER
value: 12.18.7.20
- name: NFS_PATH
value: /nfs/data
volumes:
- name: nfs-client
nfs:
server: 12.18.7.20
path: /nfs/dataCreate a StorageClass for NFS:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: nfs-storage
provisioner: fuseim.pri/ifs
reclaimPolicy: RetainWhen a pod defines a PVC that references this StorageClass, Kubernetes automatically creates the PV and binds it.
Key PV attributes:
Capacity : size of the storage.
AccessModes : ReadWriteOnce, ReadOnlyMany, or ReadWriteMany.
StorageClassName : the class used for dynamic provisioning.
Kubernetes Storage Architecture
PV Controller: manages PV‑PVC binding and lifecycle. AD Controller: handles attach/detach of storage devices. Volume Manager: mounts/unmounts volumes and formats devices. Volume Plugins: implement the actual mount logic; can be In‑Tree (built‑in) or Out‑of‑Tree (CSI). Scheduler: schedules pods considering storage requirements.
Dynamic PV Interaction Flow
User creates a pod with a PVC. PV Controller watches the API server, creates a matching PV, and binds it to the PVC.
The Provision step creates the actual storage volume. Scheduler places the pod on a suitable node. AD Controller attaches the volume to the node. Volume Manager mounts the volume into the pod’s filesystem.
Container starts and uses the mounted volume.
Conclusion
The article covered the origins of Kubernetes Volume, PV, PVC, and StorageClass, compared them with Docker volumes, explained static and dynamic provisioning, and outlined the storage architecture and interaction workflow within a Kubernetes cluster.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Open Source Linux
Focused on sharing Linux/Unix content, covering fundamentals, system development, network programming, automation/operations, cloud computing, and related professional knowledge.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
