Persistenter Speicher: Volumes, PersistentVolumes und Claims
Halte Daten über Pod-Neustarts hinweg am Leben mit PVCs und verstehe, wie StorageClasses die Teile verbinden.
Das Dateisystem eines Containers hält nur so lange wie der Container. Wird ein Pod ersetzt, ist alles, was er geschrieben hat, weg. Für zustandslose Webserver ist das in Ordnung, für Datenbanken, Uploads und alles andere, was überleben muss, ein Problem. Diese Anleitung zeigt, wie Kubernetes dauerhaften Speicher an Pods anbindet.
Warum Container-Speicher nicht ausreicht
Container sollen klein und wegwerfbar sein, Daten in ihnen abzulegen untergräbt also das Modell. Daten müssen außerhalb des Containers und außerhalb des Pods liegen, auf Speicher, den Kubernetes beim Start eines Pods anbindet. Kubernetes ist agnostisch darüber, was dieser Speicher ist: eine Cloud-Disk, eine Netzwerkfreigabe oder ein lokales Laufwerk. Es sichert die Daten auch nicht für dich. Das bleibt deine Aufgabe.
Die Speicherkette
Vier Objekte arbeiten zusammen:
- Eine StorageClass beschreibt eine Art von Speicher und wie man ihn bei Bedarf erstellt (zum Beispiel „schnelle SSD-Volumes vom Cloud-Anbieter“).
- Ein PersistentVolume (PV) ist ein tatsächliches Stück Speicher im Cluster.
- Ein PersistentVolumeClaim (PVC) ist eine Anforderung von Speicher durch einen Benutzer oder eine Anwendung: „Ich brauche 1 GiB, das ein Knoten lesen und beschreiben kann.“
- Der Pod referenziert den Claim als Volume und mountet ihn in einen Container.
Container ─ mountPath ─▶ Pod-Volume ─▶ PVC ─ bindet an ─▶ PV ─▶ echter Speicher
▲
StorageClass erstellt PVs bei Bedarf
Ein PVC bindet an genau ein PV. Der Pod verweist nie auf das PV, nur auf den Claim, was Anwendungen von den Speicherdetails unabhängig hält.
Speicher mit einem PVC anfordern
Die meisten Cluster haben eine Standard-StorageClass, die Volumes bei Bedarf erstellt (dynamische Bereitstellung genannt), und minikube bringt eine mit. Prüfe deine:
kubectl get storageclass
Fordere dann Speicher an:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: data
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
kubectl apply -f pvc.yaml
kubectl get pvc,pv
Der Claim sollte Bound werden, und ein passendes PV erscheint. Manche Storage-Klassen warten, bis ein Pod den Claim tatsächlich nutzt, bevor sie das Volume erstellen, Pending ist an dieser Stelle also nicht zwingend ein Fehler.
In einem Pod mounten und die Persistenz beweisen
apiVersion: v1
kind: Pod
metadata:
name: storage-demo
spec:
containers:
- name: app
image: busybox:1.36
command: ["sh", "-c", "sleep 3600"]
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
persistentVolumeClaim:
claimName: data
Schreibe eine Datei, zerstöre den Pod, erstelle ihn neu und prüfe, ob die Datei überlebt hat:
kubectl apply -f pod.yaml
kubectl exec storage-demo -- sh -c 'echo persisted > /data/proof.txt'
kubectl delete pod storage-demo
kubectl apply -f pod.yaml
kubectl exec storage-demo -- cat /data/proof.txt
Der neue Pod ist ein völlig anderer Container, aber der Claim und die Daten dahinter wurden wieder angebunden.
Zugriffsmodi, Reclaim-Policy und statische Volumes
- Zugriffsmodi sagen, wie ein Volume gemountet werden kann.
ReadWriteOncebedeutet Lesen und Schreiben durch einen einzelnen Knoten, sodass mehrere Pods auf diesem Knoten es trotzdem teilen können.ReadOnlyManyundReadWriteManyerlauben viele Knoten, wenn der Speicher das unterstützt.ReadWriteOncePodbeschränkt es auf einen einzelnen Pod. - Reclaim-Policy entscheidet, was mit dem Volume passiert, wenn der Claim gelöscht wird. Dynamisch bereitgestellte Volumes haben meist standardmäßig
Delete, was den zugrunde liegenden Speicher und seine Daten entfernt. NutzeRetain, wenn du die Daten behalten willst. - Statische Bereitstellung bedeutet, dass ein Administrator PVs von Hand erstellt und Claims an das jeweils passende binden. Ein
hostPath-PV, das ein Verzeichnis auf einem Knoten nutzt, ist eine gängige Demo, bindet Daten aber an eine Maschine und eignet sich nur für Einzelknoten-Entwicklung.
Datenbanken und StatefulSets
Du kannst einen Claim in die Pods eines Deployments mounten, aber Replikas eines Deployments sind austauschbar und identisch, und die meisten Datenbanken funktionieren so nicht. Ein StatefulSet ist für zustandsbehaftete Workloads gebaut. Es gibt jedem Pod eine stabile Identität (db-0, db-1), startet und aktualisiert sie in Reihenfolge und kann für jedes Replikat einen eigenen PVC erstellen:
spec:
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 5Gi
Ein StatefulSet behandelt Identität und Speicher, nicht Datenreplikation. Replikas untereinander konsistent zu halten, ist Aufgabe der Datenbank, weshalb der Betrieb von Datenbanken auf Kubernetes schwieriger ist als der von zustandslosen Services. Viele Teams nutzen eine verwaltete Datenbank oder einen Datenbank-Operator und halten die zustandslosen Anwendungen im Cluster.
Beliebte Anleitungen
-
Was Kubernetes ist und welche Probleme es löst Warum Container allein nicht mehr skalieren und wie Kubernetes eine Gruppe von Maschinen zu einer Plattform macht. -
Wie ein Kubernetes-Cluster funktioniert: Control Plane und Knoten Die Komponenten, die einen Cluster am Laufen halten, und was zwischen kubectl apply und einem laufenden Container passiert. -
Deployments: Skalieren, Selbstheilung und Rolling Updates Betreibe Replikas eines Pods, aktualisiere sie ohne Ausfallzeit und rolle zurück, wenn ein Release schiefgeht. -
Services: Stabiles Networking für kurzlebige Pods Gib Pods eine stabile Adresse, stelle sie innerhalb und außerhalb des Clusters bereit und beschränke, wer mit wem sprechen darf. -
Einen fehlschlagenden Pod debuggen: describe, logs, exec und port-forward Eine wiederholbare Checkliste, um herauszufinden, warum ein Pod Pending ist, abstürzt oder nicht antwortet.