Kubernetes Persistent Volumes

February 13, 2026 | Kubernetes Storage EBS

Dynamic provisioning with CSI drivers.

Persistent Storage in Kubernetes

Kubernetes pods are ephemeral — when a pod dies, its local storage is lost. For stateful workloads like databases, file uploads, and caches, you need Persistent Volumes (PVs) that survive pod restarts and rescheduling. Understanding the PV subsystem is critical for running production stateful applications.

Storage Architecture

  • PersistentVolume (PV) — A piece of storage provisioned by an admin or dynamically by a StorageClass
  • PersistentVolumeClaim (PVC) — A request for storage by a pod. PVCs bind to PVs that satisfy their requirements.
  • StorageClass — Defines how storage is dynamically provisioned (e.g., EBS gp3, EFS, local SSD)

Dynamic Provisioning with StorageClass

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: fast-ssd
provisioner: ebs.csi.aws.com
parameters:
  type: gp3
  iops: "5000"
  throughput: "250"
  encrypted: "true"
reclaimPolicy: Retain
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true

PersistentVolumeClaim

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: postgres-data
spec:
  accessModes:
  - ReadWriteOnce
  storageClassName: fast-ssd
  resources:
    requests:
      storage: 100Gi

Using PVCs in Pods

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: postgres
spec:
  serviceName: postgres
  replicas: 1
  template:
    spec:
      containers:
      - name: postgres
        image: postgres:15
        volumeMounts:
        - name: data
          mountPath: /var/lib/postgresql/data
  volumeClaimTemplates:
  - metadata:
      name: data
    spec:
      accessModes: ["ReadWriteOnce"]
      storageClassName: fast-ssd
      resources:
        requests:
          storage: 100Gi

StatefulSets automatically create a unique PVC for each replica, ensuring data isolation between database instances.

Access Modes

ModeAbbreviationUse Case
ReadWriteOnceRWOSingle pod read/write (databases)
ReadOnlyManyROXMultiple pods read-only (shared config)
ReadWriteManyRWXMultiple pods read/write (shared files)

AWS Storage Options

  • EBS (gp3) — Block storage, RWO only, ideal for databases. 20% cheaper than gp2 with better baseline performance.
  • EFS — NFS-based, supports RWX, ideal for shared file systems. Higher latency than EBS but supports multi-AZ access.
  • FSx for Lustre — High-performance parallel file system for ML and HPC workloads.

Volume Expansion

If your StorageClass has allowVolumeExpansion: true, you can resize PVCs:

# Edit the PVC to increase size
kubectl patch pvc postgres-data -p '{"spec":{"resources":{"requests":{"storage":"200Gi"}}}}'

# For file-system based volumes, the pod may need a restart
kubectl delete pod postgres-0  # StatefulSet will recreate it with expanded volume

Backup Strategies

  • Volume snapshots — Use VolumeSnapshot CRDs for point-in-time backups
  • Application-level backup — pg_dump, mongodump before snapshotting
  • Velero — Cluster-wide backup including PVs, ideal for disaster recovery

Reclaim Policies

  • Retain — PV persists after PVC deletion (recommended for production)
  • Delete — PV and underlying storage are deleted with PVC (use for ephemeral environments)

Eazy SaaS Tip: We configure all production StorageClasses with reclaimPolicy: Retain and automated VolumeSnapshot schedules. This ensures that even if a PVC is accidentally deleted, the data remains recoverable. We've saved clients from data loss multiple times with this approach.