Kubernetes Objects - PersistentVolume & PersistentVolumeClaim
Overview
PersistentVolumes (PVs) and PersistentVolumeClaims (PVCs) provide a way for users to request and consume storage resources without knowing the details of the underlying storage infrastructure.
PersistentVolume (PV)
Purpose
PersistentVolumes are used for:
- Storage Abstraction: Providing a unified interface for different storage backends
- Storage Management: Centralized management of storage resources
- Storage Provisioning: Dynamic and static storage allocation
Basic PV Example
apiVersion: v1
kind: PersistentVolume
metadata:
name: mysqlpv
labels:
app: mysql
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
nfs:
path: /
server: 10.255.255.10
PersistentVolumeClaim (PVC)
Purpose
PersistentVolumeClaims are used for:
- Storage Requests: Users requesting specific storage resources
- Storage Consumption: Applications consuming allocated storage
- Storage Binding: Dynamic binding to available PVs
Basic PVC Example
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysqlclaim
spec:
accessModes:
- ReadWriteOnce
volumeMode: Filesystem
resources:
requests:
storage: 5Gi
storageClassName: ""
selector:
matchLabels:
app: mysql
Storage Backends
NFS Storage
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfs-pv
labels:
app: nfs-storage
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
nfs:
path: /data
server: nfs-server.example.com
Local Storage
apiVersion: v1
kind: PersistentVolume
metadata:
name: local-pv
labels:
app: local-storage
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
local:
path: /mnt/data
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- node-1
Access Modes
ReadWriteOnce (RWO)
apiVersion: v1
kind: PersistentVolume
metadata:
name: rwo-pv
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce # Single node can mount as read-write
persistentVolumeReclaimPolicy: Retain
hostPath:
path: /data
ReadWriteMany (RWX)
apiVersion: v1
kind: PersistentVolume
metadata:
name: rwx-pv
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteMany # Multiple nodes can mount as read-write
persistentVolumeReclaimPolicy: Retain
nfs:
path: /shared-data
server: nfs-server.example.com
Reclaim Policies
Retain Policy
apiVersion: v1
kind: PersistentVolume
metadata:
name: retain-pv
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain # Manual cleanup required
hostPath:
path: /data
Delete Policy
apiVersion: v1
kind: PersistentVolume
metadata:
name: delete-pv
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Delete # Automatic cleanup
awsElasticBlockStore:
volumeID: vol-12345678
fsType: ext4
Using PV/PVC with Deployments
MySQL with Persistent Storage
apiVersion: v1
kind: Secret
metadata:
name: mysqlsecret
type: Opaque
stringData:
password: P@ssw0rd!
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: mysqlpv
labels:
app: mysql
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
nfs:
path: /
server: 10.255.255.10
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysqlclaim
spec:
accessModes:
- ReadWriteOnce
volumeMode: Filesystem
resources:
requests:
storage: 5Gi
storageClassName: ""
selector:
matchLabels:
app: mysql
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysqldeployment
labels:
app: mysql
spec:
replicas: 1
selector:
matchLabels:
app: mysql
strategy:
type: Recreate
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql
ports:
- containerPort: 3306
volumeMounts:
- mountPath: "/var/lib/mysql"
name: mysqlvolume
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysqlsecret
key: password
volumes:
- name: mysqlvolume
persistentVolumeClaim:
claimName: mysqlclaim
Basic Commands
# List PersistentVolumes
kubectl get pv
kubectl get persistentvolume
# List PersistentVolumeClaims
kubectl get pvc
kubectl get persistentvolumeclaim
# Check PV status
kubectl describe pv <pv-name>
# Check PVC status
kubectl describe pvc <pvc-name>
# Delete PV
kubectl delete pv <pv-name>
# Delete PVC
kubectl delete pvc <pvc-name>