Späť na blog

CSI VolumeAttachment zaseknutý: pody v ContainerCreating a drain, ktorý sa nepohne

Toto je storage incident, ktorý vie zobrať hodiny, lebo symptómy vyzerajú ako “Kubernetes je pomalý”:

  • pody visia v ContainerCreating donekonečna
  • kubectl drain visí, lebo volume sa neodpojí
  • v eventoch vidíš AttachVolume.Attach failed alebo Multi-Attach error
  • appka ani neštartuje, takže app debug je zbytočný

Pri CSI je často “pravda” v VolumeAttachment objekte a jeho finalizeroch — nie v pode.

Testované na: Kubernetes 1.29–1.31, CSI drivery pre cloud block storage aj on-prem, StatefulSety, managed aj self-managed clustre.

Incident (anonymizovaný)

Odišiel nám node (hard failure). StatefulSet pod sa prescheduloval na nový node, ale nikdy nenabehol.

Čo som videl:

  • Pod ostal v ContainerCreating.
  • Eventy sa striedali medzi “waiting for volume attachment” a “multi-attach”.
  • VolumeAttachment objekty sa kopili so starými node referenciami.

Skutočný root cause nebol “disk je pokazený”. CSI controller path bol degradovaný: external-attacher bežal s jednou replikou a počas chaosu sa vyhodil. Finalizery potom ostali zaseknuté a attach/detach sa nevedel zrovnať.

Constraint: toto bol stateful workload. Zlé “force” rozhodnutie môže spôsobiť data corruption. Potreboval som runbook, kde je “safe vs risky” explicitné.

Timeline

  • T-0: node padne; StatefulSet pod sa rescheduluje.
  • T+10m: pod stuck v ContainerCreating; pozriem Pod eventy.
  • T+20m: nájdem PV/PVC a related VolumeAttachmenty.
  • T+30m: VolumeAttachment ukazuje starý node; finalizer nepostupuje.
  • T+45m: mitigácia: opraviť CSI controller path (external-attacher hore) a počkať na clean detach/attach.
  • T+90m: pod nabehne; volume je attached na nový node.
  • T+1d: fix: CSI controllery ako HA + alerty na stuck VolumeAttachment.

Mechanizmus: prečo je VolumeAttachment “pravda” pri CSI incidentoch

Pody nepripájajú volume, robia to controllery

Pri CSI attach/detach koordinujú controllery a stav sa sleduje cez objekty:

  • PVC/PV popisujú čo chceš
  • VolumeAttachment je intent + stav attachu pre konkrétny node
  • external-attacher/external-provisioner + kube-controller-manager hýbu state machine

Finalizery existujú, aby Kubernetes “nezabudol” na attachment predtým, než driver potvrdí detach. Je to správne — ale keď je controller path nezdravý, finalizer je klin.

Najčastejšie failure modes

  1. Multi-Attach
  • veľa block volume podporuje iba jeden attach
  • keď node zomrie a volume je stále “attached”, nový node ho nedostane
  1. CSI controller path degradovaný
  • external-attacher nebeží / je stuck / nemá leadera
  • RBAC alebo cloud API chyby
  • control-plane congestion
  1. Node je NotReady, ale nie je “mŕtvy”
  • detach môže trvať dlho
  • force detach priskoro = dva nody píšu na to isté volume

Runbook: od symptómu v pode po bezpečné zotavenie

Čo skontrolovať ako prvé

1) Pod eventy (často ukážu presné volume)

kubectl -n <ns> describe pod <pod> | sed -n '/Events:/,$p'

Hľadaj:

  • AttachVolume.Attach failed
  • Multi-Attach error
  • timed out waiting for the condition

2) Nájsť PVC a PV

kubectl -n <ns> get pod <pod> -o jsonpath='{.spec.volumes[*].persistentVolumeClaim.claimName}{"\n"}'
kubectl -n <ns> get pvc <pvc> -o wide
kubectl get pv <pv> -o wide

3) Pozrieť VolumeAttachment (cluster-scoped)

kubectl get volumeattachment
kubectl describe volumeattachment <name>

Ak ich je veľa, vyhľadaj PV v YAML:

kubectl get volumeattachment -o yaml | grep -n "<pv>" -n | head

V describe ma zaujíma:

  • target node
  • attached: true/false
  • chyby z CSI drivera
  • finalizery, ktoré sa neodstraňujú

4) Skontrolovať CSI controller komponenty

Názvy závisia od drivera, ale typicky hľadáš:

  • external-attacher
  • external-provisioner
  • controller pody CSI drivera
kubectl -n kube-system get pods | grep -E 'csi|attacher|provisioner' | head -n 50

Ako potvrdiť hypotézu

Máš “VolumeAttachment stuck” incident, ak:

  • Pod je blokovaný na volume attach
  • VolumeAttachment referencuje starý node alebo sedí v error stave
  • CSI controller komponenty sú nezdravé alebo volume je attached inde

Silné potvrdenie je, keď po oprave controller path začnú VolumeAttachmenty postupovať bez force.

Bezpečné mitigácie

1) Najprv sprav CSI controller path zdravý

Ak external-attacher padol alebo je wedged, oprav to:

  • vrátiť repliky
  • opraviť RBAC
  • opraviť cloud API rate limit
  • reštartnúť iba controller komponenty (nie “všetko”)

Toto je bezpečné, lebo necháva state machine spraviť to, na čo je navrhnutá.

2) Pred “force” si dokáž, že starý node je fakt mŕtvy

Pri multi-attach:

  • potvrdiť NotReady a že node sa nevráti
  • potvrdiť, že FS nie je mountnuté nikde inde
  • až potom zvážiť provider-side detach

3) Drain v správnom poradí

Pri draina:

  • najprv cordon
  • podľa potreby zmazať pody, ktoré držia volume
  • počkať na detach pred pokračovaním

Rizikové mitigácie (reálny risk data loss)

  • zmazať VolumeAttachment alebo ručne strhnúť finalizer
    • Kubernetes si môže myslieť, že volume je safe na reattach, aj keď je stále mountnuté
  • force detach v provideri bez dokazania, že node je mŕtvy
    • filesystem split-brain
  • reštartovať všetko
    • viac chaosu, skrytie príčiny

Čo sme zmenili (konkrétne)

1) CSI controllery ako HA

Predtým: 1 replika, bez PDB, ľahko sa evictne pri strese.

Potom: 2 repliky + PDB + priority class (reprezentatívne):

apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: csi-controller
  namespace: kube-system
spec:
  minAvailable: 1
  selector:
    matchLabels:
      app: csi-controller

A deployment tweak (náčrt):

spec:
  replicas: 2
  template:
    spec:
      priorityClassName: system-cluster-critical

2) Alert na stuck VolumeAttachment

Zámer:

  • alert ak VolumeAttachment existuje viac než 15 minút a nepostupuje
  • alert ak je volume attached na NotReady node príliš dlho

Príklad tvaru query (názvy metrík závisia):

time() - kube_volumeattachment_created > 900

3) “Safe detach checklist” do dokumentácie

Checklist:

  • stav nodu
  • mount stav
  • VolumeAttachment target
  • až potom force detach

Ako verifikovať (merateľné)

1) VolumeAttachment sa zrovná

kubectl get volumeattachment
kubectl describe volumeattachment <name>

Očakávam:

  • chyby prestanú
  • attached sedí s realitou
  • finalizery sa odstránia keď majú

2) Pod prejde do Running

kubectl -n <ns> get pod <pod> -w

Očakávam: ContainerCreating → Running bez opakovaných attach eventov.

3) Stateful workload prejde basic integritou

Pri DB spravím minimálny read-only check, ktorý reálne číta dáta. Nechcem “recovery” za cenu korupcie.

Prevencia / guardrails

  • CSI controllery ako control-plane
    • HA, PDB, priority class, observability
  • Time budgety
    • “detach musí skončiť do N minút” ako SLO
  • Alerty
    • stuck VolumeAttachment, opakované attach errors, multi-attach
  • Runbook
    • explicitné “safe vs risky” kroky pre storage incidenty

Súvisiace čítanie

Súvisiace články

Citujte tento článok

Ak na článok odkazujete, pridajte pôvodnú URL a uveďte autora.

Michal Drozd. "CSI VolumeAttachment zaseknutý: pody v ContainerCreating a drain, ktorý sa nepohne". https://www.michal-drozd.com/sk/blog/kubernetes-volumeattachment-zaseknuty-csi/ (Publikované 30. novembra 2025).