Learn how to manage persistent storage in Kubernetes using Persistent Volumes, Persistent Volume Claims, and Storage Classes. Understand how to provide persistent storage for stateful applications.
Table of Contents
1. Storage Overview
Containers are ephemeral - when a Pod is deleted, all data in its containers is lost. For stateful applications, you need persistent storage that survives Pod restarts and deletions.
1.1 Storage Requirements
Applications may need storage for:
- Database files
- Application logs
- User uploads
- Configuration files
- Cache data
1.2 Kubernetes Storage Model
Kubernetes provides a storage abstraction with three main components:
- PersistentVolume (PV): Cluster-level storage resource
- PersistentVolumeClaim (PVC): User's request for storage
- StorageClass: Describes different classes of storage
2. Volume Types
Kubernetes supports many volume types:
2.1 Ephemeral Volumes
- emptyDir: Temporary directory, deleted when Pod is deleted
- configMap/secret: Mount ConfigMaps and Secrets as volumes
2.2 Persistent Volumes
- NFS: Network File System
- iSCSI: Internet Small Computer System Interface
- Cloud provider volumes: AWS EBS, GCE Persistent Disk, Azure Disk
- Local: Local storage on the Node
- CSI: Container Storage Interface (modern standard)
2.3 Example: emptyDir Volume
apiVersion: v1
kind: Pod
metadata:
name: app-pod
spec:
containers:
- name: app
image: myapp:1.0
volumeMounts:
- name: cache-volume
mountPath: /cache
volumes:
- name: cache-volume
emptyDir: {}
3. Persistent Volumes
A PersistentVolume (PV) is a cluster-level storage resource provisioned by an administrator or dynamically provisioned using StorageClasses.
3.1 PV Lifecycle
PVs go through these phases:
- Available: Free and available for binding
- Bound: Bound to a PVC
- Released: PVC deleted, but PV not yet reclaimed
- Failed: Automatic reclamation failed
3.2 Static PV Definition
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-example
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: manual
hostPath:
path: /mnt/data
3.3 Access Modes
- ReadWriteOnce (RWO): Can be mounted as read-write by a single Node
- ReadOnlyMany (ROX): Can be mounted read-only by many Nodes
- ReadWriteMany (RWX): Can be mounted as read-write by many Nodes
- ReadWriteOncePod (RWOP): Can be mounted as read-write by a single Pod
3.4 Reclaim Policies
- Retain: Manual reclamation (admin must delete PV)
- Recycle: Basic scrub (deprecated)
- Delete: Delete associated storage asset (cloud volumes)
3.5 Cloud Provider PV Example
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-aws
spec:
capacity:
storage: 20Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Delete
storageClassName: gp2
awsElasticBlockStore:
volumeID: vol-12345678
fsType: ext4
4. Persistent Volume Claims
A PersistentVolumeClaim (PVC) is a request for storage by a user. It specifies the size, access modes, and storage class needed.
4.1 PVC Definition
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-example
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
storageClassName: manual
4.2 Binding Process
Kubernetes binds a PVC to a PV that matches:
- Access modes
- Storage class
- Size (PV capacity must be >= PVC request)
4.3 Using PVC in Pod
apiVersion: v1
kind: Pod
metadata:
name: app-pod
spec:
containers:
- name: app
image: myapp:1.0
volumeMounts:
- name: storage
mountPath: /data
volumes:
- name: storage
persistentVolumeClaim:
claimName: pvc-example
4.4 PVC Status
PVC can be in these states:
- Pending: Waiting for a PV to be bound
- Bound: Successfully bound to a PV
- Lost: PV was deleted
4.5 Managing PVCs
# Create PVC
kubectl apply -f pvc.yaml
# List PVCs
kubectl get pvc
# Describe PVC
kubectl describe pvc pvc-example
# Delete PVC
kubectl delete pvc pvc-example
5. Storage Classes
A StorageClass describes different classes of storage available in the cluster. It enables dynamic provisioning of PersistentVolumes.
5.1 StorageClass Definition
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast-ssd
provisioner: kubernetes.io/aws-ebs
parameters:
type: gp3
fsType: ext4
encrypted: "true"
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
5.2 Key Parameters
- provisioner: Determines which volume plugin is used
- parameters: Passed to the provisioner
- volumeBindingMode: When to provision and bind volumes
- allowVolumeExpansion: Whether volumes can be expanded
5.3 Volume Binding Modes
- Immediate: Provision and bind immediately
- WaitForFirstConsumer: Wait until Pod using PVC is created
5.4 Default StorageClass
Mark a StorageClass as default to use it when no storageClassName is specified:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: standard
annotations:
storageclass.kubernetes.io/is-default-class: "true"
provisioner: kubernetes.io/aws-ebs
parameters:
type: gp2
6. Dynamic Provisioning
Dynamic provisioning automatically creates storage when a PVC is created, eliminating the need to pre-create PVs.
6.1 How It Works
- User creates a PVC with a StorageClass
- Kubernetes detects the PVC
- Storage provisioner creates a PV
- PV is bound to the PVC
- Pod can use the PVC
6.2 Example: Dynamic PVC
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-dynamic
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
storageClassName: fast-ssd # Uses StorageClass for dynamic provisioning
6.3 Benefits
- No need to pre-create PVs
- Storage created on-demand
- Simplified management
- Cost-effective (pay for what you use)
7. Volume Modes
Volumes can be used in two modes:
7.1 Filesystem Mode (Default)
Volume is mounted as a directory tree. Most common use case.
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-filesystem
spec:
capacity:
storage: 10Gi
volumeMode: Filesystem # Default
accessModes:
- ReadWriteOnce
# ... storage details
7.2 Block Mode
Volume is used as a raw block device. Used for databases and other applications that need direct block access.
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-block
spec:
capacity:
storage: 10Gi
volumeMode: Block
accessModes:
- ReadWriteOnce
# ... storage details
apiVersion: v1
kind: Pod
metadata:
name: app-pod
spec:
containers:
- name: app
image: myapp:1.0
volumeDevices:
- name: block-storage
devicePath: /dev/xvda
volumes:
- name: block-storage
persistentVolumeClaim:
claimName: pvc-block
8. Best Practices
8.1 Use Dynamic Provisioning
Prefer StorageClasses and dynamic provisioning over static PVs for easier management.
8.2 Set Appropriate Access Modes
Choose the right access mode based on your application needs. Use ReadWriteOncePod for databases.
8.3 Use WaitForFirstConsumer
Set volumeBindingMode to WaitForFirstConsumer for better Pod scheduling, especially with zone-specific storage.
8.4 Enable Volume Expansion
Set allowVolumeExpansion: true in StorageClass to allow PVC expansion without recreating Pods.
8.5 Backup Important Data
Implement backup strategies for critical data. Use Velero or cloud provider backup solutions.
8.6 Monitor Storage Usage
Monitor PVC usage and set up alerts for storage capacity. Use metrics to track storage consumption.
8.7 Use StatefulSets for Stateful Applications
For stateful applications requiring stable network identities and ordered deployment, use StatefulSets instead of Deployments.
Summary: Kubernetes provides PersistentVolumes, PersistentVolumeClaims, and StorageClasses for managing persistent storage. Use dynamic provisioning with StorageClasses for easier management. Choose appropriate access modes and volume binding modes based on your application requirements.
0 Comments