Nichtflüchtige Volumes und Bereitstellung in GKE

Auf dieser Seite finden Sie eine Übersicht über PersistentVolumes (PVs), PersistentVolumeClaims (PVCs) und Storage-Klassen in Google Kubernetes Engine (GKE). Der Schwerpunkt liegt auf Speicher, der durch Compute Engine Persistent Disks gesichert wird.

Sie erfahren, wie Sie nichtflüchtigen Speicher in Ihren GKE-Clustern effektiv erstellen, verwalten und Fehler beheben, um für Datensicherheit, Hochverfügbarkeit und optimale Leistung zu sorgen.

Diese Seite richtet sich an Speicherspezialisten, die Speicherplatz erstellen und zuweisen sowie Datensicherheit, Datenschutz sowie Zugriff und Berechtigungen konfigurieren und verwalten. Weitere Informationen zu gängigen Rollen und Beispielaufgaben, auf die wir inGoogle Cloud Inhalten verweisen, finden Sie unter Häufig verwendete GKE-Nutzerrollen und -Aufgaben.

PersistentVolumes

Ressourcen vom Typ PersistentVolume dienen zur Verwaltung von dauerhaftem Speicher in einem Cluster. In GKE wird für PersistentVolume normalerweise ein nichtflüchtiger Speicher unterstützt.

Sie können stattdessen andere Speicherlösungen wie NFS verwenden. Filestore ist eine NFS-Lösung inGoogle Cloud. Informationen zum Einrichten einer Filestore-Instanz als NFS-PV-Lösung für Ihre GKE-Cluster finden Sie in der Filestore-Dokumentation unter Mit dem Filestore-CSI-Treiber auf Filestore-Instanzen zugreifen.

Der Lebenszyklus von PersistentVolume wird in Kubernetes verwaltet. Ein PersistentVolume kann dynamisch bereitgestellt werden. Sie müssen den permanenten Speicher nicht manuell erstellen und löschen.

PersistentVolume sind von Pods unabhängige Clusterressourcen. Dies bedeutet, dass der mit einem PersistentVolume verbundene Speicher und die Daten bestehen bleiben, wenn sich der Cluster ändert und Pods gelöscht und neu erstellt werden. PersistentVolume-Ressourcen können dynamisch über PersistentVolumeClaims bereitgestellt oder explizit von einem Clusteradministrator erstellt werden.

Weitere Informationen zu PersistentVolume-Ressourcen finden Sie in der Dokumentation zu persistenten Volumes in Kubernetes und in der API-Referenz zu persistenten Volumes.

PersistentVolumeClaims

Ein PersistentVolumeClaim ist eine Anfrage und ein Anspruch auf eine PersistentVolume-Ressource. PersistentVolumeClaim-Objekte fordern eine bestimmte Größe, einen Zugriffsmodus und eine StorageClass für das PersistentVolume an. Wenn ein für die Anfrage geeignetes PersistentVolume vorhanden ist oder bereitgestellt werden kann, wird das PersistentVolumeClaim-Objekt an das PersistentVolume gebunden.

Pods verwenden Ansprüche als Volumes. Der Cluster prüft den Anspruch, um das gebundene Volume zu finden, und stellt dieses für den Pod bereit.

Ein weiterer Vorteil der Verwendung von PersistentVolumes und PersistentVolumeClaims ist die Übertragbarkeit. Sie können für verschiedene Cluster und Umgebungen die gleiche Pod-Spezifikation verwenden, da PersistentVolume eine Schnittstelle zum eigentlichen permanenten Speicher sind.

StorageClasses

Volume-Implementierungen wie der CSI-Treiber (Container Storage Interface) für den nichtflüchtigen Speicher von Compute Engine werden über StorageClass-Ressourcen konfiguriert.

GKE erstellt automatisch eine Standard-StorageClass, die den abgestimmten nichtflüchtigen Speichertyp (ext4) verwendet. Die Standard-StorageClass wird verwendet, wenn in einem PersistentVolumeClaim kein StorageClassName angegeben ist. Sie können die bereitgestellte Standard-StorageClass durch eine eigene ersetzen. Eine Anleitung finden Sie unter Standard-StorageClass ändern.

Es besteht die Möglichkeit, benutzerdefinierte StorageClass-Ressourcen zu erstellen, um unterschiedliche Speicherklassen zu beschreiben. Klassen können beispielsweise Dienstqualitätsebenen oder Sicherungsrichtlinien zugeordnet werden. Dieses Konzept wird in anderen Speichersystemen manchmal als „Profile“ bezeichnet.

Wenn Sie einen Cluster mit Windows-Knotenpools verwenden, müssen Sie eine StorageClass erstellen und einen StorageClassName im PersistentVolumeClaim angeben, da der standardmäßige fstype (ext4) von Windows nicht unterstützt wird. Wenn Sie einen nichtflüchtigen Speicher von Compute Engine verwenden, müssen Sie als Dateispeichertyp NTFS verwenden.

Wenn Sie eine StorageClass definieren, müssen Sie einen Bereitsteller auflisten. In GKE empfehlen wir die Verwendung eines der folgenden Bereitsteller:

PersistentVolumes dynamisch bereitstellen

Meist ist es nicht erforderlich, PersistentVolume-Objekte direkt zu konfigurieren oder nichtflüchtigen Compute Engine-Speicher anzulegen. Sie können stattdessen einen PersistentVolumeClaim erstellen, während von Kubernetes automatisch ein nichtflüchtiger Speicher bereitgestellt wird.

Das folgende Manifest beschreibt eine Anfrage für einen Speicher mit 30 Gibibyte (GiB) an Speicher, der aufgrund seines Zugriffsmodus von jeweils einem Knoten im Lese-/Schreibmodus bereitgestellt werden kann. Außerdem wird ein Pod erstellt, der PersistentVolumeClaim als Volume nutzt.

# pvc-pod-demo.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-demo
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 30Gi
  storageClassName: standard-rwo
---
kind: Pod
apiVersion: v1
metadata:
  name: pod-demo
spec:
  volumes:
    - name: pvc-demo-vol
      persistentVolumeClaim:
       claimName: pvc-demo
  containers:
    - name: pod-demo
      image: nginx
      resources:
        limits:
          cpu: 10m
          memory: 80Mi
        requests:
          cpu: 10m
          memory: 80Mi
      ports:
        - containerPort: 80
          name: "http-server"
      volumeMounts:
        - mountPath: "/usr/share/nginx/html"
          name: pvc-demo-vol

Wenn Sie dieses PersistentVolumeClaim-Objekt mit kubectl apply -f pvc-pod-demo.yaml erstellen, generiert Kubernetes dynamisch ein entsprechendes PersistentVolume-Objekt.

Da die Speicherklasse standard-rwo den Volume-Bindungsmodus WaitForFirstConsumer verwendet, wird das PersistentVolume erst erstellt, wenn ein Pod zur Nutzung des Volumes geplant ist.

Das folgende Beispiel zeigt das erstellte PersistentVolume.

apiVersion: v1
kind: PersistentVolume
metadata:
  annotations:
    pv.kubernetes.io/provisioned-by: pd.csi.storage.gke.io
  finalizers:
  - kubernetes.io/pv-protection
  - external-attacher/pd-csi-storage-gke-io
  name: pvc-c9a44c07-cffa-4cd8-b92b-15bac9a9b984
  uid: d52af557-edf5-4f96-8e89-42a3008209e6
spec:
  accessModes:
  - ReadWriteOnce
  capacity:
    storage: 30Gi
  claimRef:
    apiVersion: v1
    kind: PersistentVolumeClaim
    name: pvc-demo
    namespace: default
    uid: c9a44c07-cffa-4cd8-b92b-15bac9a9b984
  csi:
    driver: pd.csi.storage.gke.io
    csi.storage.k8s.io/fstype: ext4
    volumeAttributes:
      storage.kubernetes.io/csiProvisionerIdentity: 1660085000920-8081-pd.csi.storage.gke.io
    volumeHandle: projects/xxx/zones/us-central1-c/disks/pvc-c9a44c07-cffa-4cd8-b92b-15bac9a9b984
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: topology.gke.io/zone
          operator: In
          values:
          - us-central1-c
  persistentVolumeReclaimPolicy: Delete
  storageClassName: standard-rwo
  volumeMode: Filesystem
status:
  phase: Bound

Wenn Sie die Speicherklasse standard-rwo nicht ersetzt haben, wird dieses PersistentVolume in einem neuen, leeren nichtflüchtigen Compute Engine-Speicher abgelegt.

Nichtflüchtigen Speicher löschen

Beim dynamischen Bereitstellen können Sie festlegen, ob Ihr nichtflüchtiger Speicher gelöscht werden soll, wenn ein PersistentVolumeClaim (PVC) gelöscht wird. Dazu setzen Sie das Feld reclaimPolicy in der Konfiguration von StorageClass entweder auf Delete oder Retain.

  • reclaimPolicy: Delete: Dies ist die Standardrichtlinie. Wenn der PVC gelöscht wird, werden das PersistentVolume-Objekt (PV) und das zugrunde liegende Laufwerk (z. B. ein Compute Engine Persistent Disk) automatisch gelöscht. Verwenden Sie diese Richtlinie für temporäre Arbeitslasten oder für Compliance-Anforderungen, bei denen Daten nach Abschluss eines Jobs bereinigt werden müssen.

  • reclaimPolicy: Retain: Wenn Sie diese Richtlinie festlegen, werden das PV und das zugrunde liegende Laufwerk nicht gelöscht, wenn Sie das PVC löschen. Der PV-Status wird zu Released geändert. Die Daten bleiben erhalten, aber das Volume kann erst von einem neuen PVC verwendet werden, wenn ein Administrator es manuell zurückfordert.

Beibehaltene Volumes manuell verwalten

Wenn eine PersistentVolume den Status Released hat, müssen Sie manuell entscheiden, was mit den zugrunde liegenden Daten und dem Laufwerk geschehen soll.

  • Speicher endgültig löschen: Sie müssen sowohl die Kubernetes-PersistentVolume-Ressource als auch das zugrunde liegende Compute Engine-Laufwerk löschen.

    1. Löschen Sie das PersistentVolume: bash kubectl delete pv <your-pv-name>
    2. Suchen Sie nach dem Namen des zugrunde liegenden Laufwerks, indem Sie die YAML-Konfigurationsdatei für das PV beschreiben und nach dem Feld volumeHandle oder einem ähnlichen Feld suchen.
    3. Löschen Sie den nichtflüchtigen Speicher der Compute Engine: bash gcloud compute disks delete <your-disk-name> --zone=<your-zone>
  • Volume wiederverwenden: Ein Volume mit dem Status Released für die Verwendung durch einen anderen PVC zurückzufordern, ist eine anspruchsvolle Aufgabe, bei der die Festplattendaten manuell bereinigt und das PersistentVolume-Objekt bearbeitet werden muss, damit es wieder Available ist. Weitere Informationen zur detaillierten Vorgehensweise finden Sie in der offiziellen Kubernetes-Dokumentation unter PersistentVolume zurückfordern.

Um Datenverluste zu vermeiden oder zu minimieren, empfehlen wir außerdem, Backup for GKE zu aktivieren und regelmäßige Sicherungen Ihres GKE-Cluster zu planen.

Fehlerbehebung bei unerwartetem Löschen von Laufwerken

Wenn Sie feststellen, dass Ihre zugrunde liegenden nichtflüchtigen Speicher gelöscht werden, obwohl Sie das nicht erwarten, ist die häufigste Ursache das Feld reclaimPolicy, das in der von Ihrem PersistentVolumeClaim verwendeten StorageClass-Konfiguration auf Delete festgelegt ist.

So diagnostizieren Sie das Problem:

  1. Prüfen Sie den StorageClass Ihres PVC: bash kubectl get pvc <your-pvc-name> -o jsonpath='{.spec.storageClassName}'

  2. Prüfen Sie das Feld reclaimPolicy: bash kubectl get sc <your-storageclass-name> -o yaml

  3. Richten Sie die Richtlinie an Ihrer Absicht aus:

    • Wenn die Richtlinie Delete ist und für Ihre Anwendung Daten beibehalten werden müssen, müssen Sie Ihre Anwendung so aktualisieren, dass eine StorageClass-Konfiguration verwendet wird, in der die Richtlinie auf Retain festgelegt ist.
    • Wenn die Richtlinie Delete ist und Ihre Anwendung kurzlebig ist oder Compliance-Regeln unterliegt, die eine Datenbereinigung erfordern, ist die Konfiguration korrekt und funktioniert wie vorgesehen.

Weitere Informationen finden Sie in der Kubernetes-Dokumentation zur Reaktivierung.

Nichtflüchtigen Speicher beim Löschen des Clusters verwalten

Wenn ein GKE-Cluster gelöscht wird, behält GKE PersistentVolume-Ressourcen mit der Reaktivierungsrichtlinie Delete oder Retain bei.

Um PersistentVolume-Ressourcen beim Löschen eines Clusters zu entfernen, können Sie den Namespace von PersistentVolumeClaim-Ressourcen manuell löschen. Dies führt zum Löschen von PersistentVolume-Objekten mit der Richtlinie Delete. Alternativ können Sie einzelne PersistentVolumeClaim-Ressourcen löschen. GKE wartet jedoch nicht, bis diese Löschaktivitäten abgeschlossen sind, bevor der Cluster gelöscht wird. Wenn Sie also einen Namespace und dann sofort den Cluster löschen, werden PersistentVolume-Ressourcen mit Delete-Richtlinien möglicherweise nicht gelöscht.

Nach dem Löschen des Clusters können Sie die verbleibenden PersistentVolume-Ressourcen in der Google Cloud Console anzeigen lassen.

Wenn Sie nicht verwendete Ressourcen aufrufen möchten, z. B. nicht verwendete PersistentVolume-Ressourcen, können Sie sich Empfehlungen für inaktive Ressourcen ansehen

Zugriffsmodi

PersistentVolume-Ressourcen unterstützen die folgenden Zugriffsmodi:

  • ReadWriteOnce: Das Volume kann mit Lese-/Schreibzugriff von einem einzelnen Knoten bereitgestellt werden.
  • ReadOnlyMany: Das Volume kann schreibgeschützt von vielen Knoten bereitgestellt werden.
  • ReadWriteMany: Das Volume kann mit Lese-/Schreibzugriff von vielen Knoten bereitgestellt werden. PersistentVolume-Ressourcen, die von nichtflüchtigen Compute Engine-Speichern gesichert werden, unterstützen diesen Zugriffsmodus nicht.
  • ReadWriteOncePod:Das Volume kann nur von einem einzelnen Pod mit Lese-/Schreibzugriff bereitgestellt werden.

Nichtflüchtige Compute Engine-Speicher als ReadOnlyMany verwenden

ReadWriteOnce ist der häufigste Anwendungsfall für nichtflüchtigen Speicher und der Standardzugriffsmodus der meisten Anwendungen. Nichtflüchtige Compute Engine-Speicher unterstützen auch den ReadOnlyMany-Modus, sodass viele Anwendungen oder viele Replikate derselben Anwendung gleichzeitig auf denselben Speicher zugreifen können. Ein Beispiel für einen Anwendungsfall ist die Bereitstellung statischer Inhalte über mehrere Replikate hinweg.

Eine Anleitung finden Sie unter Nichtflüchtige Speicher mit mehreren Lesezugriffen verwenden.

Bestehenden nichtflüchtigen Speicher als PersistentVolumes verwenden

Dynamisch bereitgestellte PersistentVolume-Ressourcen sind bei der Erstellung leer. Wenn Sie einen vorhandenen nichtflüchtigen Speicher von Compute Engine mit Daten haben, können Sie ihn in Ihren Cluster einfügen, indem Sie manuell eine entsprechende PersistentVolume-Ressource erstellen. Der nichtflüchtige Speicher muss sich in derselben Zone wie die Clusterknoten befinden.

In diesem Beispiel wird erläutert, wie Sie ein PersistentVolume mit einem vorhandenen nichtflüchtigen Speicher erstellen.

Deployments oder StatefulSets

Sie können in übergeordneten Controllern wie Deployments oder StatefulSets PersistentVolumeClaim bzw. VolumeClaim-Vorlagen verwenden.

Deployments sind für zustandslose Anwendungen vorgesehen. Daher verwenden alle Replikate eines Deployments denselben PersistentVolumeClaim. Da die erstellten Pod-Replikate identisch sind, funktionieren damit nur Volumes im ReadWriteMany-Modus.

Auch von Deployments mit nur einem Replikat, das ein ReadWriteOnce-Volume verwendet, wird abgeraten. Der Grund dafür ist, dass mit der Standard-Deployment-Strategie bei einer Neuerstellung ein zweiter Pod erstellt wird, ohne vorher den ersten Pod zu löschen. Das Deployment kann aufgrund eines Deadlocks fehlschlagen. Der zweite Pod kann dabei nicht gestartet werden, da das ReadWriteOnce-Volume bereits verwendet wird. Der erste Pod wird dann nicht entfernt, da der zweite Pod noch nicht gestartet wurde. Verwenden Sie stattdessen ein StatefulSet mit ReadWriteOnce-Volumes.

StatefulSets sind die empfohlene Bereitstellungsmethode für zustandsorientierte Anwendungen, die pro Replikat ein eindeutiges Volume erfordern. Wenn Sie StatefulSets mit PersistentVolumeClaim-Vorlagen verwenden, können Sie Anwendungen nutzen, die sich durch die jedem Pod-Replikat zugeordneten eindeutigen PersistentVolumeClaims automatisch vertikal skalieren lassen.

Regionale nichtflüchtige Speicher

Regionale nichtflüchtige Speicher sind multizonale Ressourcen, die Daten zwischen zwei Zonen in derselben Region replizieren und ähnlich wie zonale nichtflüchtige Speicher verwendet werden können. Beim Ausfall in einer Zone oder wenn sich Clusterknoten in einer Zone nicht mehr planen lassen, kann Kubernetes Arbeitslasten mithilfe des Volumes per Failover in die andere Zone übertragen. Regionaler nichtflüchtiger Speicher bietet die Möglichkeit, hochverfügbare Lösungen für zustandsorientierte Arbeitslasten in GKE zu erstellen. Sie müssen dafür sorgen, dass die primäre Zone und die Failover-Zone mit ausreichend Ressourcenkapazität zum Ausführen der Arbeitslast konfiguriert sind.

Regionale nichtflüchtige SSD-Speicher sind eine Option für Anwendungen wie Datenbanken, die sowohl Hochverfügbarkeit als auch hohe Leistung erfordern. Weitere Informationen finden Sie unter Blockspeicher im Leistungsvergleich.

Ebenso wie zonaler nichtflüchtiger Speicher kann auch regionaler nichtflüchtiger Speicher dynamisch nach Bedarf oder vorab manuell vom Clusteradministrator bereitgestellt werden. Informationen zum Hinzufügen regionaler nichtflüchtiger Speicher finden Sie unter Regionalen nichtflüchtigen Speicher bereitstellen.

Zonen in nichtflüchtigen Speichern

Zonale nichtflüchtige Speicher sind zonale Ressourcen und regionale nichtflüchtige Speicher sind multizonale Ressourcen. Wenn Sie dem Cluster nichtflüchtigen Speicher hinzufügen, weist GKE den Speicher einer einzigen Zone zu, sofern keine Zone angegeben ist. GKE wählt die Zone zufällig aus. Wenn nichtflüchtiger Speicher bereitgestellt wurde, werden alle Pods, die auf den Speicher verweisen, für dieselbe Zone wie der nichtflüchtige Speicher geplant. Pods oder Deployments erkennen jedoch die Zone bereits vorhandener nichtflüchtiger Speicher nicht von Natur aus. Damit Pods mit bereits vorhandenen nichtflüchtigen Speichern korrekt geplant werden, verwenden Sie zonale Platzierungsmethoden wie nodeAffinity in Ihrem Pod oder Deployment. Spezifikationen, um auf die entsprechenden Zonen auszurichten.

Volume-Bindungsmodus WaitForFirstConsumer

Wenn Sie einen nichtflüchtigen Speicher in Ihrem Cluster dynamisch bereitstellen, sollten Sie den Modus für die Volume-Bindung WaitForFirstConsumer für Ihre StorageClass festlegen. Mit dieser Einstellung wird Kubernetes angewiesen, einen nichtflüchtigen Speicher in derselben Zone bereitzustellen, in der der Pod geplant ist. Dabei werden Einschränkungen bei der Pod-Planung wie Anti-Affinität und Knotenauswahlen berücksichtigt. Durch Anti-Affinität in Zonen können StatefulSet-Pods zusammen mit den entsprechenden Laufwerken auf die Zonen verteilt werden.

Im Folgenden finden Sie eine Beispiel-StorageClass zum Bereitstellen zonaler nichtflüchtiger Speicher, die WaitForFirstConsumer festlegen:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: slow
provisioner: pd.csi.storage.gke.io
parameters:
  type: pd-balanced
  csi.storage.k8s.io/fstype: ext4
volumeBindingMode: WaitForFirstConsumer

Ein Beispiel für die Verwendung regionaler nichtflüchtiger Speicher finden Sie unter Regionalen nichtflüchtigen Speicher bereitstellen.

Nächste Schritte