Skip to main content
RunBook Academy

CephLXXXV · Kubernetes IntegrationKubernetes Integration

PersistentVolumeClaims and their lifecycle

Advanced⏱ ~18 minkubectlrbdceph

What you'll learn

  • Trace the PVC lifecycle through to the RBD image
  • Identify where orphaning occurs
  • Expand and delete volumes safely
  • Reconcile Kubernetes state against Ceph

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

The PVC, the PV, and the RBD image are three objects with independent lifetimes, and they can diverge.

The lifecycle

flowchart TD
  A[PVC created] --> B[Provisioner creates RBD image]
  B --> C[PV created, bound to PVC]
  C --> D[Pod scheduled; image mapped and mounted]
  D --> E[Pod deleted; unmounted and unmapped]
  E --> F{PVC deleted?}
  F -->|no| D
  F -->|yes| G{reclaimPolicy}
  G -->|Delete| H[PV removed, RBD image deleted]
  G -->|Retain| I[PV Released; image remains]
kubectl get pvc,pv
rbd -p k8s-rbd ls

Where orphaning occurs

SituationResult
Retain policy, PVC deletedPV Released, image remains, nobody owns it
PV deleted manuallyimage remains with no Kubernetes object
Namespace force-deletedPVCs may be removed without cleanup running
Provisioner down during deletionimage remains, PV stuck Terminating
Ceph image deleted manuallyPV references a nonexistent image
# reconcile: images in Ceph without a PV
rbd -p k8s-rbd ls | while read img; do
  kubectl get pv -o json | grep -q "$img" || echo "orphan: $img"
done

Running this periodically is what prevents orphaned images accumulating indefinitely, and on a busy cluster they do.

Expansion

# Substitute your own PVC name before running:
PVC=pgdata-postgres-0

kubectl patch pvc "$PVC" -p '{"spec":{"resources":{"requests":{"storage":"20Gi"}}}}'
kubectl get pvc "$PVC" -o jsonpath='{.status.capacity.storage}'
Expansion sequence:
  the resizer expands the RBD image
  the node plugin expands the filesystem on next mount, or online if supported
  the PVC status updates
ConditionBehaviour
allowVolumeExpansion: falserejected
Online expansion supportedfilesystem grows while mounted
Not supportedrequires the pod to restart
Shrinkingnot supported at all

Deletion

NAME=acme
IMAGE=vm-disk-01
kubectl delete pvc ${NAME}
kubectl get pv | grep ${NAME}
rbd -p k8s-rbd ls | grep ${IMAGE}

With Retain, the cleanup is manual:

NAME=acme
IMAGE=vm-disk-01
kubectl delete pv ${NAME}
rbd -p k8s-rbd rm ${IMAGE}

Both steps, in that order. Deleting the image first leaves a PV referencing nothing.

Reconciling state

# PVs whose images are gone
kubectl get pv -o json | python3 -c '
import sys, json, subprocess
pvs = json.load(sys.stdin)["items"]
imgs = set(subprocess.check_output(["rbd","-p","k8s-rbd","ls"]).decode().split())
for pv in pvs:
    csi = pv.get("spec", {}).get("csi", {})
    h = csi.get("volumeAttributes", {}).get("imageName")
    if h and h not in imgs:
        print("PV", pv["metadata"]["name"], "references missing image", h)'

Quiz

Knowledge check · 4 questions

  1. Q1. Why should an RBD image be deleted before its PV rather than after?

  2. Q2. A Retained PV whose PVC has been deleted keeps consuming cluster capacity with nothing reporting it.

  3. Q3. Reconcile Kubernetes and Ceph storage state.

    A cluster has used Ceph-CSI for two years with Retain policies on several StorageClasses. The Ceph pool holds far more images than the cluster has PVs.

  4. Q4. What are the three objects in a PVC lifecycle and how can they diverge?

Passing score: 75%. Answers are checked in this browser.

Production discipline

Script a periodic reconciliation between Ceph images and PV objects — Retained volumes accumulate silently and nothing else reports them. When cleaning up manually, delete the image before the PV; the PV is the only record of which image belongs to what.

Cross-course references

  • Kubernetes: orphaned resources across controller boundaries need the same reconciliation
  • Linux: any two systems tracking the same objects will diverge without reconciliation