{"id":89,"date":"2026-08-03T22:21:00","date_gmt":"2026-08-03T19:21:00","guid":{"rendered":"https:\/\/john-nessime.com\/blog\/?p=89"},"modified":"2026-08-02T11:55:49","modified_gmt":"2026-08-02T08:55:49","slug":"kubernetes-persistent-volumes","status":"publish","type":"post","link":"https:\/\/john-nessime.com\/blog\/devops\/kubernetes-persistent-volumes\/","title":{"rendered":"It&#8217;s Only a Claim: Kubernetes Persistent Volumes and Stateful Workloads"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Someone tidies up a namespace that has not been used in a while. A few PVCs go with it. Nobody thinks twice, because a PersistentVolumeClaim sounds like bookkeeping: a claim, a request, a bit of Kubernetes paperwork.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Twenty seconds later the underlying disk no longer exists in AWS. Not detached. Deleted. The reclaim policy on the StorageClass was <code>Delete<\/code>, which is the default on essentially every managed cluster, and deleting the claim cascaded straight through to the volume.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">That is the sharp edge of <strong>Kubernetes persistent volumes<\/strong>, and it is a naming problem as much as a technical one. Three objects sit between your pod and a real disk, the relationships between them are not obvious from the names, and the defaults are tuned for ephemeral test clusters rather than for anything holding data you care about.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This is short and covers the parts that bite: reclaim policies, what access modes actually mean, why volumes pin pods to a zone, and the difference between a StatefulSet and a Deployment that matters in practice.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Three objects, one disk<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The mental model that prevents most of this:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>StorageClass<\/strong> is the recipe. It says which driver provisions volumes and what the defaults are.<\/li>\n<li><strong>PersistentVolume<\/strong> is the actual piece of storage in the cluster. Usually created for you rather than by you.<\/li>\n<li><strong>PersistentVolumeClaim<\/strong> is the request a pod makes, and the thing that binds one-to-one with a PV.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">The PVC is the object your team touches, and it is the one whose name most understates its power. Deleting a PVC can delete a disk. That behaviour comes from the StorageClass, so check what yours says before you need to know:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Read the RECLAIMPOLICY column. On managed clusters it usually\n# says Delete, and nothing anywhere warns you about that.\nkubectl get storageclass<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">For anything holding real data, define your own class with <code>Retain<\/code> and use it deliberately:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>apiVersion: storage.k8s.io\/v1\nkind: StorageClass\nmetadata:\n  name: gp3-retain\nprovisioner: ebs.csi.aws.com\nreclaimPolicy: Retain              # PV outlives the PVC\nvolumeBindingMode: WaitForFirstConsumer\nallowVolumeExpansion: true\nparameters:\n  type: gp3<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The trade-off is real and worth stating: <code>Retain<\/code> means orphaned volumes accumulate and quietly cost money, and a released PV will not automatically rebind to a new claim. You are choosing a cleanup chore over a data loss risk. That is the right trade for a database and the wrong one for a scratch cache.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Existing volumes keep whatever policy they were created with, so changing the class does nothing retroactively. Patch them individually:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl patch pv \"$PV_NAME\" \n  -p '{\"spec\":{\"persistentVolumeReclaimPolicy\":\"Retain\"}}'<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">ReadWriteOnce does not mean one pod<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">It means one <em>node<\/em>. Multiple pods scheduled onto the same node can mount the same ReadWriteOnce volume and write to it simultaneously. The Kubernetes documentation says this explicitly, and almost everyone reads the name and assumes otherwise.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For a database, two writers on one filesystem is corruption. If you need genuine exclusivity, there is an access mode for it, stable since Kubernetes 1.29 and available on CSI volumes:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>spec:\n  accessModes:\n    - ReadWriteOncePod        # enforced by the scheduler<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The same access mode causes a second, more visible problem. Put a ReadWriteOnce volume on a Deployment with the default rolling update strategy and you get a deadlock: the new pod cannot start because the volume is still attached to the old pod&#8217;s node, and the old pod will not terminate until the new one is ready. The rollout sits there until it times out.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>spec:\n  strategy:\n    type: Recreate            # old pod goes first, then the new one<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">That buys you downtime on every deploy, which is the honest cost of a single-writer volume behind a Deployment. If you cannot accept the downtime, you need either shared storage that supports ReadWriteMany or an application that handles its own replication, which is usually a StatefulSet.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Volumes pin pods to a zone<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Block storage from a cloud provider lives in one availability zone. A pod using it can only ever be scheduled onto a node in that zone. Nothing in your Deployment spec says so, and the symptom is a pod stuck in <code>Pending<\/code> after a node replacement or a scale-up that happened to land elsewhere.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>kubectl describe pod<\/code> tells you, in among the scheduler events, that no node matched the volume&#8217;s node affinity. It is easy to miss if you are scanning for something more dramatic.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The preventive setting is <code>volumeBindingMode: WaitForFirstConsumer<\/code>, which is in the StorageClass above. It delays provisioning until a pod is actually scheduled, so the volume gets created in a zone where the pod can run rather than the other way round. Set it on every class you create. The immediate-binding alternative provisions a volume somewhere convenient and then constrains your scheduler forever.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">StatefulSet or Deployment<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The practical difference is not ordering guarantees or DNS names, useful as those are. It is that a StatefulSet gives each replica <em>its own<\/em> volume, created from a template, with a stable name that survives rescheduling. A Deployment with a PVC gives every replica the <em>same<\/em> volume, which is only correct when you have one replica.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">So: one instance with a disk can be a Deployment with <code>Recreate<\/code>. Anything that scales and keeps per-replica state should be a StatefulSet.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">StatefulSet PVCs historically survived everything, including deleting the StatefulSet, which is safe and leaves litter. Since Kubernetes 1.32 you can state the policy explicitly, and both fields still default to <code>Retain<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>spec:\n  persistentVolumeClaimRetentionPolicy:\n    whenDeleted: Retain       # deleting the StatefulSet keeps the data\n    whenScaled: Delete        # scaling down cleans up the extra replicas<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">That pairing is the sensible default for most workloads. Be careful with <code>whenScaled: Delete<\/code> on anything where you scale down temporarily and expect the data back when you scale up again.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Two one-way doors<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Volumes grow, they do not shrink.<\/strong> Expansion is stable and works by editing the claim&#8217;s requested size, provided the StorageClass allows it and the driver supports it. There is no supported path back. Over-provisioning a PVC is a permanent decision until you migrate the data to a smaller one by hand.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>A volume snapshot is not a database backup.<\/strong> Snapshotting a running database&#8217;s disk gives you a crash-consistent image: the equivalent of pulling the power cable. Most engines recover from that, and &#8220;most&#8221; is not a word you want in a recovery plan. Use the database&#8217;s own backup mechanism for the database, and treat volume snapshots as infrastructure convenience rather than your restore path. Whichever you choose, restore one before you need to.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Troubleshooting<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Pod stuck in Pending.<\/strong> Read the events at the bottom of <code>kubectl describe pod<\/code>. Volume node affinity conflict means a zone mismatch. No storage class means the cluster has no default and the claim did not name one.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>PVC stuck in Pending.<\/strong> <code>kubectl describe pvc<\/code> names the provisioner error. With <code>WaitForFirstConsumer<\/code> this is normal until a pod is scheduled, so check whether anything is actually trying to consume it before debugging the driver.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Rollout hangs forever on a stateful app.<\/strong> ReadWriteOnce plus rolling update. Switch to <code>Recreate<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>PVC will not delete.<\/strong> A finalizer is holding it because something still mounts it. Find the consuming pod rather than removing the finalizer by hand, which is how you end up with a PV bound to a claim that no longer exists.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Volume is full but the PVC says it has room.<\/strong> You expanded the PVC and the filesystem did not follow. Most CSI drivers resize the filesystem on the next pod restart; if yours has not, restart the pod and check again.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Common mistakes<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Running production data on the default StorageClass without checking its reclaim policy.<\/li>\n<li>Assuming ReadWriteOnce prevents two pods from writing.<\/li>\n<li>A ReadWriteOnce volume on a Deployment with rolling updates.<\/li>\n<li>Scaling a Deployment with a PVC past one replica.<\/li>\n<li>Leaving <code>volumeBindingMode: Immediate<\/code>, then debugging Pending pods for an hour.<\/li>\n<li>Treating volume snapshots as database backups.<\/li>\n<li>Over-sizing a PVC on the assumption you can shrink it later.<\/li>\n<li>Removing a stuck finalizer instead of finding what is holding the volume.<\/li>\n<li>Deleting a namespace without checking what claims live in it.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Best practices<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Your own StorageClass with <code>Retain<\/code> for anything you would miss, and the default for everything else.<\/li>\n<li><code>WaitForFirstConsumer<\/code> on every class you define.<\/li>\n<li><code>allowVolumeExpansion: true<\/code> from the start, because adding it later does not help existing volumes.<\/li>\n<li>ReadWriteOncePod where exactly one writer is a correctness requirement.<\/li>\n<li>StatefulSets for per-replica state, single-replica Deployments with <code>Recreate<\/code> for everything else.<\/li>\n<li>An explicit <code>persistentVolumeClaimRetentionPolicy<\/code> rather than relying on the default.<\/li>\n<li>Application-level backups for databases, tested by restoring one.<\/li>\n<li>Alerts on volume capacity, because a full disk is the most predictable outage there is.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">FAQ<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Does deleting a PVC delete my data?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">If the reclaim policy is <code>Delete<\/code>, yes, and that is the default nearly everywhere. Run <code>kubectl get storageclass<\/code> and read the RECLAIMPOLICY column before you assume otherwise.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Can two pods share a ReadWriteOnce volume?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Yes, if they are on the same node. ReadWriteOnce restricts access to one node, not one pod. Use ReadWriteOncePod when you need a single writer enforced.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Why is my pod Pending with a bound PVC?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Almost always zone affinity: the volume is in one availability zone and no schedulable node is there. The events in <code>kubectl describe pod<\/code> say so. <code>WaitForFirstConsumer<\/code> prevents it happening again.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Should I run databases in Kubernetes at all?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">You can, with a mature operator that handles failover, backups and upgrades. Whether you should depends on whether your team wants to operate a database platform or just use a database. A managed service is often the better answer and there is no shame in it.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Can I shrink a PersistentVolumeClaim?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">No. Expansion is supported, reduction is not. The only route down is a new smaller volume and a data migration.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">The one thing to remember<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Kubernetes storage defaults assume your cluster is disposable. Reclaim policies delete disks, access modes permit more sharing than their names suggest, and volumes constrain scheduling in ways nothing surfaces until a pod will not start.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Go and run <code>kubectl get storageclass<\/code> on your production cluster now. If the reclaim policy on the class holding your database says <code>Delete<\/code>, you have found something worth fixing before lunch.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Need a hand with stateful workloads?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Storage is where most Kubernetes migrations get uncomfortable, and it is usually the last thing anyone designs. Work I take on:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Auditing a cluster&#8217;s storage classes, reclaim policies and access modes, and telling you what a stray <code>kubectl delete<\/code> would actually destroy.<\/li>\n<li>Moving stateful applications onto StatefulSets with sane retention, expansion and scheduling behaviour.<\/li>\n<li>Backup and restore design for data in Kubernetes, including an actual restore test rather than a documented intention.<\/li>\n<li>Diagnosing Pending pods, stuck rollouts and volumes that will not detach.<\/li>\n<li>CSI driver setup and storage class design on EKS and self-managed clusters.<\/li>\n<li>Capacity alerting so a full volume is a notification instead of an incident.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Send me the output of <code>kubectl get storageclass<\/code> and <code>kubectl get pv<\/code>, and I will tell you what stands out.<\/p>\n\n\n\n<div class=\"wp-block-buttons is-layout-flex wp-block-buttons-is-layout-flex\">\n<div class=\"wp-block-button\"><a class=\"wp-block-button__link wp-element-button\" href=\"https:\/\/www.upwork.com\/freelancers\/~01f15a912ad84a6620\" target=\"_blank\" rel=\"noreferrer noopener\">Work with me on Upwork<\/a><\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>A PersistentVolumeClaim sounds like paperwork. Delete one on a cluster with the default reclaim policy and the underlying disk goes with it. A short guide to the parts of Kubernetes storage that bite: reclaim policies, access modes, zone affinity and StatefulSets.<\/p>\n","protected":false},"author":1,"featured_media":91,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[24,173,52],"tags":[93,19,9,177,3,21,174,175,10,118,176,106,4,12],"class_list":["post-89","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-devops","category-kubernetes","category-technical-guides","tag-aws","tag-cloud","tag-containers","tag-csi","tag-devops","tag-infrastructure","tag-kubernetes","tag-persistent-volumes","tag-production","tag-sre","tag-statefulset","tag-storage","tag-troubleshooting","tag-volumes","entry","has-media"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.2 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Kubernetes Persistent Volumes: What Deletes Your Data<\/title>\n<meta name=\"description\" content=\"Kubernetes persistent volumes explained through what breaks: reclaim policies that delete disks, ReadWriteOnce deadlocks, zone affinity and snapshots.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/john-nessime.com\/blog\/devops\/kubernetes-persistent-volumes\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Kubernetes Persistent Volumes: What Deletes Your Data\" \/>\n<meta property=\"og:description\" content=\"Kubernetes persistent volumes explained through what breaks: reclaim policies that delete disks, ReadWriteOnce deadlocks, zone affinity and snapshots.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/john-nessime.com\/blog\/devops\/kubernetes-persistent-volumes\/\" \/>\n<meta property=\"og:site_name\" content=\"John Nessime\" \/>\n<meta property=\"article:published_time\" content=\"2026-08-03T19:21:00+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/john-nessime.com\/blog\/wp-content\/uploads\/2026\/08\/kubernetes-persistent-volumes.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"627\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"John Nessime\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"John Nessime\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"8 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/devops\\\/kubernetes-persistent-volumes\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/devops\\\/kubernetes-persistent-volumes\\\/\"},\"author\":{\"name\":\"John Nessime\",\"@id\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/#\\\/schema\\\/person\\\/ede0b56d0c808f123f57d5d796902105\"},\"headline\":\"It&#8217;s Only a Claim: Kubernetes Persistent Volumes and Stateful Workloads\",\"datePublished\":\"2026-08-03T19:21:00+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/devops\\\/kubernetes-persistent-volumes\\\/\"},\"wordCount\":1683,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/#\\\/schema\\\/person\\\/ede0b56d0c808f123f57d5d796902105\"},\"image\":{\"@id\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/devops\\\/kubernetes-persistent-volumes\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/08\\\/kubernetes-persistent-volumes.png\",\"keywords\":[\"AWS\",\"Cloud\",\"Containers\",\"CSI\",\"DevOps\",\"Infrastructure\",\"Kubernetes\",\"Persistent Volumes\",\"Production\",\"SRE\",\"StatefulSet\",\"Storage\",\"Troubleshooting\",\"Volumes\"],\"articleSection\":[\"DevOps\",\"Kubernetes\",\"Technical Guides\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/john-nessime.com\\\/blog\\\/devops\\\/kubernetes-persistent-volumes\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/devops\\\/kubernetes-persistent-volumes\\\/\",\"url\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/devops\\\/kubernetes-persistent-volumes\\\/\",\"name\":\"Kubernetes Persistent Volumes: What Deletes Your Data\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/devops\\\/kubernetes-persistent-volumes\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/devops\\\/kubernetes-persistent-volumes\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/08\\\/kubernetes-persistent-volumes.png\",\"datePublished\":\"2026-08-03T19:21:00+00:00\",\"description\":\"Kubernetes persistent volumes explained through what breaks: reclaim policies that delete disks, ReadWriteOnce deadlocks, zone affinity and snapshots.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/devops\\\/kubernetes-persistent-volumes\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/john-nessime.com\\\/blog\\\/devops\\\/kubernetes-persistent-volumes\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/devops\\\/kubernetes-persistent-volumes\\\/#primaryimage\",\"url\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/08\\\/kubernetes-persistent-volumes.png\",\"contentUrl\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/08\\\/kubernetes-persistent-volumes.png\",\"width\":1200,\"height\":627,\"caption\":\"Diagram showing that deleting a PersistentVolumeClaim cascades to the PersistentVolume and the underlying cloud disk when the reclaim policy is Delete, but stops at the released PV when the policy is Retain.\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/devops\\\/kubernetes-persistent-volumes\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"It&#8217;s Only a Claim: Kubernetes Persistent Volumes and Stateful Workloads\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/\",\"name\":\"John Nessime\",\"description\":\"Cloud, DevOps, Data &amp; AI \u2014 Built, Tested, Explained\",\"publisher\":{\"@id\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/#\\\/schema\\\/person\\\/ede0b56d0c808f123f57d5d796902105\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/#\\\/schema\\\/person\\\/ede0b56d0c808f123f57d5d796902105\",\"name\":\"John Nessime\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/cropped-jn.png\",\"url\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/cropped-jn.png\",\"contentUrl\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/cropped-jn.png\",\"width\":512,\"height\":512,\"caption\":\"John Nessime\"},\"logo\":{\"@id\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/cropped-jn.png\"},\"description\":\"AWS Certified Solutions Architect helping businesses build reliable cloud, data, reporting, and automation solutions. I help startups, agencies, and growing businesses replace manual processes and disconnected data with practical AWS architectures, clean data pipelines, useful dashboards, and maintainable automation.\",\"sameAs\":[\"https:\\\/\\\/john-nessime.com\\\/blog\",\"https:\\\/\\\/www.linkedin.com\\\/in\\\/john-m-nessime\"],\"url\":\"https:\\\/\\\/john-nessime.com\\\/blog\\\/author\\\/johnnessime\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Kubernetes Persistent Volumes: What Deletes Your Data","description":"Kubernetes persistent volumes explained through what breaks: reclaim policies that delete disks, ReadWriteOnce deadlocks, zone affinity and snapshots.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/john-nessime.com\/blog\/devops\/kubernetes-persistent-volumes\/","og_locale":"en_US","og_type":"article","og_title":"Kubernetes Persistent Volumes: What Deletes Your Data","og_description":"Kubernetes persistent volumes explained through what breaks: reclaim policies that delete disks, ReadWriteOnce deadlocks, zone affinity and snapshots.","og_url":"https:\/\/john-nessime.com\/blog\/devops\/kubernetes-persistent-volumes\/","og_site_name":"John Nessime","article_published_time":"2026-08-03T19:21:00+00:00","og_image":[{"width":1200,"height":627,"url":"https:\/\/john-nessime.com\/blog\/wp-content\/uploads\/2026\/08\/kubernetes-persistent-volumes.png","type":"image\/png"}],"author":"John Nessime","twitter_card":"summary_large_image","twitter_misc":{"Written by":"John Nessime","Est. reading time":"8 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/john-nessime.com\/blog\/devops\/kubernetes-persistent-volumes\/#article","isPartOf":{"@id":"https:\/\/john-nessime.com\/blog\/devops\/kubernetes-persistent-volumes\/"},"author":{"name":"John Nessime","@id":"https:\/\/john-nessime.com\/blog\/#\/schema\/person\/ede0b56d0c808f123f57d5d796902105"},"headline":"It&#8217;s Only a Claim: Kubernetes Persistent Volumes and Stateful Workloads","datePublished":"2026-08-03T19:21:00+00:00","mainEntityOfPage":{"@id":"https:\/\/john-nessime.com\/blog\/devops\/kubernetes-persistent-volumes\/"},"wordCount":1683,"commentCount":0,"publisher":{"@id":"https:\/\/john-nessime.com\/blog\/#\/schema\/person\/ede0b56d0c808f123f57d5d796902105"},"image":{"@id":"https:\/\/john-nessime.com\/blog\/devops\/kubernetes-persistent-volumes\/#primaryimage"},"thumbnailUrl":"https:\/\/john-nessime.com\/blog\/wp-content\/uploads\/2026\/08\/kubernetes-persistent-volumes.png","keywords":["AWS","Cloud","Containers","CSI","DevOps","Infrastructure","Kubernetes","Persistent Volumes","Production","SRE","StatefulSet","Storage","Troubleshooting","Volumes"],"articleSection":["DevOps","Kubernetes","Technical Guides"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/john-nessime.com\/blog\/devops\/kubernetes-persistent-volumes\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/john-nessime.com\/blog\/devops\/kubernetes-persistent-volumes\/","url":"https:\/\/john-nessime.com\/blog\/devops\/kubernetes-persistent-volumes\/","name":"Kubernetes Persistent Volumes: What Deletes Your Data","isPartOf":{"@id":"https:\/\/john-nessime.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/john-nessime.com\/blog\/devops\/kubernetes-persistent-volumes\/#primaryimage"},"image":{"@id":"https:\/\/john-nessime.com\/blog\/devops\/kubernetes-persistent-volumes\/#primaryimage"},"thumbnailUrl":"https:\/\/john-nessime.com\/blog\/wp-content\/uploads\/2026\/08\/kubernetes-persistent-volumes.png","datePublished":"2026-08-03T19:21:00+00:00","description":"Kubernetes persistent volumes explained through what breaks: reclaim policies that delete disks, ReadWriteOnce deadlocks, zone affinity and snapshots.","breadcrumb":{"@id":"https:\/\/john-nessime.com\/blog\/devops\/kubernetes-persistent-volumes\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/john-nessime.com\/blog\/devops\/kubernetes-persistent-volumes\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/john-nessime.com\/blog\/devops\/kubernetes-persistent-volumes\/#primaryimage","url":"https:\/\/john-nessime.com\/blog\/wp-content\/uploads\/2026\/08\/kubernetes-persistent-volumes.png","contentUrl":"https:\/\/john-nessime.com\/blog\/wp-content\/uploads\/2026\/08\/kubernetes-persistent-volumes.png","width":1200,"height":627,"caption":"Diagram showing that deleting a PersistentVolumeClaim cascades to the PersistentVolume and the underlying cloud disk when the reclaim policy is Delete, but stops at the released PV when the policy is Retain."},{"@type":"BreadcrumbList","@id":"https:\/\/john-nessime.com\/blog\/devops\/kubernetes-persistent-volumes\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/john-nessime.com\/blog\/"},{"@type":"ListItem","position":2,"name":"It&#8217;s Only a Claim: Kubernetes Persistent Volumes and Stateful Workloads"}]},{"@type":"WebSite","@id":"https:\/\/john-nessime.com\/blog\/#website","url":"https:\/\/john-nessime.com\/blog\/","name":"John Nessime","description":"Cloud, DevOps, Data &amp; AI \u2014 Built, Tested, Explained","publisher":{"@id":"https:\/\/john-nessime.com\/blog\/#\/schema\/person\/ede0b56d0c808f123f57d5d796902105"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/john-nessime.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/john-nessime.com\/blog\/#\/schema\/person\/ede0b56d0c808f123f57d5d796902105","name":"John Nessime","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/john-nessime.com\/blog\/wp-content\/uploads\/2026\/07\/cropped-jn.png","url":"https:\/\/john-nessime.com\/blog\/wp-content\/uploads\/2026\/07\/cropped-jn.png","contentUrl":"https:\/\/john-nessime.com\/blog\/wp-content\/uploads\/2026\/07\/cropped-jn.png","width":512,"height":512,"caption":"John Nessime"},"logo":{"@id":"https:\/\/john-nessime.com\/blog\/wp-content\/uploads\/2026\/07\/cropped-jn.png"},"description":"AWS Certified Solutions Architect helping businesses build reliable cloud, data, reporting, and automation solutions. I help startups, agencies, and growing businesses replace manual processes and disconnected data with practical AWS architectures, clean data pipelines, useful dashboards, and maintainable automation.","sameAs":["https:\/\/john-nessime.com\/blog","https:\/\/www.linkedin.com\/in\/john-m-nessime"],"url":"https:\/\/john-nessime.com\/blog\/author\/johnnessime\/"}]}},"_links":{"self":[{"href":"https:\/\/john-nessime.com\/blog\/wp-json\/wp\/v2\/posts\/89","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/john-nessime.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/john-nessime.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/john-nessime.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/john-nessime.com\/blog\/wp-json\/wp\/v2\/comments?post=89"}],"version-history":[{"count":1,"href":"https:\/\/john-nessime.com\/blog\/wp-json\/wp\/v2\/posts\/89\/revisions"}],"predecessor-version":[{"id":110,"href":"https:\/\/john-nessime.com\/blog\/wp-json\/wp\/v2\/posts\/89\/revisions\/110"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/john-nessime.com\/blog\/wp-json\/wp\/v2\/media\/91"}],"wp:attachment":[{"href":"https:\/\/john-nessime.com\/blog\/wp-json\/wp\/v2\/media?parent=89"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/john-nessime.com\/blog\/wp-json\/wp\/v2\/categories?post=89"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/john-nessime.com\/blog\/wp-json\/wp\/v2\/tags?post=89"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}