πŸ“šBook Signing at KubeCon EU 2026Meet us at Booking.com HQ (Mon 18:30-21:00) & vCluster booth #521 (Tue 24 Mar, 12:30-1:30pm) β€” free book giveaway!RSVP Booking.com Event
Storage intermediate ⏱ 15 minutes K8s 1.28+

Persistent Volume NFS iSCSI Guide

Master Kubernetes PersistentVolumes: static and dynamic provisioning, reclaim policies, volume modes, and lifecycle. From PV creation to pod mounting and data

By Luca Berton β€’ β€’ πŸ“– 5 min read

πŸ’‘ Quick Answer: storage

The Problem

This is one of the most searched Kubernetes topics with thousands of monthly searches. A comprehensive, production-ready guide prevents hours of trial and error.

The Solution

PV Lifecycle

Provisioning β†’ Binding β†’ Using β†’ Reclaiming

1. PV available (static or dynamic via StorageClass)
2. PVC created β†’ PV bound to PVC
3. Pod mounts PVC β†’ reads/writes data
4. PVC deleted β†’ PV enters Released state
5. Reclaim policy determines next step

Static PV

apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs-vol-01
  labels:
    type: nfs
    environment: production
spec:
  capacity:
    storage: 100Gi
  volumeMode: Filesystem    # or Block
  accessModes:
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain
  storageClassName: ""       # Empty for static
  mountOptions:
    - nfsvers=4.1
    - hard
  nfs:
    server: nfs.example.com
    path: /exports/data01

PV Binding with Label Selector

# PVC with selector β€” bind to specific PV
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: prod-data
spec:
  accessModes: [ReadWriteMany]
  storageClassName: ""
  resources:
    requests:
      storage: 100Gi
  selector:
    matchLabels:
      type: nfs
      environment: production

Volume Modes

# Filesystem (default) β€” mounted as directory
volumeMode: Filesystem

# Block β€” raw block device (databases that manage their own filesystem)
volumeMode: Block
# Pod spec for block:
# volumeDevices:
#   - name: data
#     devicePath: /dev/xvda

PV Status Transitions

StatusMeaning
AvailablePV is free, not bound to PVC
BoundPV bound to a PVC
ReleasedPVC deleted, PV retains data but not yet available
FailedAutomatic reclaim failed
# Manually reclaim a Released PV
kubectl patch pv nfs-vol-01 -p '{"spec":{"claimRef": null}}'
# Now PV is Available again (data still there!)
graph LR
    A[PV: Available] -->|PVC created| B[PV: Bound]
    B -->|Pod mounts| C[In use]
    C -->|PVC deleted| D{Reclaim policy?}
    D -->|Retain| E[PV: Released - data kept]
    D -->|Delete| F[PV + data deleted]
    E -->|Manual reclaim| A

Frequently Asked Questions

StorageClass "" vs not setting it?

storageClassName: "" means β€œdon’t use dynamic provisioning, bind to a static PV”. Omitting it entirely uses the default StorageClass. They are NOT the same.

Can I change a PV’s reclaim policy?

Yes: kubectl patch pv my-pv -p '{"spec":{"persistentVolumeReclaimPolicy":"Retain"}}'. Always set to Retain for production data before deleting PVCs.

Best Practices

  • Start with the simplest configuration that solves your problem
  • Test in staging before production
  • Use kubectl describe and events for troubleshooting
  • Document team conventions for consistency

Key Takeaways

  • This is fundamental Kubernetes operational knowledge
  • Follow established conventions and recommended labels
  • Monitor and iterate based on real production behavior
  • Automate repetitive tasks to reduce human error
#persistent-volume #pv #storage #provisioning #kubernetes
Luca Berton
Written by Luca Berton

Principal Solutions Architect specializing in Kubernetes, AI/GPU infrastructure, and cloud-native platforms. Author of Kubernetes Recipes and creator of CopyPasteLearn courses.

Kubernetes Recipes book cover

Want More Kubernetes Recipes?

This recipe is from Kubernetes Recipes, our 750-page practical guide with hundreds of production-ready patterns.

Luca Berton Ansible Pilot Ansible by Example Open Empower K8s Recipes Terraform Pilot CopyPasteLearn ProteinLens