Lokalen SSD-gestützten Rohblockspeicher bereitstellen und verwenden


Auf dieser Seite wird erläutert, wie Sie lokalen SSD-Speicher in GKE-Clustern (Google Kubernetes Engine) bereitstellen und Arbeitslasten konfigurieren, um Daten aus lokalem, SSD-gestützten Rohblockspeicher zu nutzen, der an Knoten in Ihrem Cluster angehängt ist.

Mit dieser Option für lokale SSDs haben Sie mehr Kontrolle über den zugrunde liegenden Speicher und können einen eigenen Cache auf Knotenebene für Pods erstellen, um eine bessere Leistung für Ihre Anwendungen zu erzielen. Sie können diese Option auch anpassen, wenn Sie ein Dateisystem auf lokalen SSD-Laufwerken installieren, indem Sie ein DaemonSet zur Konfiguration von RAID und zur Formatierung von Laufwerken nach Bedarf ausführen.

Weitere Informationen zur lokalen SSD-Unterstützung für den Zugriff auf Rohblocks in GKE finden Sie unter Lokale SSDs.

Hinweise

Führen Sie die folgenden Schritte durch, bevor Sie beginnen:

  • Aktivieren Sie die Google Kubernetes Engine API.
  • Google Kubernetes Engine API aktivieren
  • Wenn Sie die Google Cloud CLI für diese Aufgabe verwenden möchten, müssen Sie die gcloud CLI installieren und dann initialisieren. Wenn Sie die gcloud CLI bereits installiert haben, rufen Sie die neueste Version mit gcloud components update ab.

Cluster oder Knotenpool mit lokalem SSD-gestützten Rohblockspeicher erstellen

Verwenden Sie die gcloud CLI mit der Option --local-nvme-ssd-block, um einen Cluster mit lokalem SSD-gestützten Rohblockspeicher zu erstellen.

Welche gcloud CLI Sie zum Erstellen des Clusters oder Knotenpools ausführen, hängt davon ab, auf welcher Generation einer Maschinenserie der von Ihnen verwendete Maschinentyp basiert. Beispielsweise gehören N1- und N2-Maschinentypen zu einer Maschinenserie der ersten oder zweiten Generation, während C3-Maschinentypen zu einer Maschinenserie der dritten Generation gehören.

Cluster mit lokaler SSD erstellen

1. oder 2. Generation

Wenn Sie einen Maschinentyp aus einer Maschinenserie der ersten oder zweiten Generation verwenden, erstellen Sie den Cluster durch Angabe der Option --local-nvme-ssd-block count=NUMBER_OF_DISKS. Die Option gibt die Anzahl der lokalen SSD-Laufwerke an, die an die einzelnen Knoten angehängt werden sollen. Die maximale Anzahl variiert je nach Maschinentyp und Region.

So erstellen Sie ein Cluster:

gcloud container clusters create CLUSTER_NAME \
    --local-nvme-ssd-block count=NUMBER_OF_DISKS \
    --machine-type=MACHINE_TYPE \
    --release-channel CHANNEL_NAME

Ersetzen Sie Folgendes:

  • CLUSTER_NAME ist der Name des Clusters.
  • NUMBER_OF_DISKS ist die Anzahl der lokalen SSD-Laufwerke, die auf jedem Knoten bereitgestellt werden sollen. Die maximale Anzahl der Laufwerke variiert je nach Maschinentyp und Region.
  • MACHINE_TYPE ist der zu verwendende Maschinentyp der ersten oder zweiten Generation. Die Angabe dieses Felds ist erforderlich, da lokale SSDs nicht mit dem Standardtyp e2-medium verwendet werden können.
  • CHANNEL_NAME: Eine Release-Version, die GKE-Versionen nach 1.25.3-gke.1800 enthält.

3. Generation

Wenn Sie einen Maschinentyp aus einer Maschinenserie der dritten Generation nutzen, verwenden Sie die Option --local-nvme-ssd-block ohne Feld „count“, um einen Cluster zu erstellen. GKE stellt automatisch lokale SSD-Kapazität für Ihren Cluster basierend auf der VM-Form bereit. Die maximale Anzahl variiert je nach Maschinentyp und Region.

gcloud container clusters create CLUSTER_NAME \
    --machine-type=MACHINE_TYPE \
    --cluster-version CLUSTER_VERSION \
    --local-nvme-ssd-block

Ersetzen Sie Folgendes:

  • CLUSTER_NAME ist der Name des Clusters.
  • MACHINE_TYPE ist der zu verwendende Maschinentyp aus einer Maschinenserie der dritten Generation.
  • CLUSTER_VERSION ist eine GKE-Clusterversion, die lokale SSDs auf Maschinentypen aus der Maschinenserie einer dritten Generation unterstützt.

Knotenpool mit lokaler SSD erstellen

1. oder 2. Generation

Führen Sie den folgenden Befehl aus, um einen Knotenpool zu erstellen, der lokale SSD-Laufwerke für den Zugriff auf Rohblockspeicher verwendet:

gcloud container node-pools create POOL_NAME \
    --cluster=CLUSTER_NAME \
    --machine-type=MACHINE_TYPE \
    --local-nvme-ssd-block count=NUMBER_OF_DISKS

Ersetzen Sie Folgendes:

  • POOL_NAME ist der Name des neuen Knotenpools.
  • CLUSTER_NAME ist der Name des Clusters.
  • MACHINE_TYPE ist der zu verwendende Maschinentyp der ersten oder zweiten Generation. Dieses Feld ist erforderlich, da lokale SSDs nicht mit dem Standardtyp e2-medium verwendet werden können.
  • NUMBER_OF_DISKS ist die Anzahl der lokalen SSD-Laufwerke, die auf jedem Knoten bereitgestellt werden sollen. Die maximale Anzahl der Laufwerke variiert je nach Maschinentyp und Region.

3. Generation

Wenn Sie einen Maschinentyp aus einer Maschinenserie der dritten Generation nutzen, verwenden Sie die Option --local-nvme-ssd-block ohne Feld „count“, um einen Cluster zu erstellen:

gcloud container node-pools create POOL_NAME \
    --cluster=CLUSTER_NAME \
    --machine-type=MACHINE_TYPE \
    --node-version NODE_VERSION \
    --local-nvme-ssd-block

Ersetzen Sie Folgendes:

  • POOL_NAME: der Name des neuen Knotenpools.
  • CLUSTER_NAME ist der Name des Clusters.
  • MACHINE_TYPE ist der zu verwendende Maschinentyp aus einer Maschinenserie der dritten Generation.
  • NODE_VERSION: Eine GKE-Knotenpoolversion, die lokale SSDs auf Maschinentypen aus der Maschinenserie einer dritten Generation unterstützt.

Knoten im Knotenpool werden mit dem Label cloud.google.com/gke-local-nvme-ssd=true erstellt. Sie können die Berechtigungen mit dem folgenden Befehl prüfen:

kubectl describe node NODE_NAME

Das Hostbetriebssystem erstellt für jede lokale SSD, die Sie an den Knotenpool anhängen, einen symbolischen Link (Symlink), um auf das Laufwerk unter einem Ordinalordner zuzugreifen, sowie einen Symlink mit einer UUID (Universally Unique Identifier). Wenn Sie beispielsweise einen Knotenpool mit drei lokalen SSDs mit der Option --local-nvme-ssd-block erstellen, erstellt das Hostbetriebssystem die folgenden Symlinks für die Laufwerke:

  • /dev/disk/by-id/google-local-ssd-block0
  • /dev/disk/by-id/google-local-ssd-block1
  • /dev/disk/by-id/google-local-ssd-block2

Dementsprechend erstellt das Hostbetriebssystem auch folgende Symlinks mit UUIDs für die Laufwerke:

  • /dev/disk/by-uuid/google-local-ssds-nvme-block/local-ssd-GENERATED_UUID1
  • /dev/disk/by-uuid/google-local-ssds-nvme-block/local-ssd-GENERATED_UUID2
  • /dev/disk/by-uuid/google-local-ssds-nvme-block/local-ssd-GENERATED_UUID3

So kann auf die Laufwerke über eine eindeutige Kennung zugegriffen werden.

Auf lokale SSD-Volumes zugreifen

Das folgende Beispiel zeigt, wie Sie auf den lokalen SSD-gestützten Rohblockspeicher zugreifen können.

Lokale PersistentVolumes

Lokale SSD-Volumes können mithilfe von PersistentVolumes als Pods bereitgestellt werden.

Zum Erstellen von PersistentVolumes aus lokalen SSDs können Sie entweder ein PersistentVolume manuell erstellen oder den statischen Bereitsteller für lokale Volumes ausführen.

Einschränkungen lokaler PersistentVolumes

  • Derzeit werden Cluster-Autoscaling und die dynamische Bereitstellung mit lokalen PersistentVolumes nicht unterstützt.

  • Beim Aktualisieren eines GKE-Clusters oder Reparieren von Knoten werden die Compute Engine-Instanzen gelöscht. Dadurch werden auch alle Daten auf den lokalen SSDs gelöscht.

  • Aktivieren Sie daher weder automatische Knotenupgrades noch automatische Knotenreparaturen für Cluster oder Knotenpools, die lokale SSDs für nichtflüchtige Daten verwenden. Sie müssen Ihre Anwendungsdaten zuerst sichern und dann die Daten in einem neuen Cluster oder Knotenpool wiederherstellen.

  • Lokale PersistentVolume-Objekte werden nicht automatisch bereinigt, wenn ein Knoten gelöscht, aktualisiert, repariert oder herunterskaliert wird. Es wird empfohlen, regelmäßig veraltete lokale PersistentVolume-Objekte zu prüfen und zu löschen, die mit gelöschten Knoten verknüpft sind.

PersistentVolume manuell erstellen

Sie können ein PersistentVolume für jede lokale SSD auf jedem Knoten im Cluster manuell erstellen.

Verwenden Sie das Feld nodeAffinity in einem PersistentVolume-Objekt, um auf eine lokale SSD auf einem bestimmten Knoten zu verweisen. Das folgende Beispiel zeigt die PersistentVolume-Spezifikation für lokale SSDs auf Knoten, die unter Linux ausgeführt werden:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: "example-local-pv"
spec:
  capacity:
    storage: 375Gi
  accessModes:
  - "ReadWriteOnce"
  persistentVolumeReclaimPolicy: "Retain"
  storageClassName: "local-storage"
  local:
    path: "/mnt/disks/ssd0"
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: "kubernetes.io/hostname"
          operator: "In"
          values:
          - "gke-test-cluster-default-pool-926ddf80-f166"

In diesem Beispiel werden die lokalen SSDs manuell für RAID konfiguriert und formatiert und dann unter /mnt/disks/ssd0 auf Knoten gke-test-cluster-default-pool-926ddf80-f166 bereitgestellt. Das Feld „nodeAffinity“ wird verwendet, um Arbeitslasten Knoten mit lokalen SSDs zuzuweisen, die manuell für RAID konfiguriert sind. Wenn Sie nur einen Knoten in Ihrem Cluster haben oder RAID für alle Knoten konfiguriert haben, ist das Feld „nodeAffinity“ nicht erforderlich.

Die entsprechende PersistenVolumeClaim-Spezifikation sieht so aus:

  kind: PersistentVolumeClaim
  apiVersion: v1
  metadata:
    name: ssd-local-claim
  spec:
    accessModes:
    - ReadWriteOnce
    storageClassName: local-storage
    resources:
      requests:
        storage: 37Gi

Wenn Sie das PersistentVolume löschen, müssen Sie die Daten manuell vom Laufwerk löschen.

Statischen Bereitsteller für lokale Volumes ausführen

Mit dem statischen Bereitsteller für lokale Volumes können Sie PersistentVolumes für lokale SSDs automatisch erstellen. Der Bereitsteller ist ein DaemonSet, das die lokalen SSDs auf jedem Knoten verwaltet, die PersistentVolumes für diese Knoten erstellt und löscht und die Daten auf dem lokalen SSD-Laufwerk bereinigt, wenn das PersistentVolume freigegeben wird.

So führen Sie den statischen Bereitsteller für lokale Volumes aus:

  1. Verwenden Sie ein DaemonSet, um RAID zu konfigurieren und die Laufwerke zu formatieren:

    1. Laden Sie die Spezifikation gke-daemonset-raid-disks.yaml herunter.
    2. Stellen Sie das DaemonSet für Raid-Laufwerke bereit. Das DaemonSet legt ein RAID 0-Array auf allen lokalen SSD-Laufwerken fest und formatiert das Gerät in einem ext4-Dateisystem.

      kubectl create -f gke-daemonset-raid-disks.yaml
      
  2. Laden Sie die Spezifikation gke-nvme-ssd-block-raid.yaml herunter und ändern Sie die Namespace-Felder der Spezifikation nach Bedarf.

    Die Spezifikation enthält diese Ressourcen:

    • ServiceAccount für den Bereitsteller
    • ClusterRole und ClusterRoleBindings für Berechtigungen zum:
      • Erstellen und Löschen von PersistentVolume-Objekten
      • Abrufen von Node-Objekten
    • ConfigMap mit Einstellungen für den Bereitsteller für GKE
    • DaemonSet zum Ausführen des Bereitstellers
  3. Stellen Sie den Bereitsteller bereit:

    kubectl create -f gke-nvme-ssd-block-raid.yaml
    

    Wenn der Bereitsteller erfolgreich ausgeführt wird, erstellt er ein PersistentVolume-Objekt für das RAID-Local-SSD-Gerät im Cluster.

  4. Speichern Sie das folgende PersistentVolumeClaim-Manifest als provisioner-pvc-example.yaml:

    kind: PersistentVolumeClaim
    apiVersion: v1
    metadata:
      name: PVC_NAME
    spec:
      accessModes:
      - ReadWriteOnce
      resources:
        requests:
          storage: 50Gi
      storageClassName: nvme-ssd-block
    

    Ersetzen Sie PVC_NAME durch den Namen Ihres Clusters.

  5. Erstellen Sie den PersistentVolumeClaim:

    kubectl create -f provisioner-pvc-example.yaml
    
  6. Speichern Sie das folgende Pod-Manifest als provisioner-pod-example.yaml:

    apiVersion: v1
    kind: Pod
    metadata:
      name: POD_NAME
    spec:
      containers:
      - name: "shell"
        image: "ubuntu:14.04"
        command: ["/bin/sh", "-c"]
        args: ["echo 'hello world' > /cache/test.txt && sleep 1 && cat /cache/test.txt && sleep 3600"]
        volumeMounts:
        - mountPath: /cache
          name: local-ssd-storage
      volumes:
      - name: local-ssd-storage
        persistentVolumeClaim:
          claimName: PVC_NAME
    

    Ersetzen Sie POD_NAME durch den Namen Ihres Clusters.

  7. Erstellen Sie den Pod:

    kubectl create -f provisioner-pod-example.yaml
    

Verzögerte Volume-Bindung aktivieren

Zur Verbesserung der Planung empfehlen wir außerdem, eine StorageClass mit volumeBindingMode: WaitForFirstConsumer zu erstellen. Damit wird die PersistentVolumeClaim-Bindung bis zur Pod-Planung verzögert und eine lokale SSD von einem geeigneten Knoten ausgewählt, der den Pod auch ausführen kann. Dieses verbesserte Planungsverhalten bedeutet, dass bei der Auswahl eines Knotens für einen ausführbaren Pod nicht nur die Knoten berücksichtigt werden, die verfügbare lokale SSDs haben, sondern auch CPU- und Arbeitsspeicheranfragen des Pods, Knotenaffinität, Pod-Affinität und -Antiaffinität sowie mehrere PVC-Anfragen.

In diesem Beispiel wird der Modus für verzögerte Volume-Bindung verwendet:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: "local-nvme"
provisioner: "kubernetes.io/no-provisioner"
volumeBindingMode: "WaitForFirstConsumer"

Um eine StorageClass mit verzögerter Bindung zu erstellen, speichern Sie das YAML-Manifest in einer lokalen Datei und wenden Sie es mit dem folgenden Befehl auf den Cluster an:

kubectl apply -f filename

Fehlerbehebung

Eine Anleitung zur Fehlerbehebung finden Sie unter Fehlerbehebung bei Speicherproblemen in GKE.

Nächste Schritte