Optimiser l'utilisation des ressources dans un cluster GKE mutualisé à l'aide du provisionnement automatique des nœuds


Ce tutoriel explique comment effectuer le scaling d'un cluster mutualisé Google Kubernetes Engine (GKE) à l'aide du provisionnement automatique des noeuds et comment utiliser Workload Identity pour contrôler l'accès des locataires à des ressources telles que les buckets Cloud Storage. Ce tutoriel, destiné aux développeurs et aux architectes, suppose que vous connaissez déjà les concepts de base de Kubernetes et de GKE. Si vous avez besoin d'une introduction, consultez la page Présentation de GKE.

L'architecture de cluster mutualisé est souvent mise en œuvre pour réduire les coûts ou standardiser les opérations sur tous les locataires. Pour optimiser la réduction des coûts, vous devez dimensionner votre cluster afin que ses ressources soient utilisées efficacement. Vous devez également minimiser le gaspillage de ressources lors de l'autoscaling de votre cluster en vous assurant que les nœuds de cluster ajoutés ont une taille appropriée.

Dans ce tutoriel, vous allez redimensionner le cluster en utilisant le provisionnement automatique des nœuds. En ajoutant au cluster des nœuds qui correspondent parfaitement aux charges de travail en attente, le provisionnement automatique des nœuds peut vous aider à optimiser l'utilisation des ressources de votre cluster et, par conséquent, à contrôler les coûts.

Objectifs

  • Créer un cluster GKE dans lequel le provisionnement automatique des nœuds et la fonctionnalité Workload Identity sont activés.
  • Configurer le cluster pour l'architecture mutualisée.
  • Envoyer des tâches au cluster pour observer comment le provisionnement automatique des nœuds crée des nœuds de taille optimale, puis les détruit.
  • Utiliser les rejets et les libellés pour demander au provisionnement automatique des nœuds de créer des pools de nœuds dédiés pour chaque locataire.
  • Utiliser Workload Identity pour contrôler l'accès à des ressources spécifiques au locataire, telles que des buckets Cloud Storage.

Coûts

Dans ce document, vous utilisez les composants facturables suivants de Google Cloud :

Obtenez une estimation des coûts en fonction de votre utilisation prévue à l'aide du simulateur de coût. Les nouveaux utilisateurs de Google Cloud peuvent bénéficier d'un essai gratuit.

Avant de commencer

  1. Connectez-vous à votre compte Google Cloud. Si vous débutez sur Google Cloud, créez un compte pour évaluer les performances de nos produits en conditions réelles. Les nouveaux clients bénéficient également de 300 $ de crédits gratuits pour exécuter, tester et déployer des charges de travail.
  2. Dans Google Cloud Console, sur la page de sélection du projet, sélectionnez ou créez un projet Google Cloud.

    Accéder au sélecteur de projet

  3. Vérifiez que la facturation est activée pour votre projet Google Cloud.

  4. Dans Google Cloud Console, sur la page de sélection du projet, sélectionnez ou créez un projet Google Cloud.

    Accéder au sélecteur de projet

  5. Vérifiez que la facturation est activée pour votre projet Google Cloud.

  6. Dans la console Google Cloud, activez Cloud Shell.

    Activer Cloud Shell

    En bas de la fenêtre de la console Google Cloud, une session Cloud Shell démarre et affiche une invite de ligne de commande. Cloud Shell est un environnement shell dans lequel Google Cloud CLI est déjà installé, et dans lequel des valeurs sont déjà définies pour votre projet actuel. L'initialisation de la session peut prendre quelques secondes.

  7. Dans Cloud Shell, activez les API pour GKE et Cloud Build :
    gcloud services enable container.googleapis.com \
        cloudbuild.googleapis.com
    

    Cette opération peut durer quelques minutes :

Préparer l'environnement

Dans cette section, vous récupérez le code dont vous avez besoin pour ce tutoriel et configurez l'environnement avec les valeurs que vous utiliserez tout au long de ce tutoriel.

  1. Dans Cloud Shell, définissez les variables d'environnement que vous utiliserez dans ce tutoriel :

    export PROJECT_ID=$(gcloud config get-value project)
    
  2. Clonez le dépôt GitHub contenant le code du tutoriel :

    git clone https://github.com/GoogleCloudPlatform/solutions-gke-autoprovisioning
    
  3. Passez au répertoire du dépôt :

    cd solutions-gke-autoprovisioning
    
  4. Mettez à jour le fichier de configuration de la tâche YAML Kubernetes avec l'identifiant de votre projet Google :

    sed -i "s/MY_PROJECT/$PROJECT_ID/" manifests/bases/job/base-job.yaml
    
  5. Envoyez une tâche Cloud Build pour créer une image de conteneur :

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

    L'image est un programme Go qui génère une approximation de Pi. Cette image sera utilisée plus loin dans le tutoriel.

    Cloud Build exporte l'image vers le dépôt Container Registry de votre projet.

Créer un cluster GKE

Dans cette section, vous créez un cluster GKE dans lequel le provisionnement automatique des nœuds et Workload Identity sont activés. Les caractéristiques essentielles du processus de création du cluster sont les suivantes :

  • Vous spécifiez des limites de processeur et de mémoire pour le cluster. Le provisionnement automatique des nœuds respecte ces limites lors de l'ajout ou de la suppression de nœuds du cluster. Pour en savoir plus, consultez la page Activer le provisionnement automatique des nœuds dans la documentation GKE.
  • Vous spécifiez le compte de service par défaut et les niveaux d'accès des nœuds au sein des pools de nœuds provisionnés automatiquement. Ces paramètres permettent de contrôler les autorisations d'accès des nœuds provisionnés. Pour en savoir plus, consultez la section Définir les paramètres d'identité par défaut pour les nœuds provisionnés automatiquement dans la documentation GKE.
  • Vous définissez un profil d'autoscaling qui optimise l'utilisation. Ce profil indique à l'autoscaler du cluster d'effectuer rapidement un scaling à la baisse afin de minimiser les ressources inutilisées. Cela peut contribuer à améliorer l'efficacité des ressources pour les charges de travail par lot ou par tâche. Le paramètre s'applique à tous les pools de nœuds du cluster.
  • Vous activez Workload Identity en spécifiant le pool de charges de travail.

Pour créer le cluster :

  1. Créez un compte de service :

    gcloud iam service-accounts create nap-sa
    

    Ce compte de service est utilisé par les nœuds provisionnés automatiquement.

  2. Accordez à ce compte de service les autorisations nécessaires pour extraire des images du bucket Cloud Storage utilisé par Container Registry :

    gsutil iam ch \
        serviceAccount:nap-sa@$PROJECT_ID.iam.gserviceaccount.com:objectViewer \
        gs://artifacts.$PROJECT_ID.appspot.com
    
  3. Créez un cluster GKE dans lequel le provisionnement automatique des nœuds et Workload Identity sont activés :

    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. Définissez le nom du cluster et la zone de calcul par défaut :

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

Configurer le cluster pour l'architecture mutualisée

Lorsque vous gérez une application SaaS (Software as a Service) mutualisée, vous devez généralement isoler les locataires les uns des autres. L'isolation des locataires peut contribuer à contenir les dommages qu'un locataire peut causer. Elle peut également vous aider à allouer les ressources de cluster de manière homogène entre les locataires, et à effectuer un suivi de la quantité de ressources consommées par chaque locataire. Kubernetes ne peut pas garantir une isolation parfaitement sécurisée entre les locataires, mais offre des fonctionnalités qui peuvent suffire dans certains cas d'utilisation. Pour plus d'informations sur les fonctionnalités de l'architecture mutualisée de GKE, consultez les guides de présentation et de bonnes pratiques dans la documentation GKE.

Dans l'exemple d'application, créez deux locataire, tenant1 et tenant2. Dissociez ensuite chacun des locataires et ses ressources Kubernetes dans son propre espace de noms. Créez une règle de réseau simple qui applique l'isolation du locataire en empêchant la communication à partir d'autres espaces noms. Ensuite, utilisez des rejets de nœuds et des champs nodeSelector pour empêcher de programmer sur le même nœud des pods de locataires différents. Vous pouvez appliquer un degré de dissociation supplémentaire en exécutant des charges de travail locataire sur des nœuds dédiés.

Vous utilisez Kustomize pour gérer les fichiers manifeste Kubernetes que vous envoyez au cluster. Kustomize permet de combiner et de personnaliser les fichiers YAML à différentes fins.

  1. Créez un espace de noms, un compte de service et une ressource de règle de réseau pour le locataire tenant1 :

    kubectl apply -k manifests/setup/tenant1
    

    La sortie ressemble à ceci :

    namespace/tenant1-ns created
    serviceaccount/tenant1-ksa created
    networkpolicy.networking.k8s.io/tenant1-deny-from-other-namespaces created
    
  2. Créez les ressources de cluster pour le locataire tenant2 :

    kubectl apply -k manifests/setup/tenant2
    

Vérifier le comportement du provisionnement automatique des nœuds

Un cluster GKE est constitué d'un ou de plusieurs pools de nœuds. Tous les nœuds d'un pool disposent du même type de machine, ce qui signifie qu'ils bénéficient de la même quantité de ressources processeur et de mémoire. Si les besoins en ressources de votre charge de travail sont variables, il pourrait s'avérer judicieux de créer plusieurs pools de nœuds ayant des types de machines différents dans votre cluster. De cette manière, l'autoscaler du cluster peut ajouter des nœuds du type le plus approprié, ce qui peut améliorer l'efficacité de vos ressources et réduire ainsi les coûts. Toutefois, le fait de conserver plusieurs pools de nœuds génère des frais de gestion supplémentaires. Dans un cluster mutualisé, cette approche peut également s'avérer pratique si vous souhaitez exécuter des charges de travail locataires dans des pools de nœuds dédiés.

C'est pourquoi il est souvent préférable d'utiliser le provisionnement automatique des nœuds pour étendre l'autoscaler de cluster. Lorsque le provisionnement automatique des nœuds est activé, l'autoscaler de cluster peut créer automatiquement de nouveaux pools de nœuds en fonction des spécifications des pods en attente. Par conséquent, l'autoscaler de cluster peut créer des nœuds du type le plus approprié, sans que vous ayez à créer ni à gérer les pools de nœuds vous-même. Grâce au provisionnement automatique des nœuds, votre cluster peut effectuer un autoscaling efficace sans surprovisionner, ce qui peut contribuer à réduire vos coûts.

De plus, si les pods en attente ont des contraintes de séparation des charges de travail, le provisionnement automatique des nœuds peut créer des nœuds qui respectent ces contraintes. Ainsi, vous pouvez utiliser le provisionnement automatique des nœuds pour créer automatiquement des pools de nœuds qui ne seront utilisés que par un seul locataire.

Dans cette section, vous allez envoyer différentes tâches au cluster pour vérifier le comportement du provisionnement automatique des nœuds. Les tâches utilisent l'image generate-pi que vous avez créée précédemment.

Envoyer une tâche simple

Pour commencer, envoyez une tâche simple au cluster. La tâche ne spécifie aucune contrainte particulière au locataire. La capacité du disque est suffisante pour gérer les demandes de ressources mémoire et processeur de la tâche. Par conséquent, vous pouvez vous attendre à ce que la tâche soit planifiée dans l'un des nœuds existants du pool par défaut. Aucun nœud supplémentaire n'est provisionné.

  1. Répertoriez les pools de nœuds du cluster :

    gcloud container node-pools list
    

    Seul le pool par défaut s'affiche.

  2. Affichez la configuration de la tâche sur la console :

    kubectl kustomize manifests/jobs/simple-job/
    

    La sortie ressemble à ceci :

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

    La configuration ne spécifie ni rejets ni sélecteurs de nœuds.

  3. Envoyez la tâche :

    kubectl apply -k manifests/jobs/simple-job/
    
  4. Surveillez les pools de nœuds du cluster :

    watch -n 5 gcloud container node-pools list
    

    Seul le pool par défaut s'affiche, comme auparavant. Aucun autre pool de nœuds n'est créé.

  5. Après environ 30 secondes, appuyez sur Control+C pour arrêter de surveiller les pools de nœuds.

  6. Surveillez les nœuds du cluster :

    kubectl get nodes -w
    

    Aucun autre nœud n'est créé.

  7. Après une minute, appuyez sur Control+C pour arrêter de surveiller les nœuds.

  8. Répertoriez les tâches dans le cluster :

    kubectl get jobs --all-namespaces
    

    La sortie ressemble à ceci :

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

    La valeur 1/1 dans la colonne Completions indique qu'il n'y avait qu'une tâche à exécuter et qu'elle est terminée.

Envoyer une tâche comprenant des contraintes sur les locataires

Dans cette section, vous envoyez une autre tâche pour vérifier que le provisionnement automatique des nœuds respecte les contraintes de séparation des charges de travail. La configuration de la tâche comprend un sélecteur de nœuds et une tolérance spécifiques au locataire. La tâche ne peut être planifiée que sur un nœud portant des libellés qui correspondent aux paires clé/valeur du sélecteur. La tolérance fonctionne conjointement avec les rejets de nœuds, ce qui limite également les tâches pouvant être planifiées sur les nœuds. Afin d'assurer la séparation des charges de travail, il est recommandé de spécifier à la fois un sélecteur de nœuds et une tolérance pour le provisionnement automatique des nœuds.

La tâche ne peut pas être planifiée dans le pool de nœuds par défaut, car ce pool ne comporte aucun nœud répondant à la contrainte du sélecteur. Par conséquent, le provisionnement automatique des nœuds crée un nouveau pool de nœuds portant les libellés qui répondent aux exigences du sélecteur. Le provisionnement automatique des nœuds ajoute également un rejet spécifique au locataire sur les nœuds qui correspondent à la tolérance définie dans la configuration de la tâche. Seuls les pods ayant une tolérance qui correspond peuvent être planifiés sur les nœuds du pool, ce qui permet de mieux séparer les charges de travail des locataires.

  1. Répertoriez les pools de nœuds du cluster :

    gcloud container node-pools list
    

    Seul le pool par défaut s'affiche.

  2. Affichez la configuration de la tâche sur la console :

    kubectl kustomize manifests/jobs/one-tenant/
    

    La configuration comprend une exigence de sélecteur de nœud spécifique au locataire et une tolérance. La sortie ressemble à ceci :

    apiVersion: batch/v1
    kind: Job
    metadata:
    name: tenant1-pi-job
    spec:
    ...
    
  3. Envoyez la tâche :

    kubectl apply -k manifests/jobs/one-tenant/
    
  4. Surveillez les pools de nœuds du cluster :

    watch -n 5 gcloud container node-pools list
    

    Après quelques instants, vous verrez apparaître un nouveau pool de nœuds. La sortie ressemble à ceci :

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

    Le nom du pool de nœuds commence par nap-, ce qui indique qu'il a été créé par le provisionnement automatique des nœuds. Le nom du pool de nœuds inclut également le type de machine des nœuds du pool, en l'occurrence n1-standard-1.

  5. Surveillez les nœuds du cluster :

    kubectl get nodes -w
    

    Au bout d'une minute environ, un nouveau nœud apparaît dans la liste. Le nom du nœud inclut le nom du pool nap-. Le nouveau nœud est à l'état Not Ready lorsqu'il vient d'être créé. Au bout de quelques minutes, il passe à l'état Ready, ce qui signifie qu'il peut accepter des tâches en attente.

  6. Pour arrêter de surveiller les pools, appuyez sur Control+C.

  7. Répertoriez les rejets de nœuds :

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

    Le résultat indique que le nouveau nœud comporte un rejet NoSchedule pour la paire valeur/clé tenant: tenant1. Par conséquent, seuls les pods dont la tolérance correspond à tenant: tenant1 peuvent être planifiés sur ce nœud.

  8. Surveillez les tâches dans le cluster :

    kubectl get jobs -w --all-namespaces
    

    Au bout de quelques minutes, la colonne "Completions" de la tâche tenant1-pi-job prend la valeur 1/1, ce qui indique qu'elle a bien été exécutée.

  9. Pour arrêter la surveillance des tâches, appuyez sur Control+C.

  10. Surveillez les pools de nœuds du cluster :

    watch -n 5 gcloud container node-pools list
    

    Au bout de quelques minutes, le pool nap- est supprimé, et il ne reste plus dans le cluster que le pool de nœuds par défaut. Le provisionnement automatique des nœuds a supprimé le pool de nœuds nap-, car il n'y a plus de tâche en attente correspondant aux contraintes du pool.

  11. Pour arrêter la surveillance des pools de nœuds, appuyez sur Control+C.

Envoyer deux tâches plus volumineuses comprenant des contraintes sur les locataires

Dans cette section, vous envoyez deux tâches avec des contraintes spécifiques aux locataires, et vous augmentez également les demandes en ressources pour chaque tâche. De même que précédemment, ces tâches ne peuvent pas être planifiées dans le pool de nœuds par défaut en raison des contraintes du sélecteur de nœuds. Étant donné que chaque tâche comprend sa propre contrainte de sélecteur, le provisionnement automatique des nœuds crée deux nouveaux pools de nœuds. De cette manière, vous pouvez utiliser le provisionnement automatique des nœuds pour assurer la séparation des tâches en fonction des locataires. Comme les tâches exigent plus de ressources que la tâche de la section précédente, le provisionnement automatique des nœuds crée des pools de nœuds basés sur des types de machines plus puissants.

  1. Répertoriez les pools de nœuds du cluster :

    gcloud container node-pools list
    

    Seul le pool par défaut s'affiche.

  2. Affichez la configuration d'ensemble :

    kubectl kustomize manifests/jobs/two-tenants/
    

    La configuration comprend deux tâches distinctes, chacune comprenant un sélecteur de nœud et une tolérance spécifiques pour un locataire, ainsi qu'une demande plus importante en ressources.

    La sortie ressemble à ceci :

    apiVersion: batch/v1
    kind: Job
    metadata:
    name: tenant1-larger-pi-job
    spec:
    ...
    
  3. Envoyez les tâches :

    kubectl apply -k manifests/jobs/two-tenants/
    
  4. Surveillez les pools de nœuds du cluster :

    watch -n 5 gcloud container node-pools list
    

    Au bout de quelques instants, deux pools de nœuds supplémentaires s'affichent. La sortie ressemble à ceci :

    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
    

    Les noms des pools de nœuds sont précédés de nap-, ce qui indique qu'ils ont été créés par le provisionnement automatique des nœuds. Les noms des pools de nœuds incluent également le type de machine des nœuds du pool, en l'occurrence n1-standard-2.

  5. Pour arrêter de surveiller les pools, appuyez sur Control+C.

  6. Surveillez les nœuds du cluster :

    kubectl get nodes -w
    

    Après environ une minute, deux nouveaux nœuds s'affichent dans la liste. Les noms de ces nœuds incluent le nom du pool de nœuds nap- associé. Les nouveaux nœuds présentent tout d'abord l'état Not Ready. Après un certain temps, leur état passe à Ready, ce qui signifie que ces nœuds peuvent désormais accepter des tâches en attente.

  7. Pour arrêter de surveiller les nœuds, appuyez sur Control+C.

  8. Répertoriez les rejets de nœuds :

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

    Le résultat indique que les nouveaux nœuds comportent des rejets NoSchedule, l'un avec la paire clé/valeur tenant: tenant1 et l'autre avec tenant: tenant2. Seuls les pods dont la tolérance correspond aux locataires spécifiés peuvent être planifiés sur ces nœuds.

  9. Surveillez les tâches dans le cluster :

    kubectl get jobs -w --all-namespaces
    

    Au bout de quelques minutes, la colonne "Completions" des tâches tenant1-larger-pi-job et tenant2-larger-pi-job prend la valeur 1/1, ce qui indique qu'elles ont bien été exécutées.

  10. Pour arrêter la surveillance des tâches, appuyez sur Control+C.

  11. Surveillez les pools de nœuds du cluster :

    watch -n 5 gcloud container node-pools list
    

    Au bout de quelques minutes, les deux pools nap- sont supprimés, et il ne reste plus dans le cluster que le pool de nœuds par défaut. Le provisionnement automatique des nœuds a supprimé les pool de nœuds nap-, car il n'y a plus de tâche en attente correspondant aux contraintes des pools.

  12. Pour arrêter la surveillance des pools de nœuds, appuyez sur Control+C.

Contrôler l'accès aux ressources Google Cloud

Outre la séparation des locataires dans le cluster, vous souhaitez sans doute contrôler l'accès des locataires aux ressources Google Cloud, telles que les buckets Cloud Storage ou les sujets Pub/Sub. Par exemple, chaque locataire peut avoir besoin d'un bucket Cloud Storage qui ne soit pas accessible aux autres locataires.

À l'aide de Workload Identity, vous pouvez créer une association entre les comptes de service Kubernetes et les comptes de service Google Cloud. Vous pouvez ensuite attribuer les rôles IAM (Identity and Access Management) appropriés au compte de service Google Cloud. De cette manière, vous pouvez appliquer le principe du moindre privilège afin que les tâches des locataires puissent accéder à leurs ressources, sans pouvoir toutefois accéder aux ressources appartenant à d'autres locataires.

Configurer Workload Identity de GKE

Configurez l'association entre votre compte de service Kubernetes et un compte de service Google Cloud que vous créez.

  1. Créez un compte de service Google Cloud pour le locataire tenant1 :

    gcloud iam service-accounts create tenant1-gsa
    
  2. Accordez au compte de service Kubernetes du locataire tenant1 les autorisations IAM lui permettant d'utiliser le compte de service Google Cloud du locataire tenant1 que vous venez de créer :

    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. Complétez l'association entre les deux comptes de service en annotant le compte de service Kubernetes avec le compte de service Google Cloud :

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

Envoyer une tâche qui écrit dans un bucket Cloud Storage

Dans cette section, vous vérifiez qu'une tâche qui s'exécute en tant que compte de service Kubernetes peut utiliser les autorisations IAM du compte de service Google Cloud associé à ce compte Kubernetes.

  1. Créez un bucket Cloud Storage pour le locataire tenant1 :

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

    L'identifiant de votre projet est utilisé comme suffixe dans le nom du bucket afin de le rendre unique.

  2. Mettez à jour le fichier de configuration de la tâche afin qu'elle utilise le bucket Cloud Storage :

    sed -i "s/MY_BUCKET/$BUCKET/" \
        manifests/jobs/write-gcs/bucket-write.yaml
    
  3. Accordez au compte de service du locataire tenant1 les autorisations pour lire et écrire des objets dans le bucket :

    gsutil iam ch \
        serviceAccount:tenant1-gsa@$PROJECT_ID.iam.gserviceaccount.com:objectAdmin \
        gs://$BUCKET
    
  4. Affichez la configuration de la tâche :

    kubectl kustomize manifests/jobs/write-gcs/
    

    La sortie ressemble à ceci :

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

    Le nom du nouveau bucket est transmis en tant qu'argument au conteneur generate-pi, et la tâche spécifie le compte de service Kubernetes tenant1-ksa approprié.

  5. Envoyez la tâche :

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

    Comme dans la section précédente, le provisionnement automatique des nœuds crée un pool et un nœud pour exécuter la tâche.

  6. Surveillez le pod de la tâche :

    kubectl get pods -n tenant1-ns -w
    

    Dans ce cas, vous surveillez le pod au lieu de surveiller le pool de nœuds. Vous voyez le pod passer par différents états. Au bout de quelques minutes, l'état passe à Completed. Cet état indique que la tâche est bien terminée.

  7. Pour arrêter la vérification, appuyez sur Control+C.

  8. Vérifiez qu'un fichier a bien été écrit dans le bucket Cloud Storage :

    gsutil ls -l gs://$BUCKET
    

    La liste se compose d'un unique fichier.

  9. Effectuez un nettoyage en supprimant la tâche :

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

    Vous enverrez cette tâche à nouveau dans la section suivante.

Révoquer les autorisations IAM

Dans cette dernière section, vous vérifiez qu'une fois révoquées les autorisations IAM du compte de service Google Cloud, le compte de service Kubernetes associé ne peut plus accéder au bucket Cloud Storage.

  1. Révoquez les autorisations en écriture du compte de service Google Cloud sur le bucket Cloud Storage :

    gsutil iam ch -d \
        serviceAccount:tenant1-gsa@$PROJECT_ID.iam.gserviceaccount.com:objectAdmin \
        gs://$BUCKET
    
  2. Envoyez la même tâche que précédemment :

    kubectl apply -k manifests/jobs/write-gcs/
    
  3. Surveillez à nouveau l'état du pod de la tâche :

    kubectl get pods -n tenant1-ns -w
    

    Après quelques minutes, le pod passe à l'état Error, ce qui indique que la tâche a échoué. Cette erreur est prévisible, car la tâche est exécutée par un compte de service Kubernetes associé à un compte de service Google Cloud qui ne dispose plus des autorisations en écriture sur le bucket Cloud Storage.

  4. Pour arrêter la surveillance du pod, appuyez sur Control+C.

  5. Répertoriez les fichiers du bucket :

    gsutil ls -l gs://$BUCKET
    

    Il n'y a toujours qu'un seul fichier dans la liste. Aucun nouveau fichier n'a été créé.

Effectuer un nettoyage

Le moyen le plus simple d'éviter la facturation consiste à supprimer le projet Google Cloud que vous avez créé pour le tutoriel.

Supprimer le projet

  1. Dans la console Google Cloud, accédez à la page Gérer les ressources.

    Accéder à la page Gérer les ressources

  2. Dans la liste des projets, sélectionnez le projet que vous souhaitez supprimer, puis cliquez sur Supprimer.
  3. Dans la boîte de dialogue, saisissez l'ID du projet, puis cliquez sur Arrêter pour supprimer le projet.

Supprimer le cluster GKE

Si vous ne souhaitez pas supprimer le projet, supprimez le cluster GKE :

gcloud container clusters delete multitenant

Étapes suivantes