Kubernetes Storage - The Static Way | PV & PVC Guide

Comprehensive guide to Kubernetes Static Storage Provisioning covering Persistent Volumes (PV), Persistent Volume Claims (PVC), access modes (RWO, ROX, RWX), reclaim policies (Retain, Delete), storage inefficiency challenges, and manual storage management workflows

Static Storage Provisioning

Persistent Volumes (PV)

  • Represent a storage resource in the cluster
  • Cluster-wide resource available to all namespaces
  • Provisioned by a cluster administrator
  • Backed by physical storage (NFS, iSCSI, cloud storage, etc.)
  • Exist independently of any individual pod

Persistent Volume Claims (PVC)

  • A request for storage by a user
  • One-to-one mapping to a Persistent Volume
  • Can be consumed by any container within a pod
  • One or more pods can use a Persistent Volume Claim
  • Namespace-scoped resource
Persistent Volume
Persistent Volume Claim
Pod
Cloud Storage

The 3-Step Process

  1. Define the Persistent Volume - Cluster administrator creates PV
  2. Claim a portion of the storage - User creates PVC that binds to PV
  3. Use the claim in a Pod - Pod mounts the PVC as a volume

Static Provisioning Drawback

Pod's Slice (10%)
Wasted (90%)

Resource Inefficiency

The pod only needs a small slice of the available storage, but no other pods can access the remaining storage while the first pod has a claim on the PV.

What a waste of resources!

Problem

  • PVs are allocated in fixed sizes
  • PVCs claim entire PVs even if they need less
  • Unused storage remains locked
  • Inefficient for small, multiple applications

Solution

  • Use Dynamic Provisioning with StorageClasses
  • Implement volume expansion when supported
  • Use smaller, dedicated PVs for specific needs
  • Consider ReadWriteMany volumes for sharing

Access Modes

ReadWriteMany (RWX)

The volume can be mounted as read-write by many pods

accessModes:
- ReadWriteMany

ReadOnlyMany (ROX)

The volume can be mounted read-only by many pods

accessModes:
- ReadOnlyMany

ReadWriteOnce (RWO)

The volume can be mounted as read-write by a single pod

accessModes:
- ReadWriteOnce

Note: With ReadWriteOnce, the pod that mounts the volume first will be able to write to it. Other pods can mount it in read-only mode if the storage backend supports it.

Reclaim Policies

Delete Policy

Delete the data upon PVC deletion

This is the default policy for dynamically provisioned volumes.

persistentVolumeReclaimPolicy: Delete

Retain Policy

Keeps the data upon PVC deletion

Manual cleanup required. Keeps data safe from accidental deletion.

persistentVolumeReclaimPolicy: Retain

Recycle Policy (Deprecated)

The Recycle policy was available in earlier Kubernetes versions but has been deprecated in favor of dynamic provisioning. It performed a basic scrub on the volume before making it available again.

Persistent Volume States

Available

A free resource that is not yet bound to a claim

Bound

The volume is bound to a claim

Released

The claim has been deleted, but the resource is not yet reclaimed by the cluster

Failed

The volume has failed its automatic reclamation

State Transition

Available → Bound → Released → Available/Failed

The exact transition depends on the reclaim policy and storage backend capabilities

kubectl PV & PVC Commands

Deploy PVs and PVCs

kubectl apply -f [definition.yaml]

Create PV and PVC resources from YAML files

Get PV and PVC Lists

kubectl get pv
kubectl get pvc

List all PersistentVolumes and PersistentVolumeClaims

Describe PV and PVC

kubectl describe pv [pvName]
kubectl describe pvc [pvcName]

Get detailed information about PV and PVC

Delete PV and PVC

kubectl delete -f [definition.yaml]
kubectl delete pv [pvName]
kubectl delete pvc [pvcName]

Delete using YAML file or resource names

Complete Static Provisioning Example

Persistent Volume Definition

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-static-1
  labels:
    type: local
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: manual
  hostPath:
    path: "/mnt/data"

Persistent Volume Claim

apiVersion: v1
kind: Persistent VolumeClaim
metadata:
  name: pvc-static
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  selector:
    matchLabels:
      type: local
  storageClassName: manual

Pod Using the PVC

apiVersion: v1
kind: Pod
metadata:
  name: pod-with-pvc
spec:
  containers:
  - name: app-container
    image: nginx
    volumeMounts:
    - name: data-volume
      mountPath: /data
  volumes:
  - name: data-volume
    persistentVolumeClaim:
      claimName: pvc-static

Key Configuration Points

  • PV capacity: 10Gi (total available)
  • PVC request: 1Gi (what the pod needs)
  • Reclaim policy: Retain (data preserved)
  • Selector: PVC finds PV by labels
  • StorageClass: manual (static provisioning)

Deployment Steps

  1. Create the PersistentVolume
  2. Create the PersistentVolumeClaim
  3. Verify PVC binds to PV (kubectl get pv,pvc)
  4. Create the Pod using the PVC
  5. Verify pod can access the volume

Static Provisioning Best Practices

Planning & Configuration

  • Use Retain policy for critical data to prevent accidental deletion
  • Label PVs appropriately for easy PVC matching
  • Plan PV sizes based on actual application requirements
  • Use appropriate access modes for your workload
  • Document PV allocations and usage

Operations & Maintenance

  • Monitor PV states and address Failed volumes promptly
  • Clean up Released volumes according to data retention policies
  • Use descriptive names for PVs and PVCs
  • Consider using Dynamic Provisioning for most use cases
  • Implement backup strategies for critical data

When to Use Static Provisioning

Good For:
  • Small clusters with predictable storage needs
  • Environments without dynamic provisioning support
  • Specific performance requirements
  • Legacy storage systems
Consider Dynamic When:
  • Large, growing clusters
  • Unpredictable storage requirements
  • Cloud environments
  • Multiple teams with varying needs