Kubernetes Persistent Volumes — Storage Guide

Sanjeev SharmaSanjeev Sharma
4 min read

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.

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

Sanjeev Sharma

Written by

Sanjeev Sharma

Full Stack Engineer · E-mopro