TL;DR: A finalizer is holding it, and the finalizer exists for a reason:
kubernetes.io/pvc-protectionblocks deletion while a pod still uses the claim. Find and remove the consumer rather than the finalizer. Removing the finalizer bypasses API-object protection; it does not itself safely detach or fence a writer. Subsequent cleanup or reuse can lose data.
How to approach it
Name the mechanism, then explicitly refuse the shortcut before explaining when it is acceptable. Interviewers ask this because the internet's answer is "patch the finalizer to null" and that answer is dangerous.
A strong answer
Deletion in Kubernetes is two-phase. Setting a deletion timestamp marks the object for removal, but the API server will not actually delete it while its metadata.finalizers list is non-empty. Each finalizer belongs to a controller that must do cleanup and then remove its own entry. An object stuck Terminating means some controller has not finished or is not running.
For a PVC the finalizer is normally kubernetes.io/pvc-protection, and its job is to stop the claim disappearing while a pod is still mounting it. So the first question is not how to remove it, it is what is still using it:
kubectl get pvc data-postgres-0 -o jsonpath='{.metadata.finalizers}'
kubectl describe pvc data-postgres-0 | grep -i "used by"
kubectl get pods -o json | jq -r '.items[] | select(.spec.volumes[]?.persistentVolumeClaim.claimName=="data-postgres-0") | .metadata.name'
Usually you find a pod that is itself stuck Terminating, often because its node is unreachable. Now the real problem is the node, not the PVC, and the correct action is to confirm the node is genuinely dead before removing anything. If the node is merely partitioned and the pod is still writing, detaching the volume and mounting it elsewhere gives you two writers on one filesystem.
The other finalizer you will meet is on the PersistentVolume, external-provisioner.volume.kubernetes.io/finalizer, held by the CSI driver until the volume is detached and deleted in the storage backend. If the CSI controller pod is down, nothing progresses. Check that the driver is running before concluding the object is stuck.
So the safe order: confirm no pod is using it, confirm the node holding any consumer is dead rather than partitioned, confirm the CSI driver is healthy, and only then, if a controller is permanently absent, remove only the specific stale entry after reviewing its owner and taking a backup of the object. Use kubectl edit pvc data-postgres-0; preserve all other finalizers. Do not replace the entire list with null.
And know what you have done: you have told the API server to forget the object while the volume may still exist in the storage backend, which is how orphaned disks accumulate and quietly cost money.
What interviewers probe next
"Why do PVCs outlive their StatefulSet?" Deliberate. The default StatefulSet PVC retention policy is Retain, but persistentVolumeClaimRetentionPolicy can request deletion on StatefulSet deletion or scale-down. Check that policy as well as the PV reclaim policy. Volume lifecycle.
"What is the reclaim policy?" Delete removes the backing volume when the PV is released; Retain keeps it for manual recovery. Retain is the right default for anything you would miss.
"How do you find orphaned volumes afterwards?" Reconcile the storage backend against PVs in the cluster. Use provider inventory and an automated reconciliation report; do not delete an unmatched disk until ownership and recovery needs are established.
Common mistakes
Patching the finalizer out as step one. It bypasses cleanup guarantees and may orphan storage or enable unsafe reuse.
Not checking whether the consuming pod's node is actually dead, which is the difference between a cleanup and a split brain.
Assuming deleting the PVC deletes the disk. It depends entirely on the reclaim policy.