Introduction to Persistent Storage
In Kubernetes, Persistent Storage is essential for stateful applications that require data persistence beyond the lifecycle of Pods. Kubernetes provides a robust mechanism for managing storage using PersistentVolumes (PVs) and PersistentVolumeClaims (PVCs).
Why Persistent Storage?
- Ephemeral Nature of Pods: Pod storage is temporary; Persistent Storage ensures data continuity.
- Stateful Applications: Databases, content management systems, and analytics tools need persistent storage.
- Scalability: Easily provision storage across multiple nodes.
Key Kubernetes Storage Concepts
- Volumes: Attach storage to a Pod’s lifecycle.
- PersistentVolume (PV): A cluster-wide resource representing physical storage.
- PersistentVolumeClaim (PVC): A request for storage by a user or application.
- StorageClass: Defines the storage type, provisioning mechanism, and parameters.
Step-by-Step Implementation
Step 1: Create a PersistentVolume (PV)
PersistentVolume YAML
Save this as persistent-volume.yaml:
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-example
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
hostPath:
path: "/mnt/data"
Explanation:
- capacity: Specifies storage size.
- accessModes:
ReadWriteOnce: Single node read/write access.ReadOnlyMany: Multiple nodes read-only access.ReadWriteMany: Multiple nodes read/write access.
- hostPath: Points to a directory on the node.
Apply the PV:
kubectl apply -f persistent-volume.yaml
Check the PV:
kubectl get pv
Step 2: Create a PersistentVolumeClaim (PVC)
PersistentVolumeClaim YAML
Save this as persistent-volume-claim.yaml:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-example
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 500Mi
Explanation:
- accessModes: Matches the PV access modes.
- resources.requests.storage: The requested storage size.
Apply the PVC:
kubectl apply -f persistent-volume-claim.yaml
Check the PVC:
kubectl get pvc
Step 3: Use the PVC in a Pod
Pod YAML
Save this as pod-with-pvc.yaml:
apiVersion: v1
kind: Pod
metadata:
name: pod-with-pvc
spec:
containers:
- name: app-container
image: nginx
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: storage-volume
volumes:
- name: storage-volume
persistentVolumeClaim:
claimName: pvc-example
Apply the Pod:
kubectl apply -f pod-with-pvc.yaml
Verify the Pod is running:
kubectl get pods
Access the mounted volume inside the Pod:
kubectl exec pod-with-pvc -- ls /usr/share/nginx/html
Step 4: Dynamic Provisioning with StorageClass
Create a StorageClass
Save this as storage-class.yaml:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: dynamic-storage
provisioner: kubernetes.io/aws-ebs # Replace based on your cloud provider
parameters:
type: gp2
Apply the StorageClass:
kubectl apply -f storage-class.yaml
Update PVC to Use StorageClass
Save this as pvc-with-storage-class.yaml:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-dynamic
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: dynamic-storage
Apply the PVC:
kubectl apply -f pvc-with-storage-class.yaml
Verify the dynamically provisioned PV:
kubectl get pv
Step 5: StatefulSets for Stateful Applications
StatefulSet Example
Save this as statefulset.yaml:
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:5.7
env:
- name: MYSQL_ROOT_PASSWORD
value: "password"
volumeMounts:
- name: mysql-persistent-storage
mountPath: "/var/lib/mysql"
volumeClaimTemplates:
- metadata:
name: mysql-persistent-storage
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 2Gi
Apply the StatefulSet:
kubectl apply -f statefulset.yaml
Verify StatefulSet and PVCs:
kubectl get statefulset
kubectl get pvc
Monitoring Persistent Storage
Check PV and PVC Details
kubectl describe pv pv-example
kubectl describe pvc pvc-example
Check Mounted Volumes in Pods
kubectl exec pod-with-pvc -- df -h
Best Practices
- Use StorageClasses: Automate storage provisioning using dynamic provisioning.
- Understand Access Modes: Choose the correct access mode based on workload needs.
- Set Retain Policies: Use
Retain,Recycle, orDeletepolicies wisely for PVs. - Monitor Storage Usage: Prevent Pods from exhausting allocated storage.
Troubleshooting Persistent Storage
- PVC Pending:
- Check PV availability and access modes.
- Ensure the storage request matches available PVs.
kubectl describe pvc pvc-example
Volume Not Mounting:
- Inspect Pod logs and events.
kubectl describe pod pod-with-pvc
kubectl logs pod-with-pvc
- Dynamic Provisioning Fails:
- Verify the StorageClass parameters and provisioner.
- Check cloud provider configuration (e.g., IAM roles for AWS).
Conclusion
In this chapter, you learned how to:
- Use PersistentVolumes and PersistentVolumeClaims for stateful applications.
- Dynamically provision storage using StorageClasses.
- Leverage StatefulSets for managing applications like databases.