- Authors

- Name
- Phillip Pham
- @ddppham
Kubernetes PVC Pending: Storage-Probleme systematisch loesen
TL;DR
- PVC Pending bedeutet: Kubernetes findet kein passendes PersistentVolume -- alle Pods, die das Volume nutzen, bleiben ebenfalls Pending.
- Erster Befehl:
kubectl describe pvc <name>-- die Events zeigen die genaue Ursache. - Haeufigste Ursachen: keine Default StorageClass, Zone/Topology Mismatch, Kapazitaet erschoepft, CSI Driver fehlt.
- WaitForFirstConsumer ist kein Fehler -- die PVC bleibt absichtlich Pending, bis ein Pod sie referenziert.
- Dynamische Provisionierung loest die meisten Probleme. Statische PVs brauchen exakte Uebereinstimmung bei Capacity, Access Mode und StorageClass.
Was PVC Pending bedeutet
Wenn kubectl get pvc diesen Status zeigt, wartet Kubernetes auf ein Volume:
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
app-data Pending standard 5m
Kubernetes sucht entweder ein vorhandenes PersistentVolume (statisch) oder erstellt eins ueber den CSI Driver (dynamisch). Wenn beides fehlschlaegt, bleibt die PVC auf Pending.
Der Diagnose-Workflow
Schritt 1: PVC Events pruefen
# PVC-Details mit Events
kubectl describe pvc app-data -n production
# Nur PVC-Events
kubectl get events --field-selector involvedObject.kind=PersistentVolumeClaim -n production
Schritt 2: StorageClass und PVs pruefen
# Verfuegbare StorageClasses
kubectl get storageclass
# Default StorageClass identifizieren
kubectl get storageclass -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.metadata.annotations.storageclass\.kubernetes\.io/is-default-class}{"\n"}{end}'
# Vorhandene PVs
kubectl get pv -o wide
Die 7 haeufigsten Ursachen
1. Keine Default StorageClass
Wenn eine PVC keine storageClassName angibt und keine Default StorageClass existiert, bleibt sie auf Pending.
# Event: "no persistent volumes available for this claim and no storage class is set"
kubectl get storageclass
Loesung:
kubectl patch storageclass standard \
-p '{"metadata": {"annotations": {"storageclass.kubernetes.io/is-default-class": "true"}}}'
Oder eine neue StorageClass erstellen:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: standard
annotations:
storageclass.kubernetes.io/is-default-class: "true"
provisioner: ebs.csi.aws.com
parameters:
type: gp3
encrypted: "true"
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
2. StorageClass existiert nicht
Die PVC referenziert eine StorageClass, die nicht im Cluster vorhanden ist.
# StorageClass aus PVC auslesen
kubectl get pvc app-data -n production -o jsonpath='{.spec.storageClassName}'
Loesung -- StorageClass fuer gaengige Cloud-Provider:
# AWS EBS (gp3)
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast-ssd
provisioner: ebs.csi.aws.com
parameters:
type: gp3
iops: "3000"
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
---
# Azure Managed Disk
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: azure-premium
provisioner: disk.csi.azure.com
parameters:
skuName: Premium_LRS
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
3. Zone / Topology Mismatch
Cloud-Volumes koennen nur in der Zone gemounted werden, in der sie erstellt wurden. Wenn das Volume in einer anderen Zone liegt als der Node, schlaegt das Mounting fehl.
# Zone des PVs
kubectl get pv <pv-name> -o jsonpath='{.spec.nodeAffinity}'
# Zonen der Nodes
kubectl get nodes --label-columns topology.kubernetes.io/zone
Loesung: WaitForFirstConsumer verwenden -- das Volume wird erst in der Zone des zugewiesenen Nodes erstellt:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: zone-aware
provisioner: ebs.csi.aws.com
parameters:
type: gp3
volumeBindingMode: WaitForFirstConsumer # Entscheidend fuer Multi-Zone
4. Kapazitaet erschoepft
Der Cloud-Provider hat keine Kapazitaet mehr fuer neue Volumes.
# Event: "ProvisioningFailed: rpc error: code = ResourceExhausted"
kubectl describe pvc app-data -n production | grep -A5 "Events"
Loesung:
# Nicht genutzte PVs finden
kubectl get pv --no-headers | awk '$5 == "Released" || $5 == "Available"'
# Released PV freigeben (Achtung: Datenverlust!)
kubectl patch pv <pv-name> -p '{"spec":{"claimRef": null}}'
5. WaitForFirstConsumer (kein Fehler)
Mit WaitForFirstConsumer bleibt die PVC absichtlich Pending, bis ein Pod sie referenziert.
# Event: "waiting for first consumer to be created before binding"
kubectl get storageclass <name> -o jsonpath='{.volumeBindingMode}'
Das ist erwartetes Verhalten. Die PVC wird automatisch gebunden, sobald ein Pod erstellt wird. Falls sofortige Bindung noetig ist:
volumeBindingMode: Immediate # Achtung: kann Zone-Mismatches verursachen
6. CSI Driver nicht installiert
Der Provisioner aus der StorageClass ist nicht im Cluster vorhanden.
# Event: "no volume plugin matched name: ebs.csi.aws.com"
kubectl get csidrivers
kubectl get pods -n kube-system -l app=ebs-csi-controller
Loesung (Beispiel AWS EBS):
helm repo add aws-ebs-csi-driver https://kubernetes-sigs.github.io/aws-ebs-csi-driver
helm repo update
helm install aws-ebs-csi-driver aws-ebs-csi-driver/aws-ebs-csi-driver \
--namespace kube-system \
--set controller.replicaCount=2
# Pruefen
kubectl get csidrivers
7. Access Mode passt nicht
Bei statischer Provisionierung muessen PVC und PV denselben Access Mode haben.
kubectl get pvc app-data -n production -o jsonpath='{.spec.accessModes}'
kubectl get pv -o custom-columns=NAME:.metadata.name,ACCESS:.spec.accessModes,STATUS:.status.phase
Access Modes im Ueberblick:
| Access Mode | Kurzform | Bedeutung |
|---|---|---|
| ReadWriteOnce | RWO | Ein Node kann lesen/schreiben |
| ReadOnlyMany | ROX | Viele Nodes koennen lesen |
| ReadWriteMany | RWX | Viele Nodes koennen lesen/schreiben |
| ReadWriteOncePod | RWOP | Genau ein Pod (ab K8s 1.27) |
Loesung -- PVC und PV muessen uebereinstimmen:
apiVersion: v1
kind: PersistentVolume
metadata:
name: app-data-pv
spec:
capacity:
storage: 50Gi
accessModes:
- ReadWriteOnce
storageClassName: manual
hostPath:
path: /mnt/data
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: app-data
namespace: production
spec:
accessModes:
- ReadWriteOnce # Muss mit PV uebereinstimmen
resources:
requests:
storage: 50Gi # Darf nicht groesser als PV sein
storageClassName: manual # Muss mit PV uebereinstimmen
Dynamische vs. Statische Provisionierung
Dynamisch (empfohlen)
Kubernetes erstellt automatisch ein PV ueber die StorageClass:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: app-data
namespace: production
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
storageClassName: standard
Statisch (NFS, existierende Volumes)
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfs-share
spec:
capacity:
storage: 100Gi
accessModes:
- ReadWriteMany
storageClassName: nfs
nfs:
server: 10.0.0.50
path: /exports/data
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: shared-data
namespace: production
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 100Gi
storageClassName: nfs
Volume nachtraeglich vergroessern
# Expansion moeglich?
kubectl get storageclass standard -o jsonpath='{.allowVolumeExpansion}'
# PVC vergroessern
kubectl patch pvc app-data -n production \
-p '{"spec": {"resources": {"requests": {"storage": "50Gi"}}}}'
# Status pruefen
kubectl describe pvc app-data -n production | grep -A5 "Conditions"
Zusammenfassung: Diagnose-Tabelle
| Ursache | Event-Meldung | Loesung |
|---|---|---|
| Keine Default StorageClass | no storage class is set | Default StorageClass erstellen |
| StorageClass fehlt | storageclass not found | StorageClass erstellen |
| Zone Mismatch | volume node affinity conflict | WaitForFirstConsumer verwenden |
| Kapazitaet erschoepft | ResourceExhausted | Quotas pruefen, alte PVs bereinigen |
| WaitForFirstConsumer | waiting for first consumer | Kein Fehler -- Pod erstellen |
| CSI Driver fehlt | no volume plugin matched | CSI Driver installieren |
| Access Mode Mismatch | (kein PV matcht) | Access Modes angleichen |
Der wichtigste Tipp bei kubernetes pvc pending: Immer kubectl describe pvc ausfuehren. Die Events-Sektion verraet fast immer die Ursache.
Verwandte Artikel
- Kubernetes Pod Pending Troubleshooting
- Kubernetes CrashLoopBackOff Troubleshooting
- Kubernetes Backup und Disaster Recovery
- Kubernetes Security Hardening Checkliste
- Helm Charts Einfuehrung und Tutorial
Wenn Sie Hilfe bei der Konfiguration Ihrer Kubernetes-Storage-Infrastruktur brauchen oder wiederkehrende PVC-Probleme loesen moechten, helfen wir gerne -- Kontakt aufnehmen.
Kubernetes-Beratung gesucht?
Wir helfen deutschen Unternehmen bei der Kubernetes-Implementierung, Migration und Optimierung. DSGVO-konform und praxiserprobt.
📖 Verwandte Artikel
Weitere interessante Beiträge zu ähnlichen Themen
Kubernetes PVC Pending lösen: StorageClass und Provisioner debuggen
PersistentVolumeClaim bleibt auf Pending? Die häufigsten Ursachen sind eine fehlende StorageClass, ein defekter Provisioner oder erreichte Quotas. So lösen Sie es.
CoreDNS Debugging: Kubernetes-DNS Probleme lösen
DNS-Probleme in Kubernetes systematisch debuggen: CoreDNS-Logs, ndots-Konfiguration, NXDOMAIN-Fehler und Corefile-Optimierung für schnellere Auflösung.
Ephemeral Containers: Live-Debugging in Kubernetes
Ephemeral Containers fuer Live-Debugging in Kubernetes nutzen. Mit kubectl debug laufende Pods analysieren, Distroless-Images debuggen und Netzwerkprobleme loesen.
Kubernetes Incident Management: Runbooks erstellen
Effektive Runbooks für Kubernetes-Incidents erstellen: Vorlagen für CrashLoopBackOff, OOMKilled und Node-Ausfälle mit konkreten Debugging-Befehlen.
Kubernetes Storage: CSI-Treiber und PV richtig nutzen
Persistent Volumes, StorageClasses und CSI-Treiber in Kubernetes konfigurieren: Von dynamischem Provisioning bis Volume Expansion mit Praxisbeispielen.