Alright, let’s talk about what happens when you’re done with your PersistentVolumeClaim. You delete the PVC, and then what? Does the underlying storage just vanish into the ether? Does it hang around like a ghost at a party, cluttering up your cluster and your cloud bill? This is where the persistentVolumeReclaimPolicy comes in. It’s the PV’s instruction manual for what to do after its one true love, the PVC, has been deleted. It’s the “break glass in case of emergency” plan for your data, and you absolutely need to know how it works.

There are three policies: Retain, Recycle, and Delete. I’ll be honest with you, one of these is a bit of a historical relic, but we’ll cover it for completeness and a good laugh.

The Retain Policy: The Safe Bet

This is the policy you use when your data is actually important. When a PVC bound to a Retain policy PV is deleted, the PV enters a Released state. But—and this is the critical part—the data is still there on the underlying storage volume. The PV is just sitting in an orphaned state, like a reserved book at a library no one is coming to pick up.

Why is this safe? Because it prevents you from accidentally nuking your database or that giant set of training models you spent a week generating. The PV is out of the normal PVC/PVC binding cycle, so a new PVC can’t just swoop in and claim it. You, the administrator, have to manually intervene. You’d do something like this:

  1. Delete the PV object (kubectl delete pv my-pv). This only deletes the API object, not the actual storage.
  2. Go into your cloud provider’s console (or your on-prem storage system) and manually back up, delete, or do whatever you need to with the actual disk.
  3. Create a new PV manifest that points to that same storage, or create new storage and a new PV to match.

Here’s what a Retain policy PV looks like. Notice the crucial line:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: my-retained-pv
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain # This is the important bit
  storageClassName: fast
  hostPath:
    path: "/mnt/data"

After deleting the PVC, if you run kubectl get pv, you’ll see its status is Released. The data on the /mnt/data directory is still safe and sound. This is the default policy for manually provisioned PVs (and for good reason). Use this if you value your data more than a bit of manual cleanup.

The Delete Policy: The Automated Cleaner

This is the policy for the cattle, not the pets. It’s common for dynamically provisioned volumes (when you’re using a StorageClass). When you delete the PVC, the PV object is automatically deleted, and critically, the associated storage asset in the underlying infrastructure (e.g., the AWS EBS volume, the GCP PD, the Azure Disk) is also destroyed.

Poof. Gone. No Released state, no manual cleanup. It’s the equivalent of your cluster taking out its own trash.

apiVersion: v1
kind: PersistentVolume
metadata:
  name: my-delete-pv
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Delete # The cluster will do the cleanup
  storageClassName: fast
  csi:
    driver: ebs.csi.aws.com
    volumeHandle: "vol-1234567890" # This EBS volume will be deleted

This is fantastic for non-critical, ephemeral workloads like CI/CD runners, temporary cache, or any other disposable data. It prevents cloud cost death by a thousand forgotten volumes. The huge, obvious caveat is that this is irreversible. You delete the PVC, you lose everything. Forever. Make sure your StorageClass defaults are set correctly for your use case.

The Recycle Policy: The Historical Artefact

Ah, Recycle. This is where we crack the joke. This policy was designed for a simpler time, for volumes like hostPath or NFS, where “deleting” data could be achieved by just running rm -rf /the/volume/* on the PV’s contents. The idea was that the volume could be made available for a new claim without being fully reprovisioned.

Here’s the absurd part: This policy is deprecated and has been removed in recent versions of Kubernetes. It was a security nightmare (imagine giving your cluster root access to run rm -rf on whatever node hosts the volume) and incredibly unreliable. If you see it in an old blog post, nod respectfully and move on. Do not use it. It’s a museum piece. We have StorageClasses and dynamic provisioning to solve this problem correctly now.

Why This All Matters: Pitfalls and Best Practices

The number one pitfall is assuming the default behavior is what you want. If you’re manually creating PVs for a stateful database, and you forget to set persistentVolumeReclaimPolicy: Retain, you’re one stray kubectl delete pvc away from a very, very bad day.

The best practice is simple:

  • For anything you care about: Retain. No exceptions.
  • For dynamically provisioned, ephemeral storage: Let the StorageClass handle it, which usually defaults to Delete. This is perfect for most automated workflows.
  • For Recycle: Use it as a fun trivia fact to impress your friends at parties.

Always, always check the reclaim policy on your PVs (kubectl get pv -o jsonpath='{.items[*].spec.persistentVolumeReclaimPolicy}') before performing any operation you can’t take back. It’s the five seconds of diligence that saves you from the five-day recovery process.