Kubernetes Persistent Volumes — Storage Guide
Advertisement
Kubernetes Persistent Volumes — Storage Guide
Persistent storage in Kubernetes enables stateful applications and data durability across pod restarts.
Introduction
Kubernetes Persistent Volumes (PV) and Persistent Volume Claims (PVC) abstract underlying storage infrastructure, enabling applications to request and use storage independently of infrastructure specifics.
- Kubernetes Persistent Volumes — Storage Guide
- Storage Concepts
- PersistentVolume (PV)
- PersistentVolumeClaim (PVC)
- Pod Using PVC
- Storage Classes
- Access Modes
- Reclaim Policies
- Volume Types
- HostPath (Development Only)
- AWS EBS
- NFS
- GCP Persistent Disk
- StatefulSet with Persistent Storage
- Expanding Volumes
- Backup and Recovery
- Snapshot (if supported)
- Manual Backup
- Monitoring Storage
- Best Practices
- FAQ
Storage Concepts
PersistentVolume (PV)
Cluster-level storage resource provisioned by administrator.
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-example
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: standard
hostPath:
path: /data/pv-example
PersistentVolumeClaim (PVC)
Pod requests storage through a claim.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-example
spec:
accessModes:
- ReadWriteOnce
storageClassName: standard
resources:
requests:
storage: 5Gi
Pod Using PVC
apiVersion: v1
kind: Pod
metadata:
name: data-pod
spec:
containers:
- name: app
image: myapp:1.0
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
persistentVolumeClaim:
claimName: pvc-example
Storage Classes
Dynamic provisioning with storage classes:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast-ssd
provisioner: kubernetes.io/aws-ebs
parameters:
type: gp3
iops: "3000"
throughput: "125"
fstype: ext4
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
Use storage class:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: app-storage
spec:
accessModes:
- ReadWriteOnce
storageClassName: fast-ssd
resources:
requests:
storage: 20Gi
Access Modes
- ReadWriteOnce (RWO): Mounted read-write by single node
- ReadOnlyMany (ROX): Mounted read-only by multiple nodes
- ReadWriteMany (RWX): Mounted read-write by multiple nodes
accessModes:
- ReadWriteMany # NFS, EFS, etc
Reclaim Policies
What happens when PVC deleted:
- Retain: Volume retained, manual cleanup required
- Delete: Volume deleted automatically
- Recycle: Volume scrubbed and made available (deprecated)
persistentVolumeReclaimPolicy: Delete
Volume Types
HostPath (Development Only)
apiVersion: v1
kind: PersistentVolume
metadata:
name: hostpath-pv
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
hostPath:
path: /mnt/data
AWS EBS
apiVersion: v1
kind: PersistentVolume
metadata:
name: ebs-pv
spec:
capacity:
storage: 100Gi
accessModes:
- ReadWriteOnce
awsElasticBlockStore:
volumeID: vol-12345678
fsType: ext4
NFS
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfs-pv
spec:
capacity:
storage: 100Gi
accessModes:
- ReadWriteMany
nfs:
server: nfs.example.com
path: /share
GCP Persistent Disk
apiVersion: v1
kind: PersistentVolume
metadata:
name: gcp-pv
spec:
capacity:
storage: 100Gi
accessModes:
- ReadWriteOnce
gcePersistentDisk:
pdName: gce-disk-1
fsType: ext4
StatefulSet with Persistent Storage
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
spec:
serviceName: mysql
replicas: 1
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:8.0
ports:
- containerPort: 3306
env:
- name: MYSQL_ROOT_PASSWORD
value: secretpassword
volumeMounts:
- name: data
mountPath: /var/lib/mysql
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: standard
resources:
requests:
storage: 10Gi
Expanding Volumes
# Check if storage class allows expansion
kubectl get storageclass
# Edit PVC to increase size
kubectl patch pvc pvc-example -p '{"spec":{"resources":{"requests":{"storage":"20Gi"}}}}'
# Monitor expansion
kubectl describe pvc pvc-example
Backup and Recovery
Snapshot (if supported)
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
name: mysql-snapshot
spec:
volumeSnapshotClassName: csi-snapshotter
source:
persistentVolumeClaimName: mysql-storage
Manual Backup
# Mount volume in backup pod
kubectl run backup \
--image=ubuntu \
-it \
--rm \
-v mysql-storage:/data \
-- tar czf /backup/mysql_backup.tar.gz /data
Monitoring Storage
# List persistent volumes
kubectl get pv
# List persistent volume claims
kubectl get pvc
# Describe PVC
kubectl describe pvc app-storage
# Check storage usage
kubectl exec -it pod-name -- df -h
Best Practices
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: production-storage
spec:
accessModes:
- ReadWriteOnce
storageClassName: high-performance
resources:
requests:
storage: 100Gi
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: database
spec:
serviceName: database
replicas: 1
template:
metadata:
labels:
app: database
spec:
containers:
- name: db
image: postgres:15
resources:
requests:
memory: "1Gi"
cpu: "500m"
limits:
memory: "2Gi"
cpu: "1000m"
volumeMounts:
- name: data
mountPath: /var/lib/postgresql/data
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: high-performance
resources:
requests:
storage: 100Gi
FAQ
Q: What's the difference between PV and PVC? A: PV is the storage resource. PVC is a request for storage. PV is created by admin; PVC created by applications.
Q: Can I share storage between pods? A: Only if using ReadWriteMany access mode. NFS supports this; EBS doesn't. Use StatefulSets for persistent apps.
Q: What happens to data when pod is deleted? A: With PVC, data persists. Pod can be deleted and rescheduled; data remains bound to PVC.
Advertisement