Configurer la fédération d'identité de charge de travail avec Kubernetes

Ce guide explique comment utiliser la fédération d'identité de charge de travail pour permettre aux charges de travail exécutées sur Azure Kubernetes Service (AKS), Amazon Elastic Kubernetes Service ou sur un cluster Kubernetes auto-hébergé de s'authentifier auprès de Google Cloud.

Kubernetes vous permet de configurer un cluster de sorte que les charges de travail puissent obtenir des jetons de compte de service Kubernetes à partir d'un volume projeté. En configurant la fédération d'identité de charge de travail, vous pouvez autoriser les charges de travail à utiliser ces jetons de compte de service Kubernetes pour s'authentifier auprès de Google Cloud.

Si vous utilisez GKE, employez Workload Identity au lieu de configurer la fédération d'identité de charge de travail.

Avant de commencer

Avant de configurer la fédération d'identité de charge de travail, assurez-vous que votre cluster Kubernetes répond aux critères suivants :

AKS

Assurez-vous que votre cluster remplit les critères suivants :

  • Vous avez activé la fonctionnalité d'émetteur OIDC.

    Vous devez activer cette fonctionnalité afin que la fédération d'identité de charge de travail puisse accéder aux métadonnées OpenID Connect et au jeu de clés Web JSON (JWKS) pour le cluster.

EKS

Vous n'avez pas besoin de modifier votre configuration EKS.

Kubernetes

Assurez-vous que votre cluster remplit les critères suivants :

  • Vous utilisez Kubernetes en version 1.20 ou ultérieure.

    Les versions précédentes de Kubernetes utilisaient un format de jeton de compte de service différent, non compatible avec les instructions de ce document.

  • Vous avez configuré kube-apiserver afin qu'il accepte les projections des volumes de jetons ServiceAccount.

Le cluster n'a pas besoin d'être accessible sur Internet.

Configurer la fédération d'identité de charge de travail

Cette procédure n'est requise qu'une seule fois pour chaque cluster Kubernetes. Vous pouvez ensuite utiliser le même pool d'identités de charge de travail et le même fournisseur pour plusieurs pods Kubernetes et sur plusieurs projets Google Cloud.

Pour commencer à configurer la fédération d'identité de charge de travail, procédez comme suit :

  1. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  2. Nous vous recommandons d' utiliser un projet dédié pour gérer les pools d'identités de charge de travail et les fournisseurs.
  3. Make sure that billing is enabled for your Google Cloud project.

  4. Enable the IAM, Resource Manager, Service Account Credentials, and Security Token Service APIs.

    Enable the APIs

Définir un mappage et une condition d'attribut

Les jetons de compte de service Kubernetes contiennent plusieurs revendications, y compris les suivantes :

  • sub : contient l'espace de noms et le nom du compte de service, par exemple system:serviceaccount:NAMESPACE:KSA_NAME, où NAMESPACE est l'espace de noms du compte de service et KSA_NAME est le nom du compte de service.
  • "kubernetes.io".namespace : contient l'espace de noms du compte de service.
  • "kubernetes.io".serviceaccount.name : contient le nom du compte de service.
  • "kubernetes.io".pod.name : contient le nom du pod.

Pour utiliser sub comme identifiant de sujet (google.subject) dans Google Cloud, utilisez le mappage suivant :

google.subject=assertion.sub

Vous pouvez éventuellement mapper d'autres attributs. Vous pouvez ensuite faire référence à ces attributs lorsque vous autorisez l'accès aux ressources. Par exemple :

google.subject=assertion.sub,
attribute.namespace=assertion['kubernetes.io']['namespace'],
attribute.service_account_name=assertion['kubernetes.io']['serviceaccount']['name'],
attribute.pod=assertion['kubernetes.io']['pod']['name']

Vous pouvez également définir une condition d'attribut. Les conditions d'attribut sont des expressions CEL qui peuvent vérifier les attributs d'assertion et les attributs cibles. Si la condition d'attribut renvoie true pour un identifiant donné, celui-ci est accepté. Dans le cas contraire, l'identifiant est rejeté.

Vous pouvez utiliser une condition d'attribut pour limiter les comptes de service Kubernetes pouvant utiliser la fédération d'identité de charge de travail afin d'obtenir des jetons Google Cloud de courte durée. Par exemple, la condition suivante limite l'accès aux comptes de service Kubernetes provenant des espaces de noms backend et monitoring :

assertion['kubernetes.io']['namespace'] in ['backend', 'monitoring']

Créer le pool d'identité de charge de travail et le fournisseur

Rôles requis

Pour obtenir les autorisations nécessaires pour configurer la fédération d'identité de charge de travail, demandez à votre administrateur de vous accorder les rôles IAM suivants sur le projet :

Pour en savoir plus sur l'attribution de rôles, consultez la section Gérer les accès.

Vous pouvez également obtenir les autorisations requises via des rôles personnalisés ou d'autres rôles prédéfinis.

Le rôle de base IAM "Propriétaire" (roles/owner) inclut également des autorisations permettant de configurer la fédération d'identité. Les rôles de base ne doivent pas être attribués dans un environnement de production, mais ils peuvent être attribués dans un environnement de développement ou de test.

Pour créer un pool d'identités de charge de travail et un fournisseur, procédez comme suit :

AKS

  1. Déterminez l'URL de l'émetteur de votre cluster AKS :

    az aks show -n NAME -g RESOURCE_GROUP --query "oidcIssuerProfile.issuerUrl" -otsv
    

    Remplacez les éléments suivants :

    • NAME : nom du cluster.
    • RESOURCE_GROUP : groupe de ressources du cluster.

    La commande renvoie l'URL de l'émetteur. Vous aurez besoin de l'URL de l'émetteur à l'une des étapes suivantes.

    Si la commande ne renvoie aucune URL d'émetteur, vérifiez que vous avez bien activé la fonctionnalité d'émetteur OIDC.

  2. Créez un pool d'identités de charge de travail :

    gcloud iam workload-identity-pools create POOL_ID \
        --location="global" \
        --description="DESCRIPTION" \
        --display-name="DISPLAY_NAME"
    

    Remplacez les éléments suivants :

    • POOL_ID : ID unique du pool.
    • DISPLAY_NAME : nom du pool.
    • DESCRIPTION : description du pool que vous choisissez. Cette description apparaît lorsque vous accordez l'accès aux identités du pool.
  3. Ajoutez le cluster AKS en tant que fournisseur de pools d'identités de charge de travail :

    gcloud iam workload-identity-pools providers create-oidc PROVIDER_ID \
        --location="global" \
        --workload-identity-pool="POOL_ID" \
        --issuer-uri="ISSUER" \
        --attribute-mapping="MAPPINGS" \
        --attribute-condition="CONDITIONS"
    

    Remplacez les éléments suivants :

    • PROVIDER_ID : ID unique de fournisseur de pools d'identités de charge de travail de votre choix.
    • POOL_ID : ID du pool d'identités de charge de travail que vous avez créé précédemment.
    • ISSUER : URI d'émetteur que vous avez déterminé précédemment.
    • MAPPINGS : liste de mappages d'attributs séparés par des virgules que vous avez créés précédemment dans ce guide
    • CONDITIONS : condition d'attribut facultative que vous avez créée précédemment dans ce guide. Supprimez le paramètre si vous n'avez pas de condition d'attribut.

EKS

  1. Déterminez l'URL de l'émetteur de votre cluster EKS :

    aws eks describe-cluster --name NAME --query "cluster.identity.oidc.issuer" --output text
    

    Remplacez NAME par le nom du cluster.

    La commande renvoie l'URL de l'émetteur. Vous aurez besoin de l'URL de l'émetteur à l'une des étapes suivantes.

  2. Créez un pool d'identités de charge de travail :

    gcloud iam workload-identity-pools create POOL_ID \
        --location="global" \
        --description="DESCRIPTION" \
        --display-name="DISPLAY_NAME"
    

    Remplacez les éléments suivants :

    • POOL_ID : ID unique du pool.
    • DISPLAY_NAME : nom du pool.
    • DESCRIPTION : description du pool que vous choisissez. Cette description apparaît lorsque vous accordez l'accès aux identités du pool.
  3. Ajoutez le cluster EKS en tant que fournisseur de pools d'identités de charge de travail :

    gcloud iam workload-identity-pools providers create-oidc PROVIDER_ID \
        --location="global" \
        --workload-identity-pool="POOL_ID" \
        --issuer-uri="ISSUER" \
        --attribute-mapping="MAPPINGS" \
        --attribute-condition="CONDITIONS"
    

    Remplacez les éléments suivants :

    • PROVIDER_ID : ID unique de fournisseur de pools d'identités de charge de travail de votre choix.
    • POOL_ID : ID du pool d'identités de charge de travail que vous avez créé précédemment.
    • ISSUER : URI d'émetteur que vous avez déterminé précédemment.
    • MAPPINGS : liste de mappages d'attributs séparés par des virgules que vous avez créés précédemment dans ce guide
    • CONDITIONS : condition d'attribut facultative que vous avez créée précédemment dans ce guide. Supprimez le paramètre si vous n'avez pas de condition d'attribut.

Kubernetes

  1. Connectez-vous à votre cluster Kubernetes et utilisez kubectl pour déterminer l'URL de l'émetteur de votre cluster :

    kubectl get --raw /.well-known/openid-configuration | jq -r .issuer
    

    Vous aurez besoin de l'URL de l'émetteur à l'une des étapes suivantes.

  2. Téléchargez le jeu de clés Web JSON (JWKS) du cluster :

    kubectl get --raw /openid/v1/jwks > cluster-jwks.json
    

    Dans l'une des étapes suivantes, vous devez importer le JWKS pour que la fédération d'identité de charge de travail puisse vérifier l'authenticité des jetons de compte de service Kubernetes émis par votre cluster.

  3. Créez un pool d'identités de charge de travail :

    gcloud iam workload-identity-pools create POOL_ID \
        --location="global" \
        --description="DESCRIPTION" \
        --display-name="DISPLAY_NAME"
    

    Remplacez les éléments suivants :

    • POOL_ID : ID unique du pool.
    • DISPLAY_NAME : nom du pool.
    • DESCRIPTION : description du pool que vous choisissez. Cette description apparaît lorsque vous accordez l'accès aux identités du pool.
  4. Ajoutez le cluster Kubernetes en tant que fournisseur de pools d'identités de charge de travail, puis importez le JWKS du cluster :

    gcloud iam workload-identity-pools providers create-oidc PROVIDER_ID \
        --location="global" \
        --workload-identity-pool="POOL_ID" \
        --issuer-uri="ISSUER" \
        --attribute-mapping="MAPPINGS" \
        --attribute-condition="CONDITIONS" \
        --jwk-json-path="cluster-jwks.json"
    

    Remplacez les éléments suivants :

    • PROVIDER_ID : ID unique de fournisseur de pools d'identités de charge de travail de votre choix.
    • POOL_ID : ID du pool d'identités de charge de travail que vous avez créé précédemment.
    • ISSUER : URI d'émetteur que vous avez déterminé précédemment.
    • MAPPINGS : liste de mappages d'attributs séparés par des virgules que vous avez créés précédemment dans ce guide
    • CONDITIONS : condition d'attribut facultative que vous avez créée précédemment dans ce guide. Supprimez le paramètre si vous n'avez pas de condition d'attribut.

Authentifier une charge de travail Kubernetes

Cette section explique comment configurer une charge de travail Kubernetes pour utiliser la fédération d'identité de charge de travail.

Vous devez effectuer ces étapes une fois pour chaque charge de travail Kubernetes devant accéder à Google Cloud.

Créer une paire de comptes de service

Pour permettre à une charge de travail Kubernetes de s'authentifier auprès de Google Cloud, vous avez besoin d'une paire de comptes de service :

  • Un compte de service Kubernetes que vous associez au pod Kubernetes
  • Un compte de service IAM dont la charge de travail Kubernetes peut emprunter l'identité en utilisant le compte de service Kubernetes associé

Pour créer les comptes de service, procédez comme suit :

  1. Créez un compte de service IAM qui représente la charge de travail.

    Le compte de service ne doit pas obligatoirement se trouver dans le même projet que le pool d'identités de charge de travail.

    gcloud iam service-accounts create SA_NAME
    

    Remplacez les éléments suivants :

    • SA_NAME : nom du compte de service.
  2. Créez un compte de service Kubernetes :

    kubectl create serviceaccount KSA_NAME --namespace NAMESPACE
    

    Remplacez les éléments suivants :

    • KSA_NAME : nom du compte de service.
    • NAMESPACE : espace de noms dans lequel créer le compte de service.
  3. Attribuez au compte de service IAM l'accès aux ressources auxquelles la charge de travail Kubernetes doit accéder.

  4. Attribuez le rôle Utilisateur Workload Identity (roles/iam.workloadIdentityUser) à l'identité externe du compte de service Kubernetes :

    gcloud iam service-accounts add-iam-policy-binding SERVICE_ACCOUNT_EMAIL \
        --role=roles/iam.workloadIdentityUser \
        --member="principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/subject/SUBJECT"
    

    Remplacez les éléments suivants :

    • SERVICE_ACCOUNT_EMAIL : adresse e-mail du compte de service
    • PROJECT_NUMBER : numéro de projet du projet contenant le pool d'identités de charge de travail.
    • POOL_ID : ID du pool d'identités de charge de travail.
    • SUBJECT : valeur attendue pour l'attribut que vous avez mappé sur google.subject, par exemple system:serviceaccount:NAMESPACE:KSA_NAME.

Déployer la charge de travail Kubernetes

Vous allez maintenant déployer une charge de travail Kubernetes et faire en sorte qu'elle utilise la paire de comptes de service :

  1. Créez un fichier de configuration des identifiants :

    gcloud iam workload-identity-pools create-cred-config \
        projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/providers/PROVIDER_ID \
        --service-account=SERVICE_ACCOUNT_EMAIL \
        --credential-source-file=/var/run/service-account/token \
        --credential-source-type=text \
        --output-file=credential-configuration.json
    

    Remplacez les éléments suivants :

    • PROJECT_NUMBER : numéro de projet du projet contenant le pool d'identités de charge de travail
    • POOL_ID : ID du pool d'identités de charge de travail
    • PROVIDER_ID : ID du fournisseur du pool d'identités de charge de travail
    • SERVICE_ACCOUNT_EMAIL : adresse e-mail du compte de service

    Le fichier de configuration des identifiants permet aux bibliothèques clientes Cloud, à gcloud CLI et à Terraform de déterminer les éléments suivants :

    • Où obtenir des identifiants externes
    • Quel pool d'identités de charge de travail et quel fournisseur utiliser
    • À quel compte de service emprunter l'identité
  2. Importez le fichier de configuration des identifiants en tant que ConfigMap :

    kubectl create configmap CONFIGMAP_NAME \
      --from-file credential-configuration.json \
      --namespace NAMESPACE
    

    Remplacez les éléments suivants :

    • CONFIGMAP_NAME : nom du ConfigMap.
    • NAMESPACE : espace de noms dans lequel créer le ConfigMap.
  3. Déployez une charge de travail et faites en sorte qu'elle utilise le compte de service Kubernetes et ConfigMap.

    Créez un fichier manifeste et configurez-le comme suit :

    • Installez un volume de jetons projeté pour que la charge de travail puisse obtenir un jeton de compte de service Kubernetes à partir d'un fichier local. Configurez le volume de sorte que le jeton du compte de service Kubernetes utilise l'audience attendue par votre fournisseur de pools de fédération d'identité de charge de travail.
    • Installez le ConfigMap contenant le fichier de configuration des identifiants afin que la charge de travail puisse accéder à la configuration requise pour utiliser la fédération d'identité de charge de travail.
    • Ajoutez une variable d'environnement GOOGLE_APPLICATION_CREDENTIALS contenant le chemin d'accès du fichier de configuration des identifiants, afin que les charges de travail puissent trouver ce fichier.

    Vous trouverez ci-dessous un exemple de fichier manifeste qui utilise le compte de service Kubernetes et ConfigMap pour permettre à la Google Cloud CLI de s'authentifier auprès de Google Cloud :

    apiVersion: v1
    kind: Pod
    metadata:
      name: example
      namespace: NAMESPACE
    spec:
      containers:
      - name: example
        image: google/cloud-sdk:alpine
        command: ["/bin/sh", "-c", "gcloud auth login --cred-file $GOOGLE_APPLICATION_CREDENTIALS && gcloud auth list && sleep 600"]
        volumeMounts:
        - name: token
          mountPath: "/var/run/service-account"
          readOnly: true
        - name: workload-identity-credential-configuration
          mountPath: "/etc/workload-identity"
          readOnly: true
        env:
        - name: GOOGLE_APPLICATION_CREDENTIALS
          value: "/etc/workload-identity/credential-configuration.json"
    
      serviceAccountName: KSA_NAME
      volumes:
      - name: token
        projected:
          sources:
          - serviceAccountToken:
              audience: https://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/providers/PROVIDER_ID
              expirationSeconds: 3600
              path: token
      - name: workload-identity-credential-configuration
        configMap:
          name: CONFIGMAP_NAME
    

    Vous pouvez suivre la même approche pour permettre aux outils et aux charges de travail utilisant l'une des bibliothèques clientes suivantes de trouver automatiquement les identifiants :

    C++

    Les bibliothèques clientes Google Cloud pour C++ sont compatibles avec la fédération d'identité de charge de travail depuis la version v2.6.0. Pour utiliser la fédération d'identité de charge de travail, vous devez créer les bibliothèques clientes avec la version 1.36.0 ou ultérieure de gRPC.

    Go

    Les bibliothèques clientes pour Go sont compatibles avec la fédération d'identité si elles utilisent la version 0.0.0-20210218202405-ba52d332ba99 ou une version ultérieure du module golang.org/x/oauth2.

    Pour vérifier quelle version de ce module est utilisée par votre bibliothèque cliente, exécutez les commandes suivantes :

    cd $GOPATH/src/cloud.google.com/go
    go list -m golang.org/x/oauth2
    

    Java

    Les bibliothèques clientes pour Java sont compatibles avec la fédération d'identité si elles utilisent la version 0.24.0 ou une version ultérieure de l'artefact com.google.auth:google-auth-library-oauth2-http.

    Pour vérifier la version de cet artefact utilisée par votre bibliothèque cliente, exécutez la commande Maven suivante dans le répertoire de votre application :

    mvn dependency:list -DincludeArtifactIds=google-auth-library-oauth2-http
    

    Node.js

    Les bibliothèques clientes pour Node.js sont compatibles avec la fédération d'identité de charge de travail si elles utilisent la version 7.0.2 ou ultérieure du package google-auth-library.

    Pour vérifier la version de ce package utilisée par votre bibliothèque cliente, exécutez la commande suivante dans le répertoire de votre application :

    npm list google-auth-library
    

    Lorsque vous créez un objet GoogleAuth, vous pouvez spécifier un ID de projet ou autoriser GoogleAuth à le trouver automatiquement. Pour trouver automatiquement l'ID du projet, le compte de service dans le fichier de configuration doit disposer du rôle de visiteur (roles/browser) ou d'un rôle avec des autorisations équivalentes sur votre projet. Pour en savoir plus, consultez la section README du package google-auth-library.

    Python

    Les bibliothèques clientes pour Python sont compatibles avec la fédération d'identité si elles utilisent la version 1.27.0 ou ultérieure du package google-auth.

    Pour vérifier la version de ce package utilisée par votre bibliothèque cliente, exécutez la commande suivante dans l'environnement dans lequel le package est installé :

    pip show google-auth
    

    Pour spécifier un ID de projet pour le client d'authentification, vous pouvez définir la variable d'environnement GOOGLE_CLOUD_PROJECT ou autoriser le client à trouver automatiquement l'ID du projet. Pour trouver automatiquement l'ID du projet, le compte de service dans le fichier de configuration doit disposer du rôle de visiteur (roles/browser) ou d'un rôle avec des autorisations équivalentes sur votre projet. Pour en savoir plus, consultez le guide de l'utilisateur du package google-auth.

    gcloud

    Pour vous authentifier à l'aide de la fédération d'identité de charge de travail, utilisez la commande gcloud auth login :

    gcloud auth login --cred-file=FILEPATH.json
    

    Remplacez FILEPATH par le chemin d'accès au fichier de configuration des identifiants.

    La fédération d'identité de charge de travail dans gcloud CLI est disponible dans les versions 363.0.0 et ultérieures de gcloud CLI.

    Terraform

    Le fournisseur Google Cloud est compatible avec la fédération d'identité de charge de travail si vous utilisez la version 3.61.0 ou ultérieure :

    terraform {
      required_providers {
        google = {
          source  = "hashicorp/google"
          version = "~> 3.61.0"
        }
      }
    }
    

    gsutil

    Pour vous authentifier à l'aide de la fédération d'identité de charge de travail, appliquez l'une des méthodes suivantes :

    Lorsque vous utilisez gsutil conjointement avec gcloud, connectez-vous comme d'habitude :

    gcloud auth login --cred-file=FILEPATH.json
    

    Si vous utilisez gsutil en tant qu'application de ligne de commande autonome, modifiez le fichier .boto pour inclure la section suivante :

    [Credentials]
    gs_external_account_file = FILEPATH
    

    Dans les deux cas, remplacez FILEPATH par le chemin d'accès au fichier de configuration des identifiants.

    La fédération d'identité de charge de travail dans gsutil est compatible avec les versions 379.0.0 et ultérieures de gcloud CLI.

    bq

    Pour vous authentifier à l'aide de la fédération d'identité de charge de travail, utilisez la commande gcloud auth login, comme suit :

    gcloud auth login --cred-file=FILEPATH.json
    

    Remplacez FILEPATH par le chemin d'accès au fichier de configuration des identifiants.

    La fédération d'identité de charge de travail dans bq est disponible dans les versions 390.0.0 et ultérieures de gcloud CLI.

  4. Vous pouvez également vérifier que l'authentification fonctionne correctement en exécutant la commande suivante :

    kubectl exec example --namespace NAMESPACE -- gcloud auth print-access-token
    

Étapes suivantes