Zustandsorientierte Arbeitslast mit Filestore bereitstellen


In dieser Anleitung wird gezeigt, wie eine einfache zustandsorientierte Lese-/Schreib-Arbeitslast mit einem Nichtflüchtigen Volume (PV) und einem Anspruch auf nichtflüchtiges Volume (PVC) auf der Google Kubernetes Engine (GKE) bereitgestellt wird. In dieser Anleitung erfahren Sie, wie Sie mit Filestore, dem verwalteten Netzwerkdateisystem von Google Cloud, Skalierbarkeit gewährleisten können.

Hintergrund

Pods sind standardmäßig sitzungsspezifisch. Das bedeutet, dass GKE den Status und den Wert eines Pods löscht, wenn er gelöscht, entfernt oder neu geplant wird.

Als Anwendungsoperator möchten Sie möglicherweise zustandsorientierte Arbeitslasten verwalten. Beispiele für solche Arbeitslasten sind Anwendungen, die WordPress-Artikel verarbeiten, Nachrichtenanwendungen und Anwendungen, die maschinelles Lernen verarbeiten.

Mit Filestore in GKE können Sie die folgenden Vorgänge ausführen:

  • Skalierbare zustandsorientierte Arbeitslasten bereitstellen
  • Aktivieren Sie mehrere Pods, die ReadWriteMany als accessMode haben, sodass mehrere Pods gleichzeitig in denselben Speicher lesen und schreiben können.
  • Richten Sie GKE so ein, dass Volumes gleichzeitig in mehreren Pods bereitgestellt werden.
  • Nichtflüchtiger Speicher, wenn Pods entfernt werden
  • Mit Pods Daten freigeben und einfach skalieren

Ziele

Diese Anleitung richtet sich an Anwendungsoperatoren und andere Nutzer, die eine skalierbare zustandsorientierte Arbeitslast in GKE mit PVC und NFS einrichten möchten.

Diagramm: Zustandsorientierte Arbeitslast-GKE

Diese Anleitung umfasst die folgenden Schritte:

  1. einen GKE-Cluster installieren
  2. Konfigurieren Sie den verwalteten Dateispeicher mit Filestore mithilfe von CSI.
  3. Leser- und Autor-Pod erstellen
  4. Den Leser-Pod für einen Dienst-Load-Balancer verfügbar machen und darauf zugreifen.
  5. Skalieren Sie den Autor hoch.
  6. Greifen Sie auf Daten vom Schreib-Pod zu.

Kosten

In dieser Anleitung werden die folgenden kostenpflichtigen Komponenten von Google Cloudverwendet:

Mit unserem Preisrechner können Sie eine Kostenschätzung für Ihre voraussichtliche Nutzung erstellen.

Nach Abschluss dieser Anleitung können Sie weitere Kosten durch Löschen von erstellten Ressourcen vermeiden. Weitere Informationen finden Sie unter Bereinigen.


Eine detaillierte Anleitung dazu finden Sie direkt in der Google Cloud Console. Klicken Sie dazu einfach auf Anleitung:

Anleitung


Hinweis

Projekt einrichten

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. In the Google Cloud console, on the project selector page, click Create project to begin creating a new Google Cloud project.

    Go to project selector

  3. Make sure that billing is enabled for your Google Cloud project.

  4. Enable the Compute Engine, GKE, and Filestore APIs.

    Enable the APIs

  5. In the Google Cloud console, on the project selector page, click Create project to begin creating a new Google Cloud project.

    Go to project selector

  6. Make sure that billing is enabled for your Google Cloud project.

  7. Enable the Compute Engine, GKE, and Filestore APIs.

    Enable the APIs

  8. Standardeinstellungen für die Google Cloud CLI festlegen

    1. Starten Sie in der Google Cloud Console eine Cloud Shell-Instanz:
      Cloud Shell öffnen

    2. Laden Sie den Quellcode für diese Beispielanwendung herunter:

      git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
      cd kubernetes-engine-samples/databases/stateful-workload-filestore
      
    3. Legen Sie die Standardumgebungsvariablen fest:

      gcloud config set project PROJECT_ID
      gcloud config set compute/region COMPUTE_REGION
      gcloud config set compute/zone COMPUTE_ZONE
      gcloud config set filestore/zone COMPUTE_ZONE
      gcloud config set filestore/region COMPUTE_REGION
      

      Ersetzen Sie die folgenden Werte:

    GKE-Cluster erstellen

    1. Erstellen Sie einen GKE-Cluster.

      gcloud container clusters create-auto CLUSTER_NAME --location CONTROL_PLANE_LOCATION
      

      Ersetzen Sie den folgenden Wert:

      • CLUSTER_NAME: Ihr Clustername.
      • CONTROL_PLANE_LOCATION: Der Compute Engine-Standort der Steuerungsebene des Clusters. Geben Sie für regionale Cluster eine Region und für zonale Cluster eine Zone an.

      Das Ergebnis sieht nach der Erstellung des Clusters in etwa so aus:

        gcloud container clusters describe CLUSTER_NAME
        NAME: CLUSTER_NAME
        LOCATION: northamerica-northeast2
        MASTER_VERSION: 1.21.11-gke.1100
        MASTER_IP: 34.130.255.70
        MACHINE_TYPE: e2-medium
        NODE_VERSION: 1.21.11-gke.1100
        NUM_NODES: 3
        STATUS: RUNNING
      

      Dabei ist STATUS gleich RUNNING.

    Verwalteten Dateispeicher mit Filestore mithilfe von CSI konfigurieren

    GKE bietet eine Möglichkeit, den CSI-Treiber von Kubernetes Filestore automatisch in Ihren Clustern bereitzustellen und zu verwalten. Mit Filestore CSI können Sie Filestore-Instanzen dynamisch erstellen oder löschen und in Kubernetes-Arbeitslasten mit einem StorageClass oder Deployment verwenden.

    Sie können eine neue Filestore-Instanz erstellen. Erstellen Sie dazu eine PVC, die eine Filestore-Instanz und das PV dynamisch bereitstellt, oder greifen Sie auf vorbereitete Filestore-Instanzen in Kubernetes-Workloads zu.

    Neue Instanz

    Speicherklasse erstellen

    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: filestore-sc
    provisioner: filestore.csi.storage.gke.io
    volumeBindingMode: Immediate
    allowVolumeExpansion: true
    parameters:
      tier: standard
      network: default
    • volumeBindingMode ist auf Immediate gesetzt, wodurch die Bereitstellung des Volumes sofort beginnen kann.
    • tier ist auf standard gesetzt, um die Erstellungszeit von Filestore-Instanzen zu verkürzen. Wenn Sie einen höheren NFS-Speicher, Snapshots für die Datensicherung, Datenreplikation über mehrere Zonen und andere Features auf Unternehmensebene benötigen, legen Sie tier auf enterprise fest. Hinweis: Die Rückforderungsrichtlinie für dynamisch erstelltes PV wird standardmäßig auf Delete gesetzt, wenn reclaimPolicy in StorageClass nicht festgelegt ist.
    1. Erstellen Sie die Ressource StorageClass:

      kubectl create -f filestore-storageclass.yaml
      
    2. Prüfen Sie, ob die Speicherklasse erstellt wurde:

      kubectl get sc
      

      Die Ausgabe sieht etwa so aus:

      NAME                     PROVISIONER                    RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE
      filestore-sc             filestore.csi.storage.gke.io   Delete          Immediate              true                   94m
      

    Vorab bereitgestellte Instanz

    Speicherklasse erstellen

    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: filestore-sc
    provisioner: filestore.csi.storage.gke.io
    volumeBindingMode: Immediate
    allowVolumeExpansion: true

    Wenn volumeBindingMode auf Immediate gesetzt ist, kann die Bereitstellung des Volumes sofort beginnen.

    1. Erstellen Sie die Ressource StorageClass:

        kubectl create -f preprov-storageclass.yaml
      
    2. Prüfen Sie, ob die Speicherklasse erstellt wurde:

        kubectl get sc
      

      Die Ausgabe sieht etwa so aus:

        NAME                     PROVISIONER                    RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE
        filestore-sc             filestore.csi.storage.gke.io   Delete          Immediate              true                   94m
      

    Nichtflüchtiges Volume für die Filestore-Instanz erstellen

    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: fileserver
      annotations:
        pv.kubernetes.io/provisioned-by: filestore.csi.storage.gke.io
    spec:
      storageClassName: filestore-sc
      capacity:
        storage: 1Ti
      accessModes:
        - ReadWriteMany
      persistentVolumeReclaimPolicy: Delete
      volumeMode: Filesystem
      csi:
        driver: filestore.csi.storage.gke.io
        # Modify this to use the zone, filestore instance and share name.
        volumeHandle: "modeInstance/<LOCATION>/<INSTANCE_NAME>/<FILE_SHARE_NAME>"
        volumeAttributes:
          ip: <IP_ADDRESS> # Modify this to Pre-provisioned Filestore instance IP
          volume: <FILE_SHARE_NAME> # Modify this to Pre-provisioned Filestore instance share name
    1. Prüfen Sie, ob die vorhandene Filestore-Instanz bereit ist:

        gcloud filestore instances list
      

      Die Ausgabe sieht in etwa so aus, wobei der Wert STATE READY ist:

        INSTANCE_NAME: stateful-filestore
        LOCATION: us-central1-a
        TIER: ENTERPRISE
        CAPACITY_GB: 1024
        FILE_SHARE_NAME: statefulpath
        IP_ADDRESS: 10.109.38.98
        STATE: READY
        CREATE_TIME: 2022-04-05T18:58:28
      

      Notieren Sie sich INSTANCE_NAME, LOCATION, FILE_SHARE_NAME und IP_ADDRESS der Filestore-Instanz.

    2. Füllen Sie die Variablen der Filestore-Instanzkonsole aus:

        INSTANCE_NAME=INSTANCE_NAME
        LOCATION=LOCATION
        FILE_SHARE_NAME=FILE_SHARE_NAME
        IP_ADDRESS=IP_ADDRESS
      
    3. Ersetzen Sie die Platzhaltervariablen durch die oben abgerufenen Konsolenvariablen in der Datei preprov-pv.yaml:

        sed "s/<INSTANCE_NAME>/$INSTANCE_NAME/" preprov-pv.yaml > changed.yaml && mv changed.yaml preprov-pv.yaml
        sed "s/<LOCATION>/$LOCATION/" preprov-pv.yaml > changed.yaml && mv changed.yaml preprov-pv.yaml
        sed "s/<FILE_SHARE_NAME>/$FILE_SHARE_NAME/" preprov-pv.yaml > changed.yaml && mv changed.yaml preprov-pv.yaml
        sed "s/<IP_ADDRESS>/$IP_ADDRESS/" preprov-pv.yaml > changed.yaml && mv changed.yaml preprov-pv.yaml
      
    4. PV erstellen

        kubectl apply -f preprov-pv.yaml
      
    5. Prüfen Sie, ob der STATUS des PV auf Bound gesetzt ist:

        kubectl get pv
      

      Die Ausgabe sieht etwa so aus:

        NAME        CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                STORAGECLASS    REASON   AGE
        fileserver  1Ti        RWX            Delete           Bound    default/fileserver   filestore-sc             46m
      

    Mit einem PersistentVolumeClaim auf das Volume zugreifen

    Das folgende pvc.yaml-Manifest verweist auf die StorageClass des Filestore-CSI-Treibers mit dem Namen filestore-sc.

    Damit mehrere Pods Lese- und Schreibvorgänge im Volume ausführen, ist accessMode auf ReadWriteMany gesetzt.

    kind: PersistentVolumeClaim
    apiVersion: v1
    metadata:
      name: fileserver
    spec:
      accessModes:
      - ReadWriteMany
      storageClassName: filestore-sc
      resources:
        requests:
          storage: 1Ti
    1. Stellen Sie das PVC bereit:

      kubectl create -f pvc.yaml
      
    2. Prüfen Sie, ob das PVC erstellt wurde:

      kubectl get pvc
      

      Die Ausgabe sieht etwa so aus:

      NAME         STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS        AGE
      fileserver   Bound    pvc-aadc7546-78dd-4f12-a909-7f02aaedf0c3   1Ti        RWX            filestore-sc        92m
      
    3. Prüfen Sie, ob die neu erstellte Filestore-Instanz bereit ist:

      gcloud filestore instances list
      

      Die Ausgabe sieht etwa so aus:

      INSTANCE_NAME: pvc-5bc55493-9e58-4ca5-8cd2-0739e0a7b68c
      LOCATION: northamerica-northeast2-a
      TIER: STANDARD
      CAPACITY_GB: 1024
      FILE_SHARE_NAME: vol1
      IP_ADDRESS: 10.29.174.90
      STATE: READY
      CREATE_TIME: 2022-06-24T18:29:19
      

    Leser- und Autor-Pod erstellen

    In diesem Abschnitt erstellen Sie einen Leser-Pod und einen Autor-Pod. In dieser Anleitung werden Kubernetes-Bereitstellungen verwendet, um die Pods zu erstellen. Ein Deployment ist ein Kubernetes-API-Objekt, mit dem Sie mehrere Replikate von Pods ausführen können, die auf die Knoten in einem Cluster verteilt sind.

    Reader-Pod erstellen

    Der Reader-Pod liest die Datei, die von den Writer-Pods geschrieben wird. Die Reader-Pods sehen, wann und welches Autor-Pod-Replikat in die Datei geschrieben hat.

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: reader
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: reader
      template:
        metadata:
          labels:
            app: reader
        spec:
          containers:
          - name: nginx
            image: nginx:stable-alpine
            ports:
            - containerPort: 80
            volumeMounts:
            - name: fileserver
              mountPath: /usr/share/nginx/html # the shared directory 
              readOnly: true
          volumes:
          - name: fileserver
            persistentVolumeClaim:
              claimName: fileserver

    Der Reader-Pod liest aus dem Pfad /usr/share/nginx/html, der von allen Pods gemeinsam genutzt wird.

    1. Stellen Sie den Reader-Pod bereit:

      kubectl apply -f reader-fs.yaml
      
    2. Prüfen Sie, ob die Lesereplikate ausgeführt werden. Fragen Sie dazu die Liste der Pods ab:

      kubectl get pods
      

      Die Ausgabe sieht etwa so aus:

      NAME                      READY   STATUS    RESTARTS   AGE
      reader-66b8fff8fd-jb9p4   1/1     Running   0          3m30s
      

    Schreib-Pod erstellen

    Der Schreib-Pod schreibt regelmäßig in eine freigegebene Datei, auf die andere Autor- und Leser-Pods zugreifen können. Der Schreib-Pod zeichnet seinen Präsenz dadurch auf, dass er seinen Hostnamen in die freigegebene Datei schreibt.

    Das für den Schreib-Pod verwendete Image ist ein benutzerdefiniertes Image von Alpine Linux, das für Dienstprogramme und Produktionsanwendungen verwendet wird. Es enthält ein Skript indexInfo.html, das die Metadaten des neuesten Autors abruft und die Anzahl aller eindeutigen Autoren und Schreibvorgänge insgesamt ermittelt.

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: writer
    spec:
      replicas: 2 # start with 2 replicas
      selector:
        matchLabels:
          app: writer
      template:
        metadata:
          labels:
            app: writer
        spec:
          containers:
          - name: content
            image: us-docker.pkg.dev/google-samples/containers/gke/stateful-workload:latest
            volumeMounts:
            - name: fileserver
              mountPath: /html # the shared directory
            command: ["/bin/sh", "-c"]
            args:
            - cp /htmlTemp/indexInfo.html /html/index.html;
              while true; do
              echo "<b> Date :</b> <text>$(date)</text> <b> Writer :</b> <text2> ${HOSTNAME} </text2> <br>  " >> /html/indexData.html;
              sleep 30;  
              done
          volumes:
          - name: fileserver
            persistentVolumeClaim:
              claimName: fileserver

    In dieser Anleitung schreibt der Schreib-Pod alle 30 Sekunden in den Pfad /html/index.html. Ändern Sie den Zahlenwert sleep, um eine andere Schreibhäufigkeit zu erhalten.

    1. Stellen Sie den Schreib-Pod bereit:

      kubectl apply -f writer-fs.yaml
      
    2. Prüfen Sie, ob die Schreib-Pods ausgeführt werden. Fragen Sie dazu die Liste der Pods ab:

      kubectl get pods
      

      Die Ausgabe sieht etwa so aus:

      NAME                      READY   STATUS    RESTARTS   AGE
      reader-66b8fff8fd-jb9p4   1/1     Running   0          3m30s
      writer-855565fbc6-8gh2k   1/1     Running   0          2m31s
      writer-855565fbc6-lls4r   1/1     Running   0          2m31s
      

    Lese-Arbeitslast für einen Dienst-Load-Balancer verfügbar machen und darauf zugreifen

    Erstellen Sie einen Dienst vom Typ LoadBalancer, um eine Arbeitslast außerhalb des Clusters verfügbar zu machen. Dieser Diensttyp erstellt einen externen Load-Balancer mit einer IP-Adresse, die über das Internet erreichbar ist.

    1. Erstellen Sie einen Dienst vom Typ LoadBalancer mit dem Namen reader-lb:

      kubectl create -f loadbalancer.yaml
      
    2. Beobachten Sie die Bereitstellung, damit Sie sehen, dass GKE einen EXTERNAL-IP für den reader-lb-Dienst zuweist:

      kubectl get svc --watch
      

      Wenn Service bereit ist, wird in der Spalte EXTERNAL-IP die öffentliche IP-Adresse des Load-Balancers angezeigt:

        NAME         TYPE           CLUSTER-IP    EXTERNAL-IP     PORT(S)        AGE
        kubernetes   ClusterIP      10.8.128.1    <none>          443/TCP        2d21h
        reader-lb    LoadBalancer   10.8.131.79   34.71.232.122   80:32672/TCP   2d20h
      
    3. Drücken Sie Strg+C, um den Überwachungsvorgang zu beenden.

    4. Verwenden Sie einen Webbrowser, um zur EXTERNAL-IP zu wechseln, die dem Load-Balancer zugewiesen ist. Die Seite wird alle 30 Sekunden aktualisiert. Je mehr Schreib-Pods und je kürzer die Häufigkeit, desto mehr Einträge werden angezeigt.

    Weitere Informationen zum Load-Balancer-Dienst finden Sie unter loadbalancer.yaml.

    Autor hochskalieren

    Da das PV accessMode auf ReadWriteMany gesetzt wurde, kann GKE die Anzahl der Pods erhöhen, sodass mehr Schreib-Pods auf dieses gemeinsame Volume schreiben können (oder mehr Leser es lesen können).

    1. Skalieren Sie writer auf fünf Replikate hoch:

      kubectl scale deployment writer --replicas=5
      

      Die Ausgabe sieht etwa so aus:

      deployment.extensions/writer scaled
      
    2. Prüfen Sie die Anzahl der ausgeführten Replikate:

      kubectl get pods
      

      Die Ausgabe sieht etwa so aus:

      NAME                      READY   STATUS    RESTARTS   AGE
      reader-66b8fff8fd-jb9p4   1/1     Running   0          11m
      writer-855565fbc6-8dfkj   1/1     Running   0          4m
      writer-855565fbc6-8gh2k   1/1     Running   0          10m
      writer-855565fbc6-gv5rs   1/1     Running   0          4m
      writer-855565fbc6-lls4r   1/1     Running   0          10m
      writer-855565fbc6-tqwxc   1/1     Running   0          4m
      
    3. Verwenden Sie einen Webbrowser, um noch einmal die EXTERNAL-IP aufzurufen, die dem Load-Balancer zugewiesen ist.

    Jetzt haben Sie den Cluster so konfiguriert und skaliert, dass er fünf zustandsorientierte Schreib-Pods unterstützt. Wobei mehrere Schreib-Pods gleichzeitig in dieselbe Datei schreiben. Die Leser-Pods lassen sich auch einfach hochskalieren.

    Optional: Zugriff auf Daten vom Autor-Pod

    In diesem Abschnitt wird gezeigt, wie Sie über eine Befehlszeile auf einen Reader oder einen Schreib-Pod zugreifen. Sie können die gemeinsame Komponente sehen, in die der Autor schreibt und aus der der Leser liest.

    1. Rufen Sie den Namen des Schreib-Pods ab:

      kubectl get pods
      

      Die Ausgabe sieht etwa so aus:

      NAME                      READY   STATUS    RESTARTS   AGE
      writer-5465d65b46-7hxv4   1/1     Running   0          20d
      

      Notieren Sie den Hostnamen eines Schreib-Pods (Beispiel: writer-5465d65b46-7hxv4).

    2. Führen Sie den folgenden Befehl aus, um auf den Schreib-Pod zuzugreifen:

      kubectl exec -it WRITER_HOSTNAME -- /bin/sh
      
    3. Sehen Sie sich die freigegebene Komponente in der Datei indexData.html an:

      cd /html
      cat indexData.html
      
    4. Löschen Sie die Datei indexData.html:

      echo '' > indexData.html
      

      Aktualisieren Sie den Webbrowser, in dem die Adresse EXTERNAL-IP gehostet wird, damit die Änderung angezeigt wird.

    5. Beenden Sie die Umgebung:

      exit
      

    Bereinigen

    Damit Ihrem Google Cloud-Konto die in dieser Anleitung verwendeten Ressourcen nicht in Rechnung gestellt werden, löschen Sie entweder das Projekt, das die Ressourcen enthält, oder Sie behalten das Projekt und löschen die einzelnen Ressourcen.

    Projekt löschen

    1. In the Google Cloud console, go to the Manage resources page.

      Go to Manage resources

    2. In the project list, select the project that you want to delete, and then click Delete.
    3. In the dialog, type the project ID, and then click Shut down to delete the project.

    Einzelne Ressourcen löschen

    1. Löschen Sie den Load-Balancer-Dienst:

      kubectl delete service reader-lb
      

      Warten Sie, bis der für den Lesedienst bereitgestellte Load-Balancer gelöscht wurde.

    2. Prüfen Sie, ob die Liste Listed 0 items zurückgibt:

      gcloud compute forwarding-rules list
      
    3. Löschen Sie die Bereitstellungen

      kubectl delete deployment writer
      kubectl delete deployment reader
      
    4. Prüfen Sie, ob die Pods gelöscht wurden und No resources found in default namespace. zurückgeben.

      kubectl get pods
      
    5. Löschen Sie den PVC. Dadurch werden auch das PV und die Filestore-Instanz aufgrund der auf delete festgelegten Aufbewahrungsrichtlinie gelöscht.

      kubectl delete pvc fileserver
      
    6. Löschen Sie den GKE-Cluster:

      gcloud container clusters delete CLUSTER_NAME --location=CONTROL_PLANE_LOCATION
      

      Dadurch werden die Ressourcen des GKE-Clusters gelöscht, einschließlich der Leser- und Schreib-Pods.

    Nächste Schritte