Storage
Manage persistent data in Kubernetes — PersistentVolumes, PersistentVolumeClaims, StorageClasses, and StatefulSets for stateful applications.
PersistentVolumes and Claims
PersistentVolume (PV) is cluster storage provisioned by an admin or dynamically via StorageClass. PersistentVolumeClaim (PVC) is a user request for storage. Kubernetes binds PVCs to matching PVs.
Pods use PVCs as volumes — storage persists beyond pod lifecycle. When a pod is deleted and recreated, it reattaches the same PVC.
- ReadWriteOnce: one node read-write (most common)
- ReadWriteMany: multiple nodes read-write (NFS, EFS)
- ReadOnlyMany: multiple nodes read-only
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: db-storage
spec:
accessModes: [ReadWriteOnce]
storageClassName: gp3
resources:
requests:
storage: 20Gi
# Reference in pod spec
volumes:
- name: data
persistentVolumeClaim:
claimName: db-storageStorageClasses
StorageClass enables dynamic provisioning — creating PVs automatically when PVCs are created. Cloud providers offer classes mapped to their storage products: gp3 (AWS EBS), pd-ssd (GCE), managed-premium (Azure).
Set a default StorageClass so PVCs without storageClassName get provisioned automatically.
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: gp3
annotations:
storageclass.kubernetes.io/is-default-class: "true"
provisioner: ebs.csi.aws.com
parameters:
type: gp3
iops: "3000"
volumeBindingMode: WaitForFirstConsumerStatefulSets
StatefulSets manage stateful applications with stable network identities and persistent storage. Each pod gets a predictable name (web-0, web-1) and its own PVC that persists across restarts.
Use StatefulSets for databases, message queues, and any application requiring stable storage and network identity. Deploy in order (0, 1, 2) and scale down in reverse.
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: postgres
spec:
serviceName: postgres
replicas: 3
selector:
matchLabels:
app: postgres
template:
spec:
containers:
- name: postgres
image: postgres:16
volumeMounts:
- name: data
mountPath: /var/lib/postgresql/data
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: [ReadWriteOnce]
resources:
requests:
storage: 50GiVolume Types
Beyond PVCs, pods support emptyDir (temporary, dies with pod), configMap and secret volumes (configuration injection), and projected volumes (combining multiple sources).
emptyDir is useful for scratch space and inter-container sharing within a pod. configMap volumes mount configuration files that update when the ConfigMap changes.
volumes:
- name: cache
emptyDir:
sizeLimit: 1Gi
- name: config
configMap:
name: app-config
- name: secrets
secret:
secretName: db-credentialsBackup and Recovery
Back up PVC data with volume snapshots (StorageClass must support it) or by mounting the volume in a backup pod. Cloud providers offer automated snapshot schedules.
Test recovery regularly — a backup you cannot restore is worthless. Document RPO (Recovery Point Objective) and RTO (Recovery Time Objective) for each stateful service.
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
name: db-backup-20240115
spec:
volumeSnapshotClassName: csi-aws-vsc
source:
persistentVolumeClaimName: db-storage