DevOps Dictionary

Kubernetes PersistentVolumeClaim (PVC)

Kubernetes PersistentVolumeClaim (PVC) is a namespaced Kubernetes API object that requests durable storage for a pod. In practical terms, a PVC lets an application ask for storage with specific requirements, such as size, access mode, and storage class, without the pod needing to know the exact disk, file system, or cloud volume behind it.

What a PVC does

A PVC acts as the storage request between your workload and the underlying storage system. A pod does not usually mount a PersistentVolume directly. Instead, it references a PVC, and Kubernetes binds that claim to a matching PersistentVolume, often called a PV.

This separation helps platform teams expose storage options in a controlled way while application teams consume storage through a simple Kubernetes object.

  • Pods use the PVC in their volume configuration.
  • PVCs describe the requested storage.
  • PVs represent the actual durable storage resource.
  • StorageClasses define how storage is provisioned, such as AWS EBS, Azure Disk, Google Persistent Disk, NFS, or Ceph.

How it works

  1. You create a PVC in a namespace.
  2. The PVC requests storage, for example 20Gi, ReadWriteOnce, and a specific storageClassName.
  3. Kubernetes looks for a matching PV or asks the configured storage provisioner to create one dynamically.
  4. The PVC becomes Bound when Kubernetes connects it to a suitable PV.
  5. A pod in the same namespace mounts the PVC as a volume.

Most modern clusters use dynamic provisioning through a CSI driver. For example, in an Amazon EKS cluster, a PVC using an EBS-backed StorageClass can trigger creation of an AWS EBS volume. If you are managing Kubernetes manifests through infrastructure workflows, the same PVC object can be created with GitOps tools, Helm, kubectl, or Terraform, as shown in guides for deploying Kubernetes resources using Terraform.

Key fields in a PVC

  • storageClassName: Selects the type of storage to request. Examples include gp3 for AWS EBS, standard, or a custom class created by your platform team.
  • resources.requests.storage: Defines the requested capacity, such as 10Gi or 500Gi.
  • accessModes: Defines how the volume can be mounted, such as ReadWriteOnce, ReadOnlyMany, ReadWriteMany, or ReadWriteOncePod.
  • volumeMode: Defines whether the volume is exposed as a mounted file system or as a raw block device.
  • selector: Optionally restricts binding to PVs with matching labels, most often used with statically provisioned volumes.

Common access modes

  • ReadWriteOnce (RWO): The volume can be mounted as read-write by a single node. This is common for cloud block storage such as AWS EBS.
  • ReadOnlyMany (ROX): The volume can be mounted read-only by many nodes.
  • ReadWriteMany (RWX): The volume can be mounted read-write by many nodes. This usually requires shared file storage such as NFS, AWS EFS, Azure Files, or CephFS.
  • ReadWriteOncePod (RWOP): The volume can be mounted as read-write by only one pod across the cluster, when supported by the CSI driver.

Access modes describe what Kubernetes and the storage backend allow. They do not replace application-level locking, database consistency controls, or file coordination.

Simple PVC example

This example requests a 20 GiB volume from a StorageClass named gp3:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: app-data
  namespace: production
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: gp3
  resources:
    requests:
      storage: 20Gi

A pod can then mount the claim:

apiVersion: v1
kind: Pod
metadata:
  name: app
  namespace: production
spec:
  containers:
    - name: app
      image: example/app:1.0.0
      volumeMounts:
        - name: data
          mountPath: /var/lib/app
  volumes:
    - name: data
      persistentVolumeClaim:
        claimName: app-data

Common use cases

  • Databases: PostgreSQL, MySQL, MongoDB, and Redis deployments that need data to survive pod restarts.
  • StatefulSets: Workloads where each replica needs its own stable storage, such as postgres-0, postgres-1, and postgres-2.
  • Queues and brokers: Kafka, RabbitMQ, and similar systems that store messages or logs on disk.
  • Workflow tools: Platforms such as Apache Airflow may use PVCs for logs, DAG sync patterns, or supporting services, depending on the deployment design. See this example of deploying Apache Airflow on AWS EKS.
  • Build and cache storage: CI runners, package caches, and artifact processing jobs that need temporary or persistent disk space.

PVC vs PersistentVolume vs StorageClass

  • PersistentVolumeClaim: The request for storage. It is created in a namespace and used by pods.
  • PersistentVolume: The actual storage resource known to Kubernetes. It is cluster-scoped.
  • StorageClass: The template or policy used to provision storage dynamically.

A useful way to read the relationship is: the pod uses the PVC, the PVC binds to a PV, and the StorageClass controls how the PV gets created when dynamic provisioning is enabled.

Operational details to watch

  • Namespace scope: A pod can only use a PVC in the same namespace.
  • Binding mode: Some StorageClasses use WaitForFirstConsumer, which delays volume provisioning until a pod is scheduled. This helps Kubernetes pick a storage zone that matches the node.
  • Reclaim policy: The PV reclaim policy, such as Delete or Retain, controls what happens to the underlying storage after the PVC is deleted.
  • Expansion: PVC resizing works only when the StorageClass and CSI driver support volume expansion.
  • Backups: A PVC is not a backup strategy. Databases and critical state still need snapshots, logical backups, restore testing, and retention policies.
  • Scheduling constraints: Block storage is often tied to a zone. If the pod moves to a node in another zone, it may fail to attach unless your scheduling and topology settings are correct.

Benefits

  • Stable storage for unstable pods: Pods can be deleted, rescheduled, or replaced while data remains on the volume.
  • Cleaner separation of concerns: Application manifests request storage without hardcoding a cloud disk ID.
  • Automation-friendly: PVCs fit into normal Kubernetes workflows, including Helm, GitOps, Terraform, and CI/CD pipelines.
  • Portable interface: The Kubernetes API stays mostly the same even when the backend changes from EBS to Ceph, NFS, or another CSI-backed system.

Tradeoffs and limitations

  • Storage behavior still depends on the backend: EBS, EFS, NFS, local disks, and distributed storage systems have different latency, throughput, consistency, and attachment rules.
  • RWX storage can be harder to operate: Shared write access is useful, but it often brings more complexity and different performance patterns than single-writer block storage.
  • Deleting a PVC can delete data: If the bound PV uses a Delete reclaim policy, removing the PVC may remove the underlying cloud volume too.
  • Stateful workloads need more planning: PVCs solve storage attachment, but they do not handle replication, failover, schema migrations, or application recovery.

Real-world example

Suppose you run PostgreSQL on Kubernetes for a staging environment. You create a StatefulSet with a volume claim template that requests a 100 GiB PVC for each replica. Kubernetes creates a separate PVC for each pod, such as postgres-data-postgres-0 and postgres-data-postgres-1. If postgres-0 restarts or moves to another node in the same zone, Kubernetes reattaches the same volume so the database keeps its data.

For production, you would still plan backups, restore tests, monitoring, disk expansion, disruption budgets, and upgrade procedures. PVCs provide durable storage plumbing, but the database architecture remains your responsibility. This becomes especially important during cluster maintenance, where storage drivers, node drains, and workload disruption need careful handling. Practical planning for Kubernetes upgrades should include stateful workloads and their PVCs.

How PVCs fit into infrastructure workflows

Platform teams often define approved StorageClasses, backup policies, and default reclaim behavior. Application teams then request storage by creating PVCs in their namespaces. In cloud-native setups, the storage backend may be managed through Kubernetes controllers, Terraform, or control plane tools such as Crossplane. For example, teams that manage cloud resources through Kubernetes can use patterns similar to deploying AWS resources using Crossplane on Kubernetes.

Summary

A Kubernetes PersistentVolumeClaim is the standard way for a pod to request persistent storage. It hides backend storage details behind a Kubernetes object while still giving engineers control over size, access mode, and storage class. PVCs are essential for stateful workloads, but they need clear operational rules around backups, deletion, resizing, scheduling, and upgrades.

A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
R
S
T
U
V
W
Y
X
Z