Utiliser Workload Identity avec Google Cloud

Ce guide explique comment configurer l'identité de charge de travail sur GKE sur AWS de manière à contrôler l'accès de la charge de travail aux ressources GCP. Elle montre comment accéder aux ressources Google Cloud à partir de votre cluster à l'aide de l'identité d'utilisateur.

Pour plus d'informations sur l'utilisation des identités de charge de travail avec des comptes IAM AWS pour contrôler l'accès aux ressources AWS, consultez la page Utiliser Workload Identity avec AWS.

Présentation

Workload Identity utilise les autorisations IAM Google Cloud pour contrôler l'accès aux ressources Google Cloud. Avec Workload Identity, vous pouvez attribuer différents rôles IAM à chaque charge de travail. Ce contrôle précis des autorisations vous permet de suivre le principe du moindre privilège. Sans l'identité de la charge de travail, vous devez attribuer des rôles Google Cloud IAM à vos noeuds GKE sur AWS, ce qui permet à toutes les charges de travail de ces nœuds de bénéficier des mêmes autorisations que le nœud lui-même.

Prérequis

  • Créez un cluster d'utilisateur avec Kubernetes version 1.20 ou ultérieure.

  • Si votre VPC AWS utilise un proxy ou un pare-feu, autorisez les URL suivantes :

    • securetoken.googleapis.com
    • iamcredentials.googleapis.com
    • sts.googleapis.com
  • À partir de votre répertoire anthos-aws, utilisez anthos-gke pour basculer vers le contexte de votre cluster d'utilisateur.

    cd anthos-aws
    env HTTPS_PROXY=http://localhost:8118 \
      anthos-gke aws clusters get-credentials CLUSTER_NAME
    Remplacez CLUSTER_NAME par le nom de votre cluster d'utilisateur.

  • Activez les quatre nouveaux services requis pour cette fonctionnalité à l'aide des commandes suivantes :

    gcloud services enable securetoken.googleapis.com
    gcloud services enable iam.googleapis.com
    gcloud services enable iamcredentials.googleapis.com
    gcloud services enable sts.googleapis.com
    

Composer le pool WI et les noms des fournisseurs

Chaque projet Google Cloud crée automatiquement un pool d'identités de charge de travail géré portant un nom au format PROJECT_ID.svc.id.goog. De même, Google Cloud crée un fournisseur d'identité dont le nom suit le modèle https://gkehub.googleapis.com/projects/PROJECT_ID/locations/global/memberships/MEMBERSHIP_ID. Pour plus d'informations sur les pools d'identités de charge de travail, consultez la section Composants compatibles avec les parcs. Composez ces noms à partir de vos ID de projet et d'abonnement, comme indiqué ci-dessous :

export PROJECT_ID=USER_PROJECT_NAME
export CLUSTER_MEMBERSHIP_ID=PROJECT_MEMBERSHIP_NAME
export IDP="https://gkehub.googleapis.com/projects/${PROJECT_ID}/locations/global/memberships/${CLUSTER_MEMBERSHIP_ID}"
export WI_POOL="${PROJECT_ID}.svc.id.goog"

Remplacez l'élément suivant :

  • USER_PROJECT_NAME par le nom de projet utilisateur choisi par l'utilisateur
  • PROJECT_MEMBERSHIP_NAME par le nom de l'appartenance au cluster

Créer une liaison de stratégie IAM

Créez une liaison de stratégie pour autoriser un compte de service Kubernetes (KSA) à usurper l'identité d'un compte de service Google Cloud (GSA).

export K8S_NAMESPACE=KUBERNETES_NAMESPACE
export KSA_NAME=KUBERNETES_SA_NAME
export GCP_SA_EMAIL="WORKLOAD_IDENTITY_TEST@${PROJECT_ID}.iam.gserviceaccount.com"
gcloud iam service-accounts add-iam-policy-binding \
  --role roles/iam.workloadIdentityUser \
  --member "serviceAccount:$WI_POOL[$K8S_NAMESPACE/$KSA_NAME]" $GCP_SA_EMAIL

Remplacez l'élément suivant :

  • KUBERNETES_NAMESPACE par l'espace de noms Kubernetes dans lequel le compte de service Kubernetes est défini.
  • WORKLOAD_IDENTITY_TEST par le nom de charge de travail de votre choix
  • KUBERNETES_SA_NAME par le nom du compte de service Kubernetes associé à l'application

Créer un fichier ConfigMap de SDK

Exécutez le script shell ci-dessous pour stocker les détails de l'identité de charge de travail dans un fichier ConfigMap. Lorsqu'un pod installe le fichier ConfigMap, Google Cloud CLI peut lire les détails de l'identité de charge de travail.

cat << EOF > cfmap.yaml
kind: ConfigMap
apiVersion: v1
metadata:
  namespace: ${K8S_NAMESPACE}
  name: my-cloudsdk-config
data:
  config: |
    {
      "type": "external_account",
      "audience": "identitynamespace:${WI_POOL}:${IDP}",
      "service_account_impersonation_url": "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/${GCP_SA_EMAIL}:generateAccessToken",
      "subject_token_type": "urn:ietf:params:oauth:token-type:jwt",
      "token_url": "https://sts.googleapis.com/v1/token",
      "credential_source": {
        "file": "/var/run/secrets/tokens/gcp-ksa/token"
      }
    }
EOF

env HTTPS_PROXY=http://localhost:8118 \
  kubectl apply -f cfmap.yaml

Créer un compte de service Kubernetes

Créez un KSA sur votre cluster d'utilisateur avec le même nom et le même espace de noms que ceux utilisés dans la liaison IAM.

cat << EOF > k8s-service-account.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: ${KSA_NAME}
  namespace: ${K8S_NAMESPACE}
EOF

env HTTPS_PROXY=http://localhost:8118 \
  kubectl apply -f k8s-service-account.yaml

Créer un pod

Ensuite, créez un pod avec la projection de jetons du compte de service et le fichier ConfigMap créé ci-dessus.

  1. Créez l'exemple de fichier yaml du pod.

    cat << EOF > sample-pod.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: sample-pod
      namespace: ${K8S_NAMESPACE}
    spec:
      serviceAccountName: ${KSA_NAME}
      containers:
      - command:
        - /bin/bash
        - -c
        - while :; do echo '.'; sleep 500 ; done
        image: google/cloud-sdk
        name: cloud-sdk
        env:
          - name: GOOGLE_APPLICATION_CREDENTIALS
            value: /var/run/secrets/tokens/gcp-ksa/google-application-credentials.json
        volumeMounts:
        - name: gcp-ksa
          mountPath: /var/run/secrets/tokens/gcp-ksa
          readOnly: true
      volumes:
      - name: gcp-ksa
        projected:
          defaultMode: 420
          sources:
          - serviceAccountToken:
              path: token
              audience: ${WI_POOL}
              expirationSeconds: 172800
          - configMap:
              name: my-cloudsdk-config
              optional: false
              items:
               - key: "config"
                 path: "google-application-credentials.json"
    EOF
    
  2. Appliquez le fichier YAML du pod à votre cluster.

    env HTTPS_PROXY=http://localhost:8118 \
     kubectl apply -f sample-pod.yaml
    

Utiliser l'identité de charge de travail Google Cloud

Versions du SDK compatibles

Pour utiliser la fonctionnalité d'identité de charge de travail Google Cloud, vous devez créer votre code avec un SDK compatible. Pour obtenir la liste des versions de SDK compatibles avec l'identité de charge de travail Google Cloud, consultez la page Identité de charge de travail de parc.

Exemple de code utilisant l'identité de charge de travail

Cette section inclut un exemple de code Python utilisant l'identité de charge de travail Google Cloud. Dans cet exemple, le compte de service utilise une identité disposant des droits d'administrateur Cloud Storage pour lister tous les buckets Cloud Storage du projet Google Cloud.

  1. Exécutez une interface système dans le pod.

    env HTTPS_PROXY=http://localhost:8118 \
    kubectl exec -it sample-pod -- bash
    
  2. Exécutez un script pour lister les buckets de stockage du projet.

    # execute these commands inside the Pod
    pip install --upgrade google-cloud-storage
    
    cat << EOF > sample-list-bucket.py
    from google.cloud import storage
    storage_client = storage.Client()
    buckets = storage_client.list_buckets()
    
    for bucket in buckets:
      print(bucket.name)
    EOF
    
    env GOOGLE_CLOUD_PROJECT=USER_PROJECT_NAME \
     python3 sample-list-bucket.py
    

    Remplacez USER_PROJECT_NAME par votre projet Google Cloud.

Pour plus d'informations