Chapter 6.2 - PersistentVolumes and PersistentVolumeClaims
Learning Objectives
By the end of this chapter, you will be able to:
- Understand PersistentVolumes (PV) and PersistentVolumeClaims (PVC)
- Create and use PVs and PVCs
- Understand access modes (RWO, ROX, RWX)
- Manage the storage lifecycle
- Understand reclaim policies
- Choose the right type of storage based on the use case
Introduction
Ephemeral volumes (emptyDir, tmpfs) are deleted when the Pod is terminated. For important data that needs to persist (databases, user files, etc.), Kubernetes uses PersistentVolumes and PersistentVolumeClaims.
Key Concepts
PersistentVolume (PV)
A PersistentVolume is a storage resource in the cluster that has been provisioned by an administrator. It is a cluster-level resource, independent of Pods.
PersistentVolumeClaim (PVC)
A PersistentVolumeClaim is a storage request by a user. The PVC binds a PV to a Pod.
Creating a PersistentVolume
Example: PV with hostPath (Local Development)
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-volume
labels:
type: local
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: manual
hostPath:
path: /data/pv-volume
Note: hostPath is for local development only. In production, use cloud solutions (EBS, Azure Disk, GCE Persistent Disk) or NFS.
Example: PV with NFS
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-nfs
spec:
capacity:
storage: 50Gi
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
storageClassName: nfs
nfs:
server: nfs-server.example.com
path: /exports/data
Creating a PersistentVolumeClaim
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pv-claim
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
storageClassName: manual
Binding process:
Access Modes
Access modes determine how the volume can be mounted:
ReadWriteOnce (RWO)
- Only one node can mount the volume for read-write
- Multiple Pods on the same node can share the volume
- Use case: Databases, stateful applications
ReadOnlyMany (ROX)
- Multiple nodes can mount the volume as read-only
- Use case: Read-only configuration files, shared data
ReadWriteMany (RWX)
- Multiple nodes can mount the volume for read-write
- Use case: Shared file systems (NFS, GlusterFS)
Usage in a Pod
apiVersion: v1
kind: Pod
metadata:
name: pv-pod
spec:
containers:
- name: app
image: nginx:1.20
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
persistentVolumeClaim:
claimName: pv-claim
Full flow:
Reclaim Policies
The reclaim policy determines what happens to the PV when the PVC is deleted.
Retain
The PV is retained even after the PVC is deleted. Data remains intact.
Use case:
- Important data to be saved
- Need for manual recovery
- Compliance and audit
Delete
The PV is automatically deleted with the PVC. Data is lost.
Use case:
- Temporary data
- Development environments
- Dynamic provisioning
Recycle (Deprecated)
This policy is deprecated. Use Retain or Delete instead.
Complete Example: Database
Step 1: Create the PersistentVolume
apiVersion: v1
kind: PersistentVolume
metadata:
name: postgres-pv
labels:
app: postgres
spec:
capacity:
storage: 20Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: fast-ssd
hostPath:
path: /data/postgres
Step 2: Create the PersistentVolumeClaim
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: postgres-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
storageClassName: fast-ssd
Step 3: Use in a Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: postgres
spec:
replicas: 1
selector:
matchLabels:
app: postgres
template:
metadata:
labels:
app: postgres
spec:
containers:
- name: postgres
image: postgres:14
env:
- name: PGDATA
value: /var/lib/postgresql/data/pgdata
volumeMounts:
- name: postgres-storage
mountPath: /var/lib/postgresql/data
volumes:
- name: postgres-storage
persistentVolumeClaim:
claimName: postgres-pvc
Useful Commands
View PVs and PVCs
# List PVs
kubectl get pv
# Details of a PV
kubectl describe pv pv-volume
# List PVCs
kubectl get pvc
# Details of a PVC
kubectl describe pvc pv-claim
Check Binding
# View binding status
kubectl get pv
kubectl get pvc
# View details
kubectl get pv pv-volume -o yaml
kubectl get pvc pv-claim -o yaml
Delete a PVC
# Delete the PVC
kubectl delete pvc pv-claim
# Check PV status after deletion
kubectl get pv pv-volume
Storage Types
Local Storage (hostPath)
Advantages:
- Simple for development
- No external dependency
Disadvantages:
- Not portable
- Risk of data loss
- Does not work with multiple nodes
Usage: Local development only
NFS (Network File System)
Advantages:
- Supports ReadWriteMany
- Shareable between nodes
- Easy to set up
Disadvantages:
- Limited performance
- Single point of failure
- Requires an NFS server
Usage: Shared files, collaborative applications
Cloud Storage (EBS, Azure Disk, GCE PD)
Advantages:
- High performance
- Cloud-native integration
- Dynamic provisioning
- Automatic snapshots
Disadvantages:
- Cost based on usage
- Dependency on cloud provider
Usage: Production, critical applications
Best Practices
1. Use StorageClasses
Prefer dynamic provisioning with StorageClasses rather than manual PV creation.
2. Choose the Right Reclaim Policy
- Retain: For important data
- Delete: For temporary data
3. Appropriate Size
Do not over-allocate. Start small and grow as needed (with allowVolumeExpansion: true).
4. Backups
Implement regular backups for important data.
5. Monitoring
Monitor storage usage to avoid exhaustion.
Summary
In this chapter, you learned:
PersistentVolume (PV): Cluster-level storage resource
PersistentVolumeClaim (PVC): User's storage request
Access Modes: RWO (one node), ROX (multiple nodes read-only), RWX (multiple nodes read-write)
Reclaim Policy: Retain (keep) or Delete (remove)
Storage types: hostPath (dev), NFS (shared), Cloud (production)
Usage: Via persistentVolumeClaim in Pods
Best practices: StorageClasses, appropriate size, backups
Next Steps
Chapter 6.3: StorageClasses and Dynamic Provisioning
Lab 6.2: PersistentVolumes and PVCs
Chapter created on: December 2024