Skip to main content
RunBook Academy

CephLXXXVIII · Kubernetes Storage Failure ScenariosKubernetes Storage Failure Scenarios

Stale snapshots and orphaned references

Advanced⏱ ~17 minkubectlcephrbd

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

Not yet marked complete on this device.

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

DivergenceHow it arises
VolumeSnapshot with no Ceph snapshotsnapshot deleted in Ceph directly
Ceph snapshot with no VolumeSnapshotVolumeSnapshotContent deleted, Retain policy
PV referencing a missing imageimage deleted in Ceph directly
Image with no PVRetain policy, or the PV deleted first
VolumeSnapshotContent with a missing parentthe source image was deleted
Clone whose parent snapshot is gonenot 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

PreventionEffect
Never modify Ceph state for CSI-managed objects directlythe main cause
deletionPolicy: Delete on VolumeSnapshotClassKubernetes cleans up
Periodic reconciliationdivergence is found rather than accumulated
Alerts on VolumeSnapshots not readythe signal surfaces
Documented ownership of CSI-managed poolsprevents 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

  1. Q1. A VolumeSnapshot references a Ceph snapshot that was deleted. What can be done?

  2. Q2. An RBD snapshot with dependent clones can be deleted once the Kubernetes objects are removed.

  3. 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.

  4. 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