Ottimizzazione dell'utilizzo delle risorse in un cluster GKE multi-tenant mediante il provisioning automatico dei nodi


Questo tutorial mostra come utilizzare il provisioning automatico dei nodi per scalare un cluster multi-tenant Google Kubernetes Engine (GKE) e come utilizzare Workload Identity per controllare l'accesso dei tenant a risorse come i bucket Cloud Storage. Questa guida è rivolta a sviluppatori e architect; si presuppone una conoscenza di base di Kubernetes e GKE. Se ti serve un'introduzione, consulta la panoramica di GKE.

L'architettura multi-tenancy dei cluster viene spesso implementata per ridurre i costi o per standardizzare le operazioni tra i tenant. Per ottenere completamente il risparmio sui costi, devi dimensionare il cluster in modo che le risorse del cluster vengano utilizzate in modo efficiente. Dovresti anche ridurre al minimo lo spreco di risorse quando il cluster viene scalato automaticamente, assicurandoti che i nodi del cluster aggiunti siano di dimensioni appropriate.

In questo tutorial utilizzerai il provisioning automatico dei nodi per scalare il cluster. Il provisioning automatico dei nodi può aiutarti a ottimizzare l'utilizzo delle risorse dei cluster e, di conseguenza, a controllare i costi aggiungendo i nodi cluster più adatti ai carichi di lavoro in attesa.

Obiettivi

  • Crea un cluster GKE in cui sono abilitati il provisioning automatico dei nodi e Workload Identity.
  • Configura il cluster per l'architettura multi-tenancy.
  • Invia job al cluster per dimostrare in che modo il provisioning automatico dei nodi crea ed elimina i nodi di dimensioni ottimizzate.
  • Utilizza incompatibilità ed etichette per indicare al provisioning automatico dei nodi di creare pool di nodi dedicati per ogni tenant.
  • Usa Workload Identity per controllare l'accesso alle risorse specifiche dei tenant, come i bucket Cloud Storage.

Costi

In questo documento vengono utilizzati i seguenti componenti fatturabili di Google Cloud:

Per generare una stima dei costi in base all'utilizzo previsto, utilizza il Calcolatore prezzi. I nuovi utenti di Google Cloud possono essere idonei a una prova senza costi aggiuntivi.

Prima di iniziare

  1. Accedi al tuo account Google Cloud. Se non conosci Google Cloud, crea un account per valutare le prestazioni dei nostri prodotti in scenari reali. I nuovi clienti ricevono anche 300 $di crediti gratuiti per l'esecuzione, il test e il deployment dei carichi di lavoro.
  2. Nella pagina del selettore di progetti della console Google Cloud, seleziona o crea un progetto Google Cloud.

    Vai al selettore progetti

  3. Assicurati che la fatturazione sia attivata per il tuo progetto Google Cloud.

  4. Nella pagina del selettore di progetti della console Google Cloud, seleziona o crea un progetto Google Cloud.

    Vai al selettore progetti

  5. Assicurati che la fatturazione sia attivata per il tuo progetto Google Cloud.

  6. Nella console Google Cloud, attiva Cloud Shell.

    Attiva Cloud Shell

    Nella parte inferiore della console Google Cloud viene avviata una sessione di Cloud Shell che mostra un prompt della riga di comando. Cloud Shell è un ambiente shell con Google Cloud CLI già installato e con valori già impostati per il progetto attuale. L'inizializzazione della sessione può richiedere alcuni secondi.

  7. In Cloud Shell, abilita le API per GKE e l'API Cloud Build:
    gcloud services enable container.googleapis.com \
        cloudbuild.googleapis.com
    

    Il completamento di questa operazione può richiedere alcuni minuti.

Preparazione dell'ambiente

In questa sezione, otterrai il codice necessario per questo tutorial e configurerai il tuo ambiente con i valori che utilizzerai nel tutorial.

  1. In Cloud Shell, definisci le variabili di ambiente da utilizzare per questo tutorial:

    export PROJECT_ID=$(gcloud config get-value project)
    
  2. Clona il repository GitHub che contiene il codice per questo tutorial:

    git clone https://github.com/GoogleCloudPlatform/solutions-gke-autoprovisioning
    
  3. Cambia la directory del repository:

    cd solutions-gke-autoprovisioning
    
  4. Aggiorna il file di configurazione del job YAML Kubernetes con l'ID progetto Google:

    sed -i "s/MY_PROJECT/$PROJECT_ID/" manifests/bases/job/base-job.yaml
    
  5. Invia un job Cloud Build per creare un'immagine container:

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

    L'immagine è un programma Go che genera un'approssimazione di pi greco. Potrai utilizzare questa immagine container in un secondo momento.

    Cloud Build esporta l'immagine nel Container Registry del tuo progetto.

Crea un cluster GKE

In questa sezione creerai un cluster GKE in cui sono abilitati il provisioning automatico dei nodi e l'identità dei carichi di lavoro. Tieni presente i seguenti dettagli del processo di creazione del cluster:

  • Sei tu a specificare i limiti di CPU e memoria per il cluster. Il provisioning automatico dei nodi rispetta questi limiti quando aggiunge o rimuove nodi dal cluster. Per ulteriori informazioni, consulta Abilitazione del provisioning automatico dei nodi nella documentazione di GKE.
  • Sei tu a specificare l'account di servizio predefinito e gli ambiti utilizzati dai nodi all'interno dei pool di nodi di cui è stato eseguito il provisioning automatico. Utilizzando queste impostazioni, puoi controllare le autorizzazioni di accesso del nodo di cui è stato eseguito il provisioning. Per ulteriori informazioni, consulta Configurare i valori predefiniti delle identità per i nodi di cui è stato eseguito il provisioning automatico nella documentazione di GKE.
  • Puoi impostare un profilo di scalabilità automatica che dà la priorità all'utilizzo. Questo profilo indica al gestore della scalabilità automatica dei cluster di fare rapidamente fare lo scale down del cluster per ridurre al minimo le risorse inutilizzate. Ciò può contribuire all'efficienza delle risorse per i carichi di lavoro incentrati sui job o batch. L'impostazione si applica a tutti i pool di nodi nel cluster.
  • Puoi abilitare Workload Identity specificando il pool di carichi di lavoro.

Per creare il cluster:

  1. Crea un account di servizio:

    gcloud iam service-accounts create nap-sa
    

    Questo account di servizio è utilizzato dai nodi di cui è stato eseguito il provisioning automatico.

  2. Concedi al nuovo account di servizio le autorizzazioni per eseguire il pull delle immagini dal bucket Cloud Storage utilizzato da Container Registry:

    gsutil iam ch \
        serviceAccount:nap-sa@$PROJECT_ID.iam.gserviceaccount.com:objectViewer \
        gs://artifacts.$PROJECT_ID.appspot.com
    
  3. Crea un cluster GKE in cui sono abilitati il provisioning automatico dei nodi e l'identità per i carichi di lavoro:

    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. Imposta il nome del cluster e la zona di computing predefiniti:

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

Configurazione del cluster per l'architettura multi-tenancy

Quando gestisci un'app Software-as-a-Service (SaaS) multi-tenant, in genere devi separare i tenant. Separare i tenant può aiutare a ridurre al minimo i danni causati da un tenant compromesso. Inoltre, può aiutarti ad allocare le risorse del cluster in modo uniforme tra i tenant e a tenere traccia del numero di risorse utilizzate da ogni tenant. Kubernetes non può garantire un isolamento perfettamente sicuro tra i tenant, ma offre funzionalità che potrebbero essere sufficienti per casi d'uso specifici. Per ulteriori informazioni sulle funzionalità multi-tenancy di GKE, consulta la panoramica e le guide alle best practice nella documentazione di GKE.

Nell'app di esempio crei due tenant, tenant1 e tenant2. Separa ogni tenant e le relative risorse Kubernetes nel proprio spazio dei nomi. Puoi creare un semplice criterio di rete che applica l'isolamento dei tenant impedendo la comunicazione da altri spazi dei nomi. In seguito, utilizzerai incompatibilità dei nodi e campi nodeSelector per impedire la pianificazione dei pod di tenant diversi sullo stesso nodo. Puoi fornire un ulteriore grado di separazione eseguendo carichi di lavoro dei tenant su nodi dedicati.

Puoi utilizzare Kustomize per gestire i manifest Kubernetes che invii al cluster. Kustomize consente di combinare e personalizzare i file YAML per più scopi.

  1. Crea uno spazio dei nomi, un account di servizio e una risorsa dei criteri di rete per tenant1:

    kubectl apply -k manifests/setup/tenant1
    

    L'output sarà simile al seguente:

    namespace/tenant1-ns created
    serviceaccount/tenant1-ksa created
    networkpolicy.networking.k8s.io/tenant1-deny-from-other-namespaces created
    
  2. Crea le risorse del cluster tenant2:

    kubectl apply -k manifests/setup/tenant2
    

Verifica del comportamento del provisioning automatico dei nodi

Un cluster GKE è costituito da uno o più pool di nodi. Tutti i nodi all'interno di un pool di nodi hanno lo stesso tipo di macchina, il che significa che hanno la stessa quantità di CPU e memoria. Se le esigenze di risorse dei carichi di lavoro sono variabili, potresti trarre vantaggio dall'avere più pool di nodi con tipi di macchine diversi all'interno del cluster. In questo modo, il gestore della scalabilità automatica dei cluster può aggiungere nodi del tipo più adatto, il che può migliorare l'efficienza delle risorse e quindi ridurre i costi. Tuttavia, la gestione di molti pool di nodi comporta un overhead per la gestione. Inoltre, in un cluster multi-tenant potrebbe non essere pratico se vuoi eseguire carichi di lavoro tenant in pool di nodi dedicati.

Puoi invece utilizzare il provisioning automatico dei nodi per estendere il gestore della scalabilità automatica dei cluster. Quando è abilitato il provisioning automatico dei nodi, il gestore della scalabilità automatica dei cluster può creare automaticamente nuovi pool di nodi in base alle specifiche dei pod in attesa. Di conseguenza, il gestore della scalabilità automatica dei cluster può creare nodi del tipo più adatto, ma non devi creare o gestire personalmente i pool di nodi. Grazie al provisioning automatico dei nodi, il tuo cluster può scalare automaticamente in modo efficiente senza eseguire il provisioning eccessivo, con un conseguente abbassamento dei costi.

Inoltre, se i pod in attesa hanno vincoli di separazione dei carichi di lavoro, il provisioning automatico dei nodi può creare nodi che soddisfano i vincoli. In questo modo, puoi utilizzare il provisioning automatico dei nodi per creare automaticamente pool di nodi che verranno utilizzati da un solo tenant.

In questa sezione invierai vari job al cluster per verificare il comportamento del provisioning automatico dei nodi. I job utilizzano l'immagine generate-pi che hai creato in precedenza.

Invia un job semplice

Per prima cosa, invii un job semplice al cluster. Il job non specifica alcun vincolo specifico del tenant. Nel cluster c'è abbastanza capacità di riserva per gestire le richieste di CPU e memoria del job. Di conseguenza, prevedi che il job venga pianificato in uno dei nodi esistenti nel pool di nodi predefinito. Non viene eseguito il provisioning di nodi aggiuntivi.

  1. Elenca i pool di nodi nel cluster:

    gcloud container node-pools list
    

    Vedrai un unico pool predefinito.

  2. Stampa la configurazione del processo nella console:

    kubectl kustomize manifests/jobs/simple-job/
    

    L'output sarà simile al seguente:

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

    La configurazione non specifica incompatibilità dei nodi o selettori.

  3. Invia il job:

    kubectl apply -k manifests/jobs/simple-job/
    
  4. Controlla i pool di nodi nel cluster:

    watch -n 5 gcloud container node-pools list
    

    Visualizzerai comunque un unico pool predefinito. Non viene creato un nuovo pool di nodi.

  5. Dopo circa 30 secondi, premi Control+C per interrompere la visualizzazione dei pool di nodi.

  6. Controlla i nodi nel cluster:

    kubectl get nodes -w
    

    Non vedi la creazione di nuovi nodi.

  7. Dopo 1 minuto, premi Control+C per interrompere la visione.

  8. Elenca i job nel cluster:

    kubectl get jobs --all-namespaces
    

    L'output sarà simile al seguente:

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

    Il valore 1/1 nella colonna Completions indica che è stato completato 1 job su un totale di 1.

Invia un job con vincoli specifici per il tenant

In questa sezione, invierai un altro job per confermare che il provisioning automatico dei nodi ometta i vincoli di separazione dei carichi di lavoro. La configurazione del job include un selettore di nodi specifico per il tenant e una tollerazione specifica per il tenant. Il job può essere pianificato solo su un nodo con etichette che corrispondono alle coppie chiave-valore del selettore. Una tolleranza funziona in combinazione con le incompatibilità dei nodi, che limitano anche i job che possono essere pianificati su un nodo. Una best practice per il provisioning automatico dei nodi prevede l'inclusione di un selettore di nodi e di una tolleranza per la separazione del carico di lavoro.

Questo job non può essere pianificato nel pool di nodi predefinito, perché questo pool non ha nodi che soddisfano il vincolo del selettore. Di conseguenza, il provisioning automatico dei nodi crea un nuovo pool di nodi con etichette dei nodi che soddisfano il requisito del selettore. Il provisioning automatico dei nodi aggiunge anche un'incompatibilità specifica per il tenant ai nodi che corrispondono alla tolleranza nella configurazione del job. Solo i pod con una tolleranza corrispondente possono essere pianificati sui nodi nel pool, in modo da separare ulteriormente i carichi di lavoro dei tenant.

  1. Elenca i pool di nodi nel cluster:

    gcloud container node-pools list
    

    Vedrai un unico pool predefinito.

  2. Stampa la configurazione del processo nella console:

    kubectl kustomize manifests/jobs/one-tenant/
    

    La configurazione include un requisito del selettore dei nodi specifico per il tenant e una tolleranza. L'output sarà simile al seguente:

    apiVersion: batch/v1
    kind: Job
    metadata:
    name: tenant1-pi-job
    spec:
    ...
    
  3. Invia il job:

    kubectl apply -k manifests/jobs/one-tenant/
    
  4. Controlla i pool di nodi nel cluster:

    watch -n 5 gcloud container node-pools list
    

    Dopo un po' di tempo, vedrai un nuovo pool di nodi. L'output ha il seguente aspetto:

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

    Il nome del pool di nodi è preceduto dal prefisso nap-, per indicare che è stato creato dal provisioning automatico dei nodi. Il nome del pool di nodi include anche il tipo di macchina dei nodi nel pool, ad esempio n1-standard-1.

  5. Controlla i nodi nel cluster:

    kubectl get nodes -w
    

    Dopo circa un minuto, viene visualizzato un nuovo nodo nell'elenco. Il nome del nodo include il nome del pool di nodi nap-. Il nuovo nodo ha inizialmente uno stato Not Ready. Dopo un po' di tempo, lo stato del nuovo nodo diventa Ready, il che significa che il nodo può accettare il lavoro in sospeso.

  6. Per interrompere la visualizzazione dei nodi, premi Control+C.

  7. Elenca le incompatibilità dei nodi:

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

    Vedi che il nuovo nodo ha un'incompatibilità NoSchedule per la coppia chiave-valore tenant: tenant1. Di conseguenza, solo i pod che hanno una tolleranza corrispondente a tenant: tenant1 possono essere pianificati sul nodo.

  8. Controlla i job nel cluster:

    kubectl get jobs -w --all-namespaces
    

    Dopo un po' di tempo, vedrai che tenant1-pi-job ha un completamento 1/1, che indica che è stato completato correttamente.

  9. Per interrompere la visualizzazione dei job, premi Control+C.

  10. Controlla i pool di nodi nel cluster:

    watch -n 5 gcloud container node-pools list
    

    Dopo un po' di tempo, vedrai che il pool nap- è stato eliminato e che il cluster ha di nuovo solo il singolo pool di nodi predefinito. Il provisioning automatico dei nodi ha eliminato il pool di nodi nap-, perché non è presente altro lavoro in attesa corrispondente ai vincoli del pool.

  11. Per interrompere l'osservazione dei pool di nodi, premi Control+C.

Inviare due job più grandi con vincoli tenant

In questa sezione invierai due job con vincoli specifici per i tenant e aumenterai anche le richieste di risorse per ogni job. Ancora una volta, questi job non possono essere pianificati nel pool di nodi predefinito a causa dei vincoli del selettore di nodi. Poiché ogni job ha il proprio vincolo del selettore, il provisioning automatico dei nodi crea due nuovi pool di nodi. In questo modo, puoi utilizzare il provisioning automatico dei nodi per mantenere separati i job tenant. Poiché i job hanno un numero maggiore di richieste di risorse rispetto al job precedente, il provisioning automatico dei nodi crea pool di nodi con tipi di macchine più grandi rispetto all'ultima volta.

  1. Elenca i pool di nodi nel cluster:

    gcloud container node-pools list
    

    Vedrai un unico pool predefinito.

  2. Stampa la configurazione combinata:

    kubectl kustomize manifests/jobs/two-tenants/
    

    La configurazione include due job separati, ciascuno con un selettore e una tolleranza specifici del tenant e con un numero maggiore di richieste di risorse.

    L'output sarà simile al seguente:

    apiVersion: batch/v1
    kind: Job
    metadata:
    name: tenant1-larger-pi-job
    spec:
    ...
    
  3. Invia i job:

    kubectl apply -k manifests/jobs/two-tenants/
    
  4. Controlla i pool di nodi nel cluster:

    watch -n 5 gcloud container node-pools list
    

    Dopo un po' di tempo, vengono visualizzati altri due pool di nodi. L'output è simile al seguente:

    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
    

    I nomi dei pool di nodi sono preceduti dal prefisso nap-, per indicare che sono stati creati mediante il provisioning automatico dei nodi. I nomi dei pool di nodi includono anche il tipo di macchina dei nodi nel pool, ad esempio n1-standard-2.

  5. Per interrompere la visualizzazione dei nodi, premi Control+C.

  6. Controlla i nodi nel cluster:

    kubectl get nodes -w
    

    Dopo circa un minuto, vengono visualizzati due nuovi nodi nell'elenco. I nomi dei nodi includono il nome del pool di nodi nap- associato. Inizialmente, i nuovi nodi hanno lo stato Not Ready. Dopo un po' di tempo, lo stato dei nuovi nodi cambia in Ready, il che significa che i nodi possono ora accettare operazioni in sospeso.

  7. Per interrompere la visualizzazione dei nodi, premi Control+C.

  8. Elenca le incompatibilità dei nodi:

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

    Vedrai che i nuovi nodi hanno NoSchedule incompatibilità, una con la coppia chiave-valore tenant: tenant1 e l'altra con tenant: tenant2. Solo i pod con tolleranze dei tenant corrispondenti possono essere pianificati.

  9. Controlla i job nel cluster:

    kubectl get jobs -w --all-namespaces
    

    Dopo un po' di tempo, vedrai che tenant1-larger-pi-job e tenant2-larger-pi-job cambiano in modo da completare 1/1 ciascuno, il che indica che i job sono stati completati correttamente.

  10. Per interrompere la visualizzazione dei job, premi Control+C.

  11. Controlla i pool di nodi nel cluster:

    watch -n 5 gcloud container node-pools list
    

    Dopo un po' di tempo, vedrai che entrambi i pool nap- vengono eliminati e che il cluster ha di nuovo un unico pool di nodi predefinito. Il provisioning automatico dei nodi ha eliminato nap- pool di nodi, perché non è presente altro lavoro in attesa corrispondente ai vincoli dei pool.

  12. Per interrompere l'osservazione dei pool di nodi, premi Control+C.

Controllo dell'accesso alle risorse Google Cloud

Oltre a mantenere la separazione dei tenant all'interno del cluster, in genere è consigliabile controllare l'accesso dei tenant alle risorse Google Cloud, come i bucket Cloud Storage o gli argomenti Pub/Sub. Ad esempio, ogni tenant potrebbe richiedere un bucket Cloud Storage che non dovrebbe essere accessibile da altri tenant.

Con Workload Identity puoi creare un mapping tra gli account di servizio Kubernetes e gli account di servizio Google Cloud. Successivamente potrai assegnare i ruoli Identity and Access Management (IAM) appropriati all'account di servizio Google Cloud. In questo modo puoi applicare il principio del privilegio minimo in modo che i job tenant possano accedere alle risorse assegnate, ma non possano accedere alle risorse di proprietà di altri tenant.

Configura GKE Workload Identity

Configura la mappatura tra il tuo account di servizio Kubernetes e un account di servizio Google Cloud creato da te.

  1. Crea un account di servizio Google Cloud per tenant1:

    gcloud iam service-accounts create tenant1-gsa
    
  2. Concedi all'account di servizio Kubernetes le autorizzazioni IAM di tenant1 per utilizzare l'account di servizio Google Cloud corrispondente per tenant1:

    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. Completa la mappatura tra gli account di servizio annotando l'account di servizio Kubernetes con l'account di servizio Google Cloud:

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

Invia un job che scrive in un bucket Cloud Storage

In questa sezione confermi che un job in esecuzione come un particolare account di servizio Kubernetes può utilizzare le autorizzazioni IAM dell'account di servizio Google Cloud mappato.

  1. Crea un nuovo bucket Cloud Storage per tenant1:

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

    Utilizza l'ID progetto come suffisso sul nome del bucket per renderlo univoco.

  2. Aggiorna il file di configurazione del job in modo da utilizzare il bucket Cloud Storage:

    sed -i "s/MY_BUCKET/$BUCKET/" \
        manifests/jobs/write-gcs/bucket-write.yaml
    
  3. Concedi all'account di servizio tenant1 le autorizzazioni di lettura e scrittura di oggetti nel bucket:

    gsutil iam ch \
        serviceAccount:tenant1-gsa@$PROJECT_ID.iam.gserviceaccount.com:objectAdmin \
        gs://$BUCKET
    
  4. Stampa la configurazione del processo:

    kubectl kustomize manifests/jobs/write-gcs/
    

    L'output sarà simile al seguente:

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

    Il nome del nuovo bucket viene passato come argomento al container generate-pi e il job specifica l'account di servizio Kubernetes tenant1-ksa appropriato.

  5. Invia il job:

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

    Come nella sezione precedente, il provisioning automatico dei nodi crea un nuovo pool di nodi e un nuovo nodo per eseguire il job.

  6. Guarda il pod del job:

    kubectl get pods -n tenant1-ns -w
    

    In questo caso, controlli il pod anziché il pool di nodi. Vedrai la transizione del pod in diversi stati. Dopo un paio di minuti, lo stato diventa Completed. Questo stato indica che il job è stato completato correttamente.

  7. Per interrompere la visione, premi Control+C.

  8. Verifica che un file sia stato scritto nel bucket Cloud Storage:

    gsutil ls -l gs://$BUCKET
    

    Viene visualizzato un solo file.

  9. Per eseguire la pulizia, elimina il job:

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

    Dovrai inviare di nuovo questo job nella sezione successiva.

Revoca autorizzazioni IAM

Infine, confermi che la revoca delle autorizzazioni IAM dall'account di servizio Google Cloud impedisce all'account di servizio Kubernetes mappato di accedere al bucket Cloud Storage.

  1. Revoca le autorizzazioni dell'account di servizio Google Cloud per scrivere nel bucket Cloud Storage:

    gsutil iam ch -d \
        serviceAccount:tenant1-gsa@$PROJECT_ID.iam.gserviceaccount.com:objectAdmin \
        gs://$BUCKET
    
  2. Invia lo stesso lavoro di prima:

    kubectl apply -k manifests/jobs/write-gcs/
    
  3. Controlla di nuovo lo stato del pod del job:

    kubectl get pods -n tenant1-ns -w
    

    Dopo un paio di minuti, lo stato cambia in Error, a indicare che il job non è riuscito. Questo errore è previsto perché il job viene eseguito come account di servizio Kubernetes mappato a un account di servizio Google Cloud che a sua volta non dispone più delle autorizzazioni di scrittura per il bucket Cloud Storage.

  4. Per interrompere la visualizzazione del pod, premi Control+C.

  5. Elenca i file contenuti nel bucket:

    gsutil ls -l gs://$BUCKET
    

    Nel bucket è presente un solo file; non è stato scritto nessun nuovo file.

Esegui la pulizia

Il modo più semplice per eliminare la fatturazione è eliminare il progetto Google Cloud che hai creato per il tutorial.

Elimina il progetto

  1. Nella console Google Cloud, vai alla pagina Gestisci risorse.

    Vai a Gestisci risorse

  2. Nell'elenco dei progetti, seleziona il progetto che vuoi eliminare, quindi fai clic su Elimina.
  3. Nella finestra di dialogo, digita l'ID del progetto e fai clic su Chiudi per eliminare il progetto.

Elimina il cluster GKE

Se non vuoi eliminare il progetto, elimina il cluster GKE:

gcloud container clusters delete multitenant

Passaggi successivi