Ressourcennutzung in einem mandantenfähigen GKE-Cluster mithilfe der automatischen Knotenbereitstellung optimieren


In dieser Anleitung wird gezeigt, wie Sie mithilfe der automatischen Knotenbereitstellung einen mandantenfähigen GKE-Cluster (Google Kubernetes Engine) skalieren und mithilfe von Workload Identity den Mandantenzugriff auf Ressourcen wie Cloud Storage-Buckets steuern. Dieser Leitfaden richtet sich an Entwickler und Architekten und setzt Grundkenntnisse in Kubernetes und GKE voraus. Eine Einführung finden Sie in der Übersicht über GKE.

Die Mehrmandantenfähigkeit von Clustern wird häufig implementiert, um Kosten zu senken oder Vorgänge für Mandanten zu standardisieren. Um das Potenzial für Kosteneinsparungen komplett auszuschöpfen, sollten Sie die Größe Ihres Clusters so anpassen, dass die Clusterressourcen effizient genutzt werden. Außerdem wird empfohlen, Ressourcenverschwendung zu minimieren, wenn für Ihren Cluster das Autoscaling aktiviert ist. Sorgen Sie dafür, dass hinzugefügte Clusterknoten eine geeignete Größe haben.

In dieser Anleitung verwenden Sie die automatische Knotenbereitstellung, um den Cluster zu skalieren. Mit der automatischen Knotenbereitstellung können Sie die Nutzung von Clusterressourcen optimieren und damit Ihre Kosten entsprechend steuern. Dabei werden Clusterknoten hinzugefügt, die optimal für Ihre ausstehenden Arbeitslasten sind.

Ziele

  • Einen GKE-Cluster erstellen, bei dem die automatische Knotenbereitstellung und Workload Identity aktiviert sind
  • Den Cluster für Mandantenfähigkeit einrichten
  • Jobs an den Cluster senden, um zu sehen, wie Knoten optimierter Größen über die automatische Knotenbereitstellung erstellt und gelöscht werden
  • Mithilfe von Markierungen und Labels die automatische Knotenbereitstellung anweisen, separate Knotenpools für jeden Mandanten zu erstellen
  • Workload Identity verwenden, um den Zugriff auf mandantenspezifische Ressourcen wie Cloud Storage-Buckets zu steuern

Kosten

In diesem Dokument verwenden Sie die folgenden kostenpflichtigen Komponenten von Google Cloud:

Mit dem Preisrechner können Sie eine Kostenschätzung für Ihre voraussichtliche Nutzung vornehmen. Neuen Google Cloud-Nutzern steht möglicherweise eine kostenlose Testversion zur Verfügung.

Hinweis

  1. Melden Sie sich bei Ihrem Google Cloud-Konto an. Wenn Sie mit Google Cloud noch nicht vertraut sind, erstellen Sie ein Konto, um die Leistungsfähigkeit unserer Produkte in der Praxis sehen und bewerten zu können. Neukunden erhalten außerdem ein Guthaben von 300 $, um Arbeitslasten auszuführen, zu testen und bereitzustellen.
  2. Wählen Sie in der Google Cloud Console auf der Seite der Projektauswahl ein Google Cloud-Projekt aus oder erstellen Sie eines.

    Zur Projektauswahl

  3. Die Abrechnung für das Google Cloud-Projekt muss aktiviert sein.

  4. Wählen Sie in der Google Cloud Console auf der Seite der Projektauswahl ein Google Cloud-Projekt aus oder erstellen Sie eines.

    Zur Projektauswahl

  5. Die Abrechnung für das Google Cloud-Projekt muss aktiviert sein.

  6. Aktivieren Sie Cloud Shell in der Google Cloud Console.

    Cloud Shell aktivieren

    Unten in der Google Cloud Console wird eine Cloud Shell-Sitzung gestartet und eine Eingabeaufforderung angezeigt. Cloud Shell ist eine Shell-Umgebung, in der das Google Cloud CLI bereits installiert ist und Werte für Ihr aktuelles Projekt bereits festgelegt sind. Das Initialisieren der Sitzung kann einige Sekunden dauern.

  7. Aktivieren Sie in Cloud Shell die APIs für GKE und die Cloud Build API:
    gcloud services enable container.googleapis.com \
        cloudbuild.googleapis.com
    

    Dies kann einige Minuten dauern.

Umgebung vorbereiten

In diesem Abschnitt rufen Sie den Code ab, den Sie für diese Anleitung benötigen, und richten Ihre Umgebung mit Werten ein, die Sie im Verlauf der Anleitung verwenden.

  1. Definieren Sie in Cloud Shell die Umgebungsvariablen für diese Anleitung:

    export PROJECT_ID=$(gcloud config get-value project)
    
  2. Klonen Sie das GitHub-Repository, das den Code für diese Anleitung enthält:

    git clone https://github.com/GoogleCloudPlatform/solutions-gke-autoprovisioning
    
  3. Wechseln Sie in das Repository-Verzeichnis:

    cd solutions-gke-autoprovisioning
    
  4. Aktualisieren Sie die YAML-Jobkonfigurationsdatei für Kubernetes mit Ihrer Google-Projekt-ID:

    sed -i "s/MY_PROJECT/$PROJECT_ID/" manifests/bases/job/base-job.yaml
    
  5. Senden Sie einen Cloud Build-Job, um ein Container-Image zu erstellen:

    gcloud builds submit pi/ --tag gcr.io/$PROJECT_ID/generate-pi
    

    Das Image ist ein Go-Programm, das eine Pi-Näherung generiert. Sie werden dieses Container-Image später verwenden.

    Cloud Build exportiert das Image in die Container Registry Ihres Projekts.

GKE-Cluster erstellen

In diesem Abschnitt erstellen Sie einen GKE-Cluster, für den die automatische Knotenbereitstellung und Workload Identity aktiviert sind. Beachten Sie Folgendes für die Clustererstellung:

  • Sie legen CPU- und Arbeitsspeicherlimits für den Cluster fest. Bei der automatischen Knotenbereitstellung werden diese Limits berücksichtigt, wenn dem Cluster Knoten hinzugefügt oder daraus entfernt werden. Weitere Informationen finden Sie in der GKE-Dokumentation unter Automatische Knotenbereitstellung aktivieren.
  • Sie geben das Standarddienstkonto und die Standardbereiche an, die von den Knoten in den automatisch bereitgestellten Knotenpools verwendet werden. Mit diesen Einstellungen können Sie die Zugriffsberechtigungen des bereitgestellten Knotens steuern. Weitere Informationen finden Sie unter Identitätseinstellungen für automatisch bereitgestellte Knoten festlegen in der GKE-Dokumentation.
  • Sie legen ein Autoscaling-Profil fest, das die Nutzung priorisiert. Mit diesem Profil wird für das Cluster-Autoscaling festgelegt, dass der Cluster schnell herunterskaliert wird, um den Umfang nicht verwendeter Ressourcen zu minimieren. Dies kann die Ressourceneffizienz für Batch- oder joborientierte Arbeitslasten verbessern. Die Einstellung gilt für alle Knotenpools im Cluster.
  • Sie aktivieren Workload Identity, indem Sie den Workloadpool angeben.

So erstellen Sie den Cluster:

  1. Erstellen Sie ein Dienstkonto:

    gcloud iam service-accounts create nap-sa
    

    Dieses Dienstkonto wird von den automatisch bereitgestellten Knoten verwendet.

  2. Gewähren Sie dem neuen Dienstkonto Berechtigungen zum Abrufen von Images aus dem von der Container Registry verwendeten Cloud Storage-Bucket:

    gsutil iam ch \
        serviceAccount:nap-sa@$PROJECT_ID.iam.gserviceaccount.com:objectViewer \
        gs://artifacts.$PROJECT_ID.appspot.com
    
  3. Erstellen Sie einen GKE-Cluster, bei dem die automatische Knotenbereitstellung und die Workloadidentität aktiviert sind:

    gcloud container clusters create multitenant \
        --release-channel=regular \
        --zone=us-central1-c \
        --num-nodes=2 \
        --machine-type=n1-standard-2 \
        --workload-pool=${PROJECT_ID}.svc.id.goog \
        --autoscaling-profile=optimize-utilization \
        --enable-autoprovisioning \
        --autoprovisioning-service-account=nap-sa@${PROJECT_ID}.iam.gserviceaccount.com \
        --autoprovisioning-scopes=\
    https://www.googleapis.com/auth/devstorage.read_write,\
    https://www.googleapis.com/auth/cloud-platform \
        --min-cpu 1 \
        --min-memory 1 \
        --max-cpu 50 \
        --max-memory 256 \
        --enable-network-policy \
        --enable-ip-alias
    
  4. Legen Sie den Standard-Clusternamen und die Computing-Zone fest:

    gcloud config set container/cluster multitenant
    gcloud config set compute/zone us-central1-c
    

Cluster für Mandantenfähigkeit einrichten

Wenn Sie eine mandantenfähige SaaS-Anwendung (Software as a Service) betreiben, sollten Sie Ihre Mandanten normalerweise trennen. Durch die Trennung von Mandanten können Sie Schäden durch einen manipulierten Mandanten minimieren. Außerdem können Sie dadurch Clusterressourcen gleichmäßig auf Mandanten verteilen und die Anzahl der Ressourcen verfolgen, die jeder Mandant verbraucht. Kubernetes kann keine vollständig sichere Isolation zwischen Mandanten gewährleisten, aber es bietet Funktionen, die für bestimmte Anwendungsfälle möglicherweise ausreichend sind. Weitere Informationen zu den Funktionen der GKE-Mehrmandantenfähigkeit finden Sie in der Übersicht und den Best Practices in der GKE-Dokumentation.

In der Beispielanwendung erstellen Sie zwei Mandanten: tenant1 und tenant2. Sie trennen die Mandanten und die zugehörigen Kubernetes-Ressourcen in eigene Namespaces. Sie erstellen eine einfache Netzwerkrichtlinie, die die Mandantentrennung erzwingt und dafür die Kommunikation aus anderen Namespaces verhindert. Später verwenden Sie die Felder Knotenmarkierungen und nodeSelector, um zu verhindern, dass Pods verschiedener Mandanten auf demselben Knoten geplant werden. Sie können die Trennung der Mandanten zusätzlich unterstützen, wenn Sie Mandantenarbeitslasten auf dedizierten Knoten ausführen.

Mit Kustomize verwalten Sie die Kubernetes-Manifeste, die Sie an den Cluster senden. Kustomize bietet die Möglichkeit, YAML-Dateien für verschiedene Zwecke zu kombinieren und anzupassen.

  1. Erstellen Sie einen Namespace, ein Dienstkonto und eine Netzwerkrichtlinienressource für tenant1:

    kubectl apply -k manifests/setup/tenant1
    

    Die Ausgabe sieht so aus:

    namespace/tenant1-ns created
    serviceaccount/tenant1-ksa created
    networkpolicy.networking.k8s.io/tenant1-deny-from-other-namespaces created
    
  2. Erstellen Sie die Clusterressourcen für tenant2:

    kubectl apply -k manifests/setup/tenant2
    

Verhalten der automatischen Knotenbereitstellung prüfen

Ein GKE-Cluster besteht aus einem oder mehreren Knotenpools. Alle Knoten in einem Knotenpool haben denselben Maschinentyp, also dieselbe CPU- und Arbeitsspeicherkapazität. Wenn Ihre Anforderungen an Arbeitslastressourcen variieren, kann es sinnvoll sein, mehrere Knotenpools mit unterschiedlichen Maschinentypen im Cluster bereitzustellen. Auf diese Weise können durch das Cluster-Autoscaling Knoten vom jeweils am besten geeigneten Typ hinzugefügt werden. Dies verbessert die Ressourceneffizienz und senkt somit die Kosten. Die Nutzung vieler Knotenpools erhöht aber auch den Verwaltungsaufwand. Es ist in einem mehrmandantenfähigen Cluster möglicherweise auch nicht sinnvoll, Mandantenarbeitslasten in dedizierten Knotenpools auszuführen.

Stattdessen können Sie die automatische Knotenbereitstellung verwenden, um den Cluster Autoscaler zu erweitern. Wenn die automatische Knotenbereitstellung aktiviert ist, kann der Cluster-Autoscaler neue Knotenpools basierend auf den Spezifikationen ausstehender Pods automatisch erstellen. Der Cluster Autoscaler kann daher Knoten des geeigneten Typs erstellen, ohne die Knotenpools selbst erstellen oder verwalten zu müssen. Mit der automatischen Knotenbereitstellung kann der Cluster effizient ohne Überdimensionierung skalieren, wodurch Sie die Kosten senken können.

Wenn für ausstehende Pods Einschränkungen bei der Arbeitslasttrennung gelten, kann die automatische Knotenbereitstellung außerdem Knoten erstellen, die den Einschränkungen genügen. Dies bietet die Möglichkeit, mit der automatischen Knotenbereitstellung automatisch Knotenpools zu erstellen, die nur von einem einzigen Mandanten verwendet werden.

In diesem Abschnitt senden Sie verschiedene Jobs an den Cluster, um das Verhalten der automatischen Knotenbereitstellung zu prüfen. Die Jobs verwenden das zuvor erstellte Image generate-pi.

Einfachen Job senden

Als Erstes senden Sie einen einfachen Job an den Cluster. Mit dem Job werden keine mandantenspezifischen Einschränkungen definiert. Der Cluster enthält ausreichend freie Kapazitäten für die CPU- und Arbeitsspeicheranforderungen des Jobs. Daher soll der Job in einem der vorhandenen Knoten im Standardknotenpool geplant werden. Es werden keine zusätzlichen Knoten bereitgestellt.

  1. Knotenpools im Cluster auflisten:

    gcloud container node-pools list
    

    Es wird ein einzelner Standardpool angezeigt.

  2. Geben Sie die Konfiguration des Jobs in der Konsole aus:

    kubectl kustomize manifests/jobs/simple-job/
    

    Die Ausgabe sieht so aus:

    apiVersion: batch/v1
    kind: Job
    metadata:
    name: pi-job
    spec:
    ...
    

    In der Konfiguration werden keine Knotenmarkierungen oder -selektoren festgelegt.

  3. Senden Sie den Job:

    kubectl apply -k manifests/jobs/simple-job/
    
  4. Beobachten Sie die Knotenpools im Cluster:

    watch -n 5 gcloud container node-pools list
    

    Es wird weiterhin ein einzelner Standardpool angezeigt. Es wurden keine neuen Knotenpools erstellt.

  5. Drücken Sie nach 30 Sekunden auf Control+C, um die Anzeige der Knotenpools zu beenden.

  6. Beobachten Sie die Knoten im Cluster:

    kubectl get nodes -w
    

    Es wurden keine neuen Knoten erstellt.

  7. Drücken Sie nach einer Minute Control+C, um die Wiedergabe zu beenden.

  8. Listen Sie die Jobs im Cluster auf:

    kubectl get jobs --all-namespaces
    

    Die Ausgabe sieht so aus:

    NAMESPACE   NAME     COMPLETIONS   DURATION   AGE
    default     pi-job   1/1           14s        21m
    

    Der Wert 1/1 in der Spalte Completions gibt an, dass 1 Job von insgesamt 1 Job abgeschlossen wurde.

Job mit mandantenspezifischen Einschränkung senden

In diesem Abschnitt senden Sie einen weiteren Job, um zu prüfen, ob die automatische Knotenbereitstellung die Einschränkungen für die Arbeitslasttrennung einhält. Die Jobkonfiguration enthält einen mandantenspezifischen Knotenselektor und eine mandantenspezifische Toleranz. Der Job kann nur für einen Knoten geplant werden, dessen Labels mit den Schlüssel/Wert-Paaren des Selektors übereinstimmen. Eine Toleranz wird in Verbindung mit Knotenmarkierungen verwendet, die außerdem einschränken, welche Jobs auf einem Knoten geplant werden können. Eine der Best Practices für die automatische Knotenbereitstellung besteht darin, sowohl einen Knotenselektor als auch eine Toleranz für die Trennung der Arbeitslasten anzugeben.

Dieser Job kann nicht im Standardknotenpool geplant werden, da dieser Pool keine Knoten enthält, die die Selektoreinschränkung erfüllen. Daher erstellt die automatische Knotenbereitstellung einen neuen Knotenpool mit Knotenlabels, die die Anforderung des Selektors erfüllen. Die automatische Knotenbereitstellung fügt den Knoten auch eine mandantenspezifische Markierung hinzu, die der Toleranz in der Jobkonfiguration entspricht. Nur Pods mit einer übereinstimmenden Toleranz können auf Knoten im Pool geplant werden. Dadurch lassen sich Arbeitslasten von Mandanten genauer trennen.

  1. Knotenpools im Cluster auflisten:

    gcloud container node-pools list
    

    Es wird ein einzelner Standardpool angezeigt.

  2. Geben Sie die Konfiguration des Jobs in der Konsole aus:

    kubectl kustomize manifests/jobs/one-tenant/
    

    Die Konfiguration umfasst die Anforderung eines mandantenspezifischen Knotenselektors und eine Toleranz. Die Ausgabe sieht so aus:

    apiVersion: batch/v1
    kind: Job
    metadata:
    name: tenant1-pi-job
    spec:
    ...
    
  3. Senden Sie den Job:

    kubectl apply -k manifests/jobs/one-tenant/
    
  4. Beobachten Sie die Knotenpools im Cluster:

    watch -n 5 gcloud container node-pools list
    

    Nach einiger Zeit wird ein neuer Knotenpool angezeigt. Die Ausgabe sieht in etwa so aus:

    NAME                            MACHINE_TYPE       DISK_SIZE_GB
    default-pool                    n1-standard-2      100
    nap-n1-standard-1-15jwludl      n1-standard-1      100
    

    Der Name des Knotenpools erhält das Präfix nap-, das angibt, dass er durch die automatische Knotenbereitstellung erstellt wurde. Der Knotenpoolname enthält auch den Maschinentyp der Knoten im Pool, z. B. n1-standard-1.

  5. Beobachten Sie die Knoten im Cluster:

    kubectl get nodes -w
    

    Nach etwa einer Minute wird ein neuer Knoten in der Liste angezeigt. Der Knotenname enthält den Namen des Knotenpools nap-. Der neue Knoten hat anfangs den Status Not Ready. Nach einiger Zeit ändert sich der Status des neuen Knotens in Ready. Das bedeutet, dass der Knoten jetzt ausstehende Arbeitslasten akzeptiert.

  6. Zum Beenden der Knoten drücken Sie Control+C.

  7. Listen Sie die Knotenmarkierungen auf:

    kubectl get nodes -o custom-columns=NAME:.metadata.name,TAINTS:.spec.taints
    

    Der neue Knoten hat eine NoSchedule-Markierung für das Schlüssel/Wert-Paar tenant: tenant1. Daher können nur Pods, die eine entsprechende Toleranz für tenant: tenant1 haben, auf dem Knoten geplant werden.

  8. Beobachten Sie die Jobs im Cluster:

    kubectl get jobs -w --all-namespaces
    

    Nach einiger Zeit sehen Sie, dass tenant1-pi-job 1/1 Abschluss hat, was darauf hinweist, dass sie erfolgreich abgeschlossen wurde.

  9. Um die Beobachtung der Jobs zu beenden, drücken Sie Control+C.

  10. Beobachten Sie die Knotenpools im Cluster:

    watch -n 5 gcloud container node-pools list
    

    Nach einiger Zeit stellen Sie fest, dass der Pool nap- gelöscht wird und der Cluster wieder nur noch den einzigen Standardknotenpool hat. Der Knotenpool nap- wurde durch die automatische Knotenbereitstellung gelöscht, da keine ausstehenden Aufgaben vorhanden sind, die den Einschränkungen des Pools entsprechen.

  11. Drücken Sie Control+C, um die Beobachtung der Knotenpools zu beenden.

Zwei größere Jobs mit Mandantenbeschränkungen senden

In diesem Abschnitt senden Sie zwei Jobs mit mandantenspezifischen Einschränkungen und erhöhen außerdem die Ressourcenanforderungen für jeden Job. Auch hier können diese Jobs aufgrund der Einschränkungen des Knotenselektors nicht für den Standardknotenpool geplant werden. Da für jeden Job eine eigene Selektoreinschränkung vorhanden ist, werden bei der automatischen Knotenbereitstellung zwei neue Knotenpools erstellt. Auf diese Weise können Sie die automatische Knotenbereitstellung dazu verwenden, um die Mandantenjobs getrennt zu halten. Da die Jobs im Vergleich zum vorherigen Job eine höhere Ressourcenanforderung haben, werden bei der automatischen Knotenbereitstellung Knotenpools erstellt, deren Maschinentypen größer sind als das letzte Mal.

  1. Knotenpools im Cluster auflisten:

    gcloud container node-pools list
    

    Es wird ein einzelner Standardpool angezeigt.

  2. Geben Sie die kombinierte Konfiguration aus:

    kubectl kustomize manifests/jobs/two-tenants/
    

    Die Konfiguration umfasst zwei separate Jobs mit jeweils einem mandantenspezifischen Knotenselektor und einer Toleranz sowie mit erhöhten Ressourcenanforderungen.

    Die Ausgabe sieht so aus:

    apiVersion: batch/v1
    kind: Job
    metadata:
    name: tenant1-larger-pi-job
    spec:
    ...
    
  3. Senden Sie die Jobs:

    kubectl apply -k manifests/jobs/two-tenants/
    
  4. Beobachten Sie die Knotenpools im Cluster:

    watch -n 5 gcloud container node-pools list
    

    Nach einiger Zeit werden zwei zusätzliche Knotenpools angezeigt. Die Ausgabe sieht in etwa so aus:

    NAME                            MACHINE_TYPE       DISK_SIZE_GB
    default-pool                    n1-standard-2      100
    nap-n1-standard-2-6jxjqobt      n1-standard-2      100
    nap-n1-standard-2-z3s06luj      n1-standard-2      100
    

    Die Namen der Knotenpools haben das Präfix nap-. Dieses gibt an, dass sie durch die automatische Knotenbereitstellung erstellt wurden. Die Namen der Knotenpools enthalten auch den Maschinentyp der Knoten im Pool, z. B. n1-standard-2.

  5. Zum Beenden der Knoten drücken Sie Control+C.

  6. Beobachten Sie die Knoten im Cluster:

    kubectl get nodes -w
    

    Nach etwa einer Minute werden zwei neue Knoten in der Liste angezeigt. Die Knotennamen enthalten den Namen des zugehörigen nap--Knotenpools. Die neuen Knoten haben anfangs den Status Not Ready. Nach einiger Zeit ändert sich der Status des neuen Knotens in Ready. Das bedeutet, dass der Knoten jetzt ausstehende Arbeitslasten akzeptiert.

  7. Zum Beenden der Knoten drücken Sie Control+C.

  8. Listen Sie die Knotenmarkierungen auf:

    kubectl get nodes -o custom-columns=NAME:.metadata.name,TAINTS:.spec.taints
    

    Sie sehen, dass die neuen Knoten NoSchedule-Markierungen haben, eine Markierung mit dem Schlüssel/Wert-Paar tenant: tenant1 und eine andere mit tenant: tenant2. Auf den Knoten können nur Pods mit entsprechenden Mandantentoleranzen geplant werden.

  9. Beobachten Sie die Jobs im Cluster:

    kubectl get jobs -w --all-namespaces
    

    Nach einiger Zeit wird für tenant1-larger-pi-job und tenant2-larger-pi-job der Status 1/1 angezeigt, um anzugeben, dass die Jobs erfolgreich abgeschlossen wurden.

  10. Um die Beobachtung der Jobs zu beenden, drücken Sie Control+C.

  11. Beobachten Sie die Knotenpools im Cluster:

    watch -n 5 gcloud container node-pools list
    

    Nach einiger Zeit sehen Sie, dass beide nap--Pools gelöscht werden und der Cluster wieder nur einen einzigen Standardknotenpool hat. Durch die automatische Knotenbereitstellung wurden die nap--Knotenpools gelöscht, da keine ausstehenden Arbeitsaufträge mehr vorhanden sind, die den Pooleinschränkungen entsprechen.

  12. Drücken Sie Control+C, um die Beobachtung der Knotenpools zu beenden.

Zugriff auf Google Cloud-Ressourcen steuern

Zusätzlich zur Trennung der Mandanten in einem Cluster möchten Sie normalerweise auch den Mandantenzugriff auf Google Cloud-Ressourcen wie Cloud Storage-Buckets oder Pub/Sub-Themen steuern. Beispielsweise kann jeder Mandant einen Cloud Storage-Bucket benötigen, der nicht von anderen Mandanten zugänglich sein soll.

Mit Workload Identity können Sie eine Zuordnung zwischen Kubernetes-Dienstkonten und Google Cloud-Dienstkonten erstellen. Anschließend haben Sie die Möglichkeit, dem Google Cloud-Dienstkonto die entsprechenden Rollen für Identity and Access Management (IAM) zuzuweisen. Sie können so das Prinzip der geringsten Berechtigung erzwingen, damit Mandantenjobs auf ihre zugewiesenen Ressourcen zugreifen können, aber nicht auf die Ressourcen, die zu anderen Mandanten gehören.

Richten Sie die GKE-Workloadidentität ein

Konfigurieren Sie die Zuordnung zwischen Ihrem Kubernetes-Dienstkonto und einem von Ihnen erstellten Google Cloud-Dienstkonto.

  1. Erstellen Sie ein Google Cloud-Dienstkonto für tenant1.

    gcloud iam service-accounts create tenant1-gsa
    
  2. Gewähren Sie dem Kubernetes-Dienstkonto für tenant1 IAM-Berechtigungen, um das entsprechende Google Cloud-Dienstkonto für tenant1 zu verwenden:

    gcloud iam service-accounts add-iam-policy-binding \
        tenant1-gsa@${PROJECT_ID}.iam.gserviceaccount.com \
        --role roles/iam.workloadIdentityUser \
        --member "serviceAccount:${PROJECT_ID}.svc.id.goog[tenant1-ns/tenant1-ksa]"
    
  3. Schließen Sie die Zuordnung zwischen den Dienstkonten ab. Annotieren Sie dazu das Kubernetes-Dienstkonto mit dem Google Cloud-Dienstkonto:

    kubectl annotate serviceaccount tenant1-ksa -n tenant1-ns \
        iam.gke.io/gcp-service-account=tenant1-gsa@${PROJECT_ID}.iam.gserviceaccount.com
    

Job senden, der in einen Cloud Storage-Bucket schreibt

In diesem Abschnitt prüfen Sie, ob ein Job, der als ein bestimmtes Kubernetes-Dienstkonto ausgeführt wird, die IAM-Berechtigungen seines zugeordneten Google Cloud-Dienstkontos verwendet.

  1. Erstellen Sie einen neuen Cloud Storage-Bucket für tenant1:

    export BUCKET=tenant1-$PROJECT_ID
    gsutil mb -b on -l us-central1 gs://$BUCKET
    

    Sie verwenden die Projekt-ID als Suffix für den Bucket-Namen, um den Namen eindeutig zu machen.

  2. Aktualisieren Sie die Konfigurationsdatei des Jobs so, dass der Cloud Storage-Bucket verwendet wird:

    sed -i "s/MY_BUCKET/$BUCKET/" \
        manifests/jobs/write-gcs/bucket-write.yaml
    
  3. Gewähren Sie dem Dienstkonto tenant1 Berechtigungen zum Lesen und Schreiben von Objekten im Bucket:

    gsutil iam ch \
        serviceAccount:tenant1-gsa@$PROJECT_ID.iam.gserviceaccount.com:objectAdmin \
        gs://$BUCKET
    
  4. Geben Sie die Jobkonfiguration aus:

    kubectl kustomize manifests/jobs/write-gcs/
    

    Die Ausgabe sieht so aus:

    apiVersion: batch/v1
    kind: Job
    metadata:
    name: tenant1-pi-job-gcs
    spec:
    ...
    

    Der neue Bucket-Name wird als Argument an den Container generate-pi übergeben und der Job legt das entsprechende Kubernetes-Dienstkonto tenant1-ksa fest.

  5. Senden Sie den Job:

    kubectl apply -k manifests/jobs/write-gcs/
    

    Wie im vorherigen Abschnitt erstellt die automatische Knotenbereitstellung einen neuen Knotenpool und einen neuen Knoten, um den Job auszuführen.

  6. Beobachten Sie den Pod des Jobs:

    kubectl get pods -n tenant1-ns -w
    

    In diesem Fall beobachten Sie den Pod und nicht den Knotenpool. Für den Pod-Übergang werden verschiedene Status angegeben. Nach einigen Minuten ändert sich der Status in Completed. Dieser Status zeigt an, dass der Job erfolgreich abgeschlossen wurde.

  7. Drücken Sie Control+C, um die Wiedergabe zu beenden.

  8. Prüfen Sie, ob eine Datei in den Cloud Storage-Bucket geschrieben wurde:

    gsutil ls -l gs://$BUCKET
    

    Es wird eine einzelne Datei angezeigt.

  9. Löschen Sie den Job zur Bereinigung:

    kubectl delete job tenant1-pi-job-gcs -n tenant1-ns
    

    Im nächsten Abschnitt senden Sie diesen Job noch einmal.

IAM-Berechtigungen widerrufen

Abschließend prüfen Sie, ob durch das Widerrufen von IAM-Berechtigungen aus dem Google Cloud-Dienstkonto der Zugriff auf das zugeordnete Kubernetes-Dienstkonto verhindert wird.

  1. Widerrufen Sie für das Google Cloud-Dienstkonto die Berechtigung zum Schreiben in den Cloud Storage-Bucket:

    gsutil iam ch -d \
        serviceAccount:tenant1-gsa@$PROJECT_ID.iam.gserviceaccount.com:objectAdmin \
        gs://$BUCKET
    
  2. Senden Sie den gleichen Job wie zuvor:

    kubectl apply -k manifests/jobs/write-gcs/
    
  3. Hier sehen Sie den Pod-Status des Jobs noch einmal:

    kubectl get pods -n tenant1-ns -w
    

    Nach einigen Minuten ändert sich der Status auf Error, was darauf hinweist, dass der Job fehlgeschlagen ist. Dieser Fehler wird erwartet, da der Job als Kubernetes-Dienstkonto ausgeführt wird, das einem Google Cloud-Dienstkonto zugeordnet ist, das wiederum keine Schreibrechte für den Cloud Storage-Bucket hat.

  4. Wenn Sie den Pod nicht länger beobachten möchten, drücken Sie Control+C.

  5. Listen Sie die Dateien im Bucket auf:

    gsutil ls -l gs://$BUCKET
    

    Es wird eine einzige Datei im Bucket angezeigt, d. h., es wurde keine neue Datei geschrieben.

Bereinigen

Am einfachsten können Sie die Abrechnung deaktivieren, wenn Sie das Google Cloud-Projekt löschen, das Sie für die Anleitung erstellt haben.

Projekt löschen

  1. Wechseln Sie in der Google Cloud Console zur Seite Ressourcen verwalten.

    Zur Seite „Ressourcen verwalten“

  2. Wählen Sie in der Projektliste das Projekt aus, das Sie löschen möchten, und klicken Sie dann auf Löschen.
  3. Geben Sie im Dialogfeld die Projekt-ID ein und klicken Sie auf Shut down (Beenden), um das Projekt zu löschen.

GKE-Cluster löschen

Wenn Sie das Projekt nicht löschen möchten, löschen Sie den GKE-Cluster:

gcloud container clusters delete multitenant

Nächste Schritte