Skip to content

7.06 Persistent Volume Claims (PVC)

Abstract

Persistent Volume Claims (PVCs) are requests for storage in Kubernetes.

Administrators create Persistent Volumes (PVs) as storage resources, and users create PVCs to claim storage for their applications.

PVCs make storage consumption easier and help separate storage administration from application deployment.


PV and PVC Relationship

Persistent Volumes and Persistent Volume Claims are separate Kubernetes objects.

Object Created By Purpose
Persistent Volume (PV) Administrator Provides storage
Persistent Volume Claim (PVC) User / Developer Requests storage

Workflow:

Administrator creates PV
        ↓
User creates PVC
        ↓
Kubernetes finds matching PV
        ↓
PVC binds to PV
        ↓
Pod uses PVC

Note

Every PVC binds to one PV. This is a 1:1 relationship.


Why PVCs Are Needed

PVCs allow users to request storage without knowing the full backend details.

Users only specify:

  • storage size
  • access mode
  • storage class
  • volume mode
  • optional selector

Kubernetes handles matching the claim with a suitable PV.

Tip

PVCs make storage usage easier for developers while allowing admins to manage storage centrally.


Binding Process

When a PVC is created, Kubernetes tries to find a matching PV.

Matching is based on:

  • sufficient capacity
  • access modes
  • volume mode
  • storage class
  • selector labels

Note

A smaller PVC can bind to a larger PV if all other requirements match.

Example:

PVC requests: 500Mi
Available PV: 1Gi
Result: PVC can bind to the 1Gi PV

Warning

Even if the PVC uses only part of the PV capacity, the remaining capacity cannot be used by another PVC.


PVC Example

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: myclaim

spec:
  accessModes:
    - ReadWriteOnce

  resources:
    requests:
      storage: 500Mi

Create PVC:

kubectl create -f pvc-definition.yaml

View PVC:

kubectl get persistentvolumeclaim

Short command:

kubectl get pvc

Matching PV Example

Example Persistent Volume:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-vol1

spec:
  accessModes:
    - ReadWriteOnce

  capacity:
    storage: 1Gi

  awsElasticBlockStore:
    volumeID: <volume-id>
    fsType: ext4

The PVC requesting 500Mi can bind to this PV because:

  • access mode matches
  • requested capacity is less than available capacity
  • volume is available

Success

Once matched, the PVC status becomes Bound.


Viewing PVC Binding

Command:

kubectl get persistentvolumeclaim

Example output:

NAME      STATUS   VOLUME    CAPACITY   ACCESS MODES
myclaim   Bound    pv-vol1   1Gi        RWO

PVC status values:

Status Meaning
Pending No matching PV found yet
Bound PVC is successfully attached to a PV
Lost Bound PV is missing or unavailable

Note

If no matching PV exists, the PVC remains in Pending state until suitable storage becomes available.


Using PVCs in Pods

Once you create a PVC, you can use it in a Pod definition file by referencing the PVC claim name under the persistentVolumeClaim section.

The PVC is defined inside the volumes section, and then mounted into the container using volumeMounts.

apiVersion: v1
kind: Pod
metadata:
  name: mypod

spec:
  containers:
    - name: myfrontend
      image: nginx
      volumeMounts:
      - mountPath: "/var/www/html"
        name: mypd

  volumes:
    - name: mypd
      persistentVolumeClaim:
        claimName: myclaim

Tip

The claimName must match the name of an existing PVC.

In this example:

Field Meaning
claimName: myclaim Uses the PVC named myclaim
name: mypd Internal volume name inside the Pod
mountPath: /var/www/html Path where the volume is mounted inside the container

Note

The same approach applies to ReplicaSets and Deployments.
Add the volumes and volumeMounts configuration inside the Pod template section.


Using PVCs in Deployments

For Deployments, add the PVC under:

spec.template.spec.volumes

And mount it under:

spec.template.spec.containers[].volumeMounts

Example:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment

spec:
  replicas: 2

  selector:
    matchLabels:
      app: nginx

  template:
    metadata:
      labels:
        app: nginx

    spec:
      containers:
      - name: nginx
        image: nginx
        volumeMounts:
        - mountPath: "/var/www/html"
          name: mypd

      volumes:
      - name: mypd
        persistentVolumeClaim:
          claimName: myclaim

Warning

Make sure the storage backend supports the access mode required by multiple replicas.
For example, multiple Pods may require ReadWriteMany if they need simultaneous write access.


Using Selectors

If multiple PVs match a PVC, selectors can be used to choose a specific PV.

Example:

selector:
  matchLabels:
    type: fast

Tip

Use selectors when you want a PVC to bind only to a specific class or type of storage.


Access Modes

PVCs request storage using access modes.

Access Mode Meaning
ReadOnlyMany Many nodes can mount read-only
ReadWriteOnce One node can mount read-write
ReadWriteMany Many nodes can mount read-write

Warning

Access mode support depends on the storage backend.


Deleting PVCs

Delete PVC:

kubectl delete persistentvolumeclaim myclaim

What happens to the PV depends on the reclaim policy.


Reclaim Policy

A reclaim policy defines what happens to the PV after the PVC is deleted.

Reclaim Policy Description
Retain Keeps PV and data
Delete Deletes PV and backing storage
Recycle Deprecated; scrubs data and makes PV available again

Warning

Recycle is deprecated and should not be used in modern Kubernetes clusters.


Retain Policy

Retain keeps the PV and its data after the PVC is deleted.

persistentVolumeReclaimPolicy: Retain

Use this for:

  • databases
  • critical application data
  • data requiring manual recovery

Success

Retain is safer for production because it prevents accidental data deletion.


Delete Policy

Delete removes the PV and the underlying storage after the PVC is deleted.

persistentVolumeReclaimPolicy: Delete

Use this for:

  • temporary workloads
  • non-critical data
  • dynamically provisioned storage

Danger

Be careful with Delete. It can permanently remove storage and data.


Why Recycle Is Deprecated

The old Recycle policy attempted cleanup by deleting files inside the volume.

Example cleanup behavior:

rm -rf /scrub/*

This approach is not reliable because:

  • it does not guarantee secure erasure
  • it may not handle snapshots
  • it may fail due to permissions
  • it does not work consistently across storage providers
  • it does not handle cloud metadata or provider-level cleanup

Warning

Modern Kubernetes uses StorageClasses and CSI drivers for better provisioning and cleanup behavior.


Production Best Practices

Recommended

  • Use PVCs instead of direct Pod volumes for persistent workloads
  • Use StorageClasses for dynamic provisioning
  • Use CSI drivers for production storage
  • Use Retain for critical databases
  • Use Delete only for disposable workloads
  • Monitor PVC status and capacity
  • Back up important volumes regularly
  • Confirm access modes before scaling replicas

Do's

  • Use PVCs for stateful applications
  • Define clear storage requests
  • Use appropriate access modes
  • Use reclaim policies carefully
  • Test storage failover and recovery
  • Reference PVCs through persistentVolumeClaim in Pod specs

Don'ts

  • Don't assume every PV supports every access mode
  • Don't delete PVCs without understanding reclaim policy
  • Don't use deprecated Recycle
  • Don't depend on manual static PVs when dynamic provisioning is available
  • Don't store critical data without backups
  • Don't scale Pods with shared PVCs unless the storage supports the required access mode

Danger

Incorrect PVC and reclaim policy configuration can cause data loss or failed application recovery.


PVC Binding Rules Summary

Kubernetes binds PVCs to PVs based on:

Requirement Description
Capacity PV must have enough storage
Access Modes Must match PVC request
Volume Mode Filesystem or Block
StorageClass Must match if specified
Selector Optional label-based matching

Quick Commands

Create PVC:

kubectl create -f pvc-definition.yaml

List PVCs:

kubectl get pvc

Describe PVC:

kubectl describe pvc myclaim

Delete PVC:

kubectl delete pvc myclaim

List PVs:

kubectl get pv

Summary

Quote

  • PVCs are requests for storage
  • PVs are storage resources created by admins or dynamically provisioned
  • Kubernetes binds PVCs to matching PVs
  • PVC and PV binding is one-to-one
  • Pods use PVCs through the persistentVolumeClaim field
  • Reclaim policy controls what happens after PVC deletion
  • Production clusters should use StorageClasses and CSI drivers