CephLXXXVIII · Kubernetes Storage Failure ScenariosKubernetes Storage Failure Scenarios
Stale snapshots and orphaned references
What you'll learn
- Identify divergence between Kubernetes and Ceph state
- Understand how each divergence arises
- Reconcile safely
- Prevent recurrence
Prerequisites
None — start here.
Verified against Ceph Tentacle 20.2.x · Ceph Squid 19.2.x (supported previous) · cephadm matches the verified Ceph release · podman 4.x · csi-rbd and csi-cephfs current · RBD / CephFS / RGW current (matches Ceph release) · Linux kernel 5.15+ (5.10 minimum) · Ubuntu 24.04 LTS (Ceph host baseline) · Debian 12 (Bookworm) (Ceph host baseline) · Rocky Linux / RHEL / AlmaLinux 9.x (Ceph host baseline) · Proxmox VE 9.x (cross-course integration) · Kubernetes 1.31+ (cross-course integration) · 2026-08-18
Why this matters in production
Kubernetes objects and Ceph state are maintained by different systems, and several ordinary operations cause them to diverge.
The kinds of divergence
| Divergence | How it arises |
|---|---|
| VolumeSnapshot with no Ceph snapshot | snapshot deleted in Ceph directly |
| Ceph snapshot with no VolumeSnapshot | VolumeSnapshotContent deleted, Retain policy |
| PV referencing a missing image | image deleted in Ceph directly |
| Image with no PV | Retain policy, or the PV deleted first |
| VolumeSnapshotContent with a missing parent | the source image was deleted |
| Clone whose parent snapshot is gone | not possible; Ceph prevents it |
IMAGE=vm-disk-01
kubectl get volumesnapshot,volumesnapshotcontent --all-namespaces
rbd -p k8s-rbd snap ls ${IMAGE}
Identifying divergence
# VolumeSnapshots whose Ceph snapshot is missing
kubectl get volumesnapshotcontent -o json | python3 -c '
import sys, json, subprocess
for c in json.load(sys.stdin)["items"]:
h = c.get("status", {}).get("snapshotHandle", "")
print(c["metadata"]["name"], "ready:",
c.get("status", {}).get("readyToUse"), h[:60])'
# a VolumeSnapshot that is not ready is the first signal
kubectl get volumesnapshot --all-namespaces -o wide | grep -v true
Reconciling safely
For a VolumeSnapshot whose Ceph snapshot is gone:
the snapshot cannot be restored; the object is useless
delete the VolumeSnapshot and VolumeSnapshotContent
do not attempt to recreate — the point-in-time data is gone
For a Ceph snapshot with no Kubernetes object:
confirm it is not referenced by any clone
delete it in Ceph
# check for dependent clones before deleting a snapshot
IMAGE=vm-disk-01
SNAP=backup-20260818
rbd children k8s-rbd/${IMAGE}@${SNAP}
# safe deletion order
IMAGE=vm-disk-01
SNAP=backup-20260818
rbd snap unprotect k8s-rbd/${IMAGE}@${SNAP}
rbd snap rm k8s-rbd/${IMAGE}@${SNAP}
Checking for children first is essential: a snapshot with clones cannot be removed, and forcing it would break the clones.
Preventing recurrence
| Prevention | Effect |
|---|---|
| Never modify Ceph state for CSI-managed objects directly | the main cause |
deletionPolicy: Delete on VolumeSnapshotClass | Kubernetes cleans up |
| Periodic reconciliation | divergence is found rather than accumulated |
| Alerts on VolumeSnapshots not ready | the signal surfaces |
| Documented ownership of CSI-managed pools | prevents well-meaning manual cleanup |
- alert: VolumeSnapshotNotReady
expr: |
kube_volumesnapshot_status_ready_to_use == 0
for: 1h
labels: { severity: ticket }
# a reconciliation worth scheduling
rbd -p k8s-rbd ls | while read img; do
kubectl get pv -o json | grep -q "$img" || echo "orphan image: $img"
done
Quiz
Knowledge check · 4 questions
Q1. A VolumeSnapshot references a Ceph snapshot that was deleted. What can be done?
Q2. An RBD snapshot with dependent clones can be deleted once the Kubernetes objects are removed.
Q3. Reconcile divergent state.
A cluster has 40 VolumeSnapshots showing readyToUse: false and a Ceph pool with more RBD snapshots than the cluster has VolumeSnapshot objects. Someone previously ran manual cleanup in the pool.
Q4. What must be checked before deleting an RBD snapshot found orphaned in Ceph?
Passing score: 75%. Answers are checked in this browser.
Production discipline
Never delete images or snapshots in a CSI-managed pool directly —
Kubernetes objects reference them by name and a broken reference can only
be deleted, not repaired. Document CSI-managed pools as such, and check
rbd children before removing any snapshot found orphaned.
Cross-course references
- Kubernetes: modifying resources managed by a controller always causes divergence
- Linux: two systems tracking the same objects diverge without a single owner