8.1 Storage Concepts (PVs, PVCs, StorageClasses & CSI)

Key Takeaways

  • Kubernetes separates temporary container storage (emptyDir, hostPath) from persistent storage that outlives Pod lifecycles.
  • PersistentVolumes (PVs) and PersistentVolumeClaims (PVCs) decouple cluster storage administration from application storage consumption.
  • StorageClasses enable dynamic volume provisioning, automatically creating cloud or SAN storage volumes on demand without manual administrator intervention.
  • Container Storage Interface (CSI) provides a standardized, out-of-tree API specification allowing third-party storage vendors to write plugins independently of core Kubernetes code.
  • Access modes (ReadWriteOnce, ReadOnlyMany, ReadWriteMany, ReadWriteOncePod) and reclaim policies (Retain, Delete) govern how volumes are mounted and recycled across the cluster.
Last updated: August 2026

8.1 Storage Concepts (PVs, PVCs, StorageClasses & CSI)

Quick Answer: Kubernetes separates transient container storage from persistent data through PersistentVolume (PV) and PersistentVolumeClaim (PVC) abstractions. StorageClasses enable dynamic volume provisioning via Container Storage Interface (CSI) drivers, freeing operators from manual storage allocation. PV access modes (RWO, ROX, RWX, RWOP) determine node mounting capabilities, while reclaim policies (Retain, Delete) define storage lifecycle behavior when claims are deleted.

Managing state in containerized environments presents unique challenges. Containers are designed to be disposable and stateless, meaning data stored directly inside a container's root filesystem disappears when the container crashes or restarts. To run stateful applications—such as databases, key-value stores, and file management systems—Kubernetes provides a robust suite of storage abstractions that separate data persistence from container lifecycles.


Ephemeral vs. Persistent Storage

In Kubernetes, storage resources fall into two fundamental categories based on their lifecycle behavior:

Storage TypeCharacteristics & DriversBest Used For
Ephemeral StorageTied directly to the lifecycle of a Pod. Data is created when the Pod starts and completely erased when the Pod is deleted or rescheduled. Implemented using emptyDir or hostPath.Temporary scratch space, caching layers, log buffering, or sharing temporary data between containers in a single Pod.
Persistent StorageIndependent of Pod lifecycles. Data persists across Pod restarts, container crashes, and node migrations. Implemented via cloud block storage (AWS EBS, GCP Persistent Disk), SAN/NAS, or distributed filesystems (Ceph).Relational databases (PostgreSQL, MySQL), stateful stores (Kafka, Elasticsearch), and persistent user file uploads.

PV & PVC Decoupling Architecture

To maintain clear organizational boundaries, Kubernetes decouples storage infrastructure details from application storage requests using two complementary API resources: PersistentVolumes (PVs) and PersistentVolumeClaims (PVCs).

This separation follows a role-based operational model:

ResourceResponsibility & ScopeDescription
PersistentVolume (PV)Cluster Administrator (Cluster-Scoped)A piece of storage in the cluster that has been provisioned manually by an admin or dynamically by a StorageClass. Contains infrastructure details such as disk capacity, driver type, NFS endpoints, or cloud volume IDs.
PersistentVolumeClaim (PVC)Application Developer (Namespace-Scoped)A request for storage by a user or workload. Specifies storage size requirements, access modes, and optional StorageClass filters without referencing underlying storage hardware.
+-------------------------------------------------------------+
|                     Storage Lifecycle                       |
|                                                             |
|   +-------------------+              +------------------+   |
|   |  Developer (PVC)  |  ---Binds---> | Admin/CSI (PV)   |   |
|   |  (Size, Access)   |              | (Capacity, Disk) |   |
|   +-------------------+              +------------------+   |
|             |                                 |             |
|             +------------ Mounts ------------+             |
|                               v                             |
|                        +--------------+                     |
|                        | Stateful Pod |                     |
|                        +--------------+                     |
+-------------------------------------------------------------+

The PV-PVC Binding Lifecycle

  1. Provisioning: Storage is provisioned either statically (admin creates PVs in advance) or dynamically (StorageClass creates PVs on demand).
  2. Binding: The Kubernetes control plane matches a user's PVC to a suitable PV based on capacity and access mode, establishing a strict 1-to-1 binding.
  3. Using: The Pod specifies the PVC in its volume definitions, and the container runtime mounts the volume into the container filesystem path.
  4. Reclaiming: When the user deletes the PVC, the PV's Reclaim Policy dictates what happens to the underlying storage volume.

StorageClasses & Dynamic Provisioning

Before StorageClasses were introduced, cluster administrators had to manually pre-provision dozens of PersistentVolumes (Static Provisioning). If no pre-provisioned PV matched a developer's PVC request, the PVC remained stuck in a Pending state indefinitely.

A StorageClass provides a blueprint for Dynamic Provisioning. It defines which volume plugin (provisioner) should be invoked and what parameters (e.g., disk type, IOPS, replication factors) should be passed to the underlying storage provider when a PVC is submitted.

StorageClass and PVC Example

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: fast-ebs
provisioner: ebs.csi.aws.com
volumeBindingMode: WaitForFirstConsumer
reclaimPolicy: Delete
parameters:
  type: gp3
  iops: "3000"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: db-data-pvc
  namespace: database
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: fast-ebs
  resources:
    requests:
      storage: 50Gi

When the db-data-pvc manifest is created, the AWS EBS CSI provisioner automatically allocates a 50Gi gp3 volume in AWS and creates a corresponding PersistentVolume object bound to the claim.


Container Storage Interface (CSI)

Historically, Kubernetes included storage driver code directly inside the core Kubernetes codebase (known as in-tree drivers). This architecture posed major drawbacks: storage vendors had to wait for official Kubernetes release cycles to release bug fixes or new features, and third-party storage code running in the core API server created security and stability risks.

The Container Storage Interface (CSI) is an industry-wide specification developed jointly by the container-orchestrator communities — Kubernetes, Mesos, Cloud Foundry, and Nomad — that standardizes how storage vendors build out-of-tree storage plugins. It is a cross-project specification rather than a CNCF-hosted project, which is precisely why a single driver works across several orchestrators.

Architecture of a CSI Driver

CSI separates storage management into two decoupled components:

  1. CSI Controller Plugin (Cluster-Scoped): Operates as a deployment in the control plane. Handles high-level volume lifecycle operations such as volume creation, deletion, cloud attachment, detachment, and volume snapshotting (CreateVolume, DeleteVolume, ControllerPublishVolume).
  2. CSI Node Plugin (Node-Scoped): Runs as a DaemonSet on every worker node. Handles node-level mounting operations, formatting block devices, and mounting directories into Pod containers (NodeStageVolume, NodePublishVolume).

CSI plugins enable features like volume resizing, volume snapshotting, inline ephemeral volumes, and volume cloning without modifying Kubernetes core source code.


Volume Access Modes & Reclaim Policies

Understanding how volumes are mounted and cleaned up is critical for designing fault-tolerant storage systems.

PersistentVolume Access Modes

Access ModeAbbreviationOperational CapabilityTypical Drivers
ReadWriteOnceRWOVolume can be mounted as read-write by a single node at a time. Multiple Pods on the same node can read/write.Cloud Block Storage (AWS EBS, GCP PD, Azure Disk).
ReadOnlyManyROXVolume can be mounted as read-only by many nodes concurrently.Network File Systems (NFS), read-only media assets.
ReadWriteManyRWXVolume can be mounted as read-write by many nodes simultaneously.Distributed File Systems (NFS, AWS EFS, CephFS).
ReadWriteOncePodRWOPVolume can be mounted as read-write by a single Pod across the entire cluster. (Introduced in K8s v1.22+).Single-instance databases requiring strict single-writer lockouts.

PersistentVolume Reclaim Policies

When an application developer deletes a PersistentVolumeClaim, the PV's Reclaim Policy instructs Kubernetes how to handle the released storage resource:

Reclaim PolicyBehavior Upon PVC DeletionBest Used For
RetainThe PersistentVolume remains in the cluster in a Released state. The data on the underlying physical storage is preserved. No other PVC can bind to it until an admin manually cleans it up.Critical production databases where data loss prevention is paramount.
DeleteThe PersistentVolume object and the actual underlying physical infrastructure storage (e.g., AWS EBS volume) are automatically deleted.Dynamic workloads, stateless test environments, and standard cloud-native deployments.
Recycle (Deprecated)Performs a basic data wipe (rm -rf /volume/*) on the volume to make it available for binding by a new claim.Deprecated in favor of dynamic provisioning via CSI.

Complete Manifest Example: Mounting Persistent Storage to a Pod

The following example demonstrates how a Pod consumes storage from a PVC bound to a dynamic StorageClass.

apiVersion: v1
kind: Pod
metadata:
  name: postgres-db
  namespace: database
spec:
  containers:
    - name: postgresql
      image: postgres:15
      ports:
        - containerPort: 5432
      volumeMounts:
        - name: pgdata-volume
          mountPath: /var/lib/postgresql/data
  volumes:
    - name: pgdata-volume
      persistentVolumeClaim:
        claimName: db-data-pvc

Key Takeaways

  • Ephemeral vs. Persistent: Ephemeral storage (emptyDir) dies with the Pod; persistent storage outlives Pod container lifecycles.
  • PV / PVC Separation: PVs define infrastructure storage resources (Admin); PVCs express storage requests (Developer).
  • StorageClasses: Enable dynamic provisioning of underlying cloud or SAN storage volumes on demand.
  • CSI Standard: Out-of-tree storage interface allowing third-party vendors to add volume functionality without editing core Kubernetes code.
  • Access & Reclaim: Access modes (RWO, ROX, RWX, RWOP) control node mounting limits, while reclaim policies (Retain, Delete) define post-deletion volume lifecycles.
Test Your Knowledge

Which Kubernetes storage abstraction allows application developers to request storage capacity without knowing the underlying cloud provider or hardware implementation details?

A
B
C
D
Test Your Knowledge

What is the primary advantage of the Container Storage Interface (CSI) over legacy in-tree volume plugins in Kubernetes?

A
B
C
D
Test Your Knowledge

What occurs when a PersistentVolumeClaim is deleted if the associated PersistentVolume has a reclaim policy set to Retain?

A
B
C
D