Configura la federazione delle identità per i carichi di lavoro con Kubernetes

Questa guida descrive come utilizzare la federazione delle identità per i carichi di lavoro per consentire l'autenticazione in Google Cloud dei carichi di lavoro eseguiti su Azure Kubernetes Service (AKS), Amazon Elastic Kubernetes o su un cluster Kubernetes self-hosted.

Kubernetes consente di configurare un cluster in modo che i carichi di lavoro possano ottenere i token degli account di servizio Kubernetes da un volume previsto. Configurando la federazione delle identità per i carichi di lavoro, puoi consentire ai carichi di lavoro di utilizzare questi token dell'account di servizio Kubernetes per l'autenticazione su Google Cloud.

Se utilizzi GKE, usa Workload Identity anziché configurare la federazione delle identità per i carichi di lavoro.

Prima di iniziare

Prima di configurare la federazione delle identità per i carichi di lavoro, assicurati che il tuo cluster Kubernetes soddisfi i seguenti criteri:

AKS

Assicurati che il cluster soddisfi i seguenti criteri:

  • Hai abilitato la funzionalità Emittente OIDC.

    Devi abilitare questa funzionalità in modo che la federazione delle identità per i carichi di lavoro possa accedere ai metadati OpenID Connect e al set di chiavi web JSON (JWKS) per il cluster.

EKS

Non è necessario apportare modifiche alla configurazione EKS.

Kubernetes

Assicurati che il cluster soddisfi i seguenti criteri:

  • Stai eseguendo Kubernetes 1.20 o versioni successive.

    Le versioni precedenti di Kubernetes utilizzavano un formato token dell'account di servizio diverso non compatibile con le istruzioni riportate in questo documento.

  • Hai configurato kube-apiserver in modo che supporti le proiezioni di volumi di token ServiceAccount.

Il cluster non deve essere accessibile tramite internet.

Configura la federazione delle identità per i carichi di lavoro

Dovrai eseguire questi passaggi solo una volta per ogni cluster Kubernetes. Puoi quindi utilizzare lo stesso pool di identità per i carichi di lavoro e lo stesso provider per più pod Kubernetes e su più progetti Google Cloud.

Per avviare la configurazione della federazione delle identità per i carichi di lavoro:

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

    Go to project selector

  2. Ti consigliamo di utilizzare un progetto dedicato per gestire provider e pool di identità per i carichi di lavoro.
  3. Assicurati che la fatturazione sia attivata per il tuo progetto Google Cloud.

  4. Abilita le API IAM, Resource Manager, Service Account Credentials, and Security Token Service.

    Abilita le API

Definisci una mappatura e una condizione degli attributi

I token dell'account di servizio Kubernetes contengono più attestazioni, tra cui:

  • sub: contiene lo spazio dei nomi e il nome dell'account di servizio, ad esempio system:serviceaccount:NAMESPACE:KSA_NAME, dove NAMESPACE è lo spazio dei nomi dell'account di servizio e KSA_NAME è il nome dell'account di servizio.
  • "kubernetes.io".namespace: contiene lo spazio dei nomi dell'account di servizio.
  • "kubernetes.io".serviceaccount.name: contiene il nome dell'account di servizio.
  • "kubernetes.io".pod.name: contiene il nome del pod.

Per utilizzare sub come identificatore del soggetto (google.subject) in Google Cloud, utilizza la seguente mappatura:

google.subject=assertion.sub

Se vuoi, puoi mappare ulteriori attributi. Puoi quindi fare riferimento a questi attributi quando concedi l'accesso alle risorse. Ad esempio:

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']

Facoltativamente, definisci una condizione dell'attributo. Le condizioni degli attributi sono espressioni CEL in grado di controllare gli attributi di asserzioni e gli attributi di destinazione. Se la condizione dell'attributo ha valore true per una determinata credenziale, la credenziale viene accettata. In caso contrario, la credenziale viene rifiutata.

Puoi utilizzare una condizione degli attributi per limitare gli account di servizio Kubernetes che possono utilizzare la federazione delle identità dei carichi di lavoro per ottenere token Google Cloud di breve durata. Ad esempio, la condizione seguente limita l'accesso agli account di servizio Kubernetes dagli spazi dei nomi backend e monitoring:

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

Crea il pool di identità per i carichi di lavoro e il provider

Ruoli obbligatori

Per ottenere le autorizzazioni necessarie per configurare la federazione delle identità per i carichi di lavoro, chiedi all'amministratore di concederti i seguenti ruoli IAM sul progetto:

Per saperne di più sulla concessione dei ruoli, consulta Gestire l'accesso.

Potresti anche essere in grado di ottenere le autorizzazioni richieste tramite i ruoli personalizzati o altri ruoli predefiniti.

In alternativa, il ruolo di base Proprietario IAM (roles/owner) include anche le autorizzazioni per configurare la federazione delle identità. Non devi concedere ruoli di base in un ambiente di produzione, ma puoi concederli in un ambiente di sviluppo o test.

Per creare un pool di identità per i carichi di lavoro e un provider:

AKS

  1. Determina l'URL dell'emittente del cluster AKS:

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

    Sostituisci quanto segue:

    • NAME: il nome del cluster
    • RESOURCE_GROUP: il gruppo di risorse del cluster

    Il comando restituisce l'URL dell'emittente. L'URL dell'emittente deve essere indicato in uno dei seguenti passaggi.

    Se il comando non restituisce un URL dell'emittente, verifica di aver abilitato la funzionalità emittente OIDC.

  2. Crea un nuovo pool di identità per i carichi di lavoro:

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

    Sostituisci quanto segue:

    • POOL_ID: l'ID univoco del pool.
    • DISPLAY_NAME: il nome del pool.
    • DESCRIPTION: una descrizione del pool che scegli. Questa descrizione viene visualizzata quando concedi l'accesso alle identità dei pool.
  3. Aggiungi il cluster AKS come provider di pool di identità per i carichi di lavoro:

    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"
    

    Sostituisci quanto segue:

    • PROVIDER_ID: un ID provider univoco del pool di identità per i carichi di lavoro a tua scelta.
    • POOL_ID: l'ID pool di identità per i carichi di lavoro creato in precedenza.
    • ISSUER: l'URI dell'emittente che hai stabilito in precedenza.
    • MAPPINGS: un elenco separato da virgole di mappature degli attributi che hai creato in precedenza in questa guida.
    • CONDITIONS: una condizione dell'attributo facoltativa che hai creato in precedenza in questa guida. Rimuovi il parametro se non hai una condizione per l'attributo.

EKS

  1. Determina l'URL emittente del cluster EKS:

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

    Sostituisci NAME con il nome del cluster.

    Il comando restituisce l'URL dell'emittente. L'URL dell'emittente deve essere indicato in uno dei seguenti passaggi.

  2. Crea un nuovo pool di identità per i carichi di lavoro:

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

    Sostituisci quanto segue:

    • POOL_ID: l'ID univoco del pool.
    • DISPLAY_NAME: il nome del pool.
    • DESCRIPTION: una descrizione del pool che scegli. Questa descrizione viene visualizzata quando concedi l'accesso alle identità dei pool.
  3. Aggiungi il cluster EKS come provider di pool di identità per i carichi di lavoro:

    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"
    

    Sostituisci quanto segue:

    • PROVIDER_ID: un ID provider univoco del pool di identità per i carichi di lavoro a tua scelta.
    • POOL_ID: l'ID pool di identità per i carichi di lavoro creato in precedenza.
    • ISSUER: l'URI dell'emittente che hai stabilito in precedenza.
    • MAPPINGS: un elenco separato da virgole di mappature degli attributi che hai creato in precedenza in questa guida.
    • CONDITIONS: una condizione dell'attributo facoltativa che hai creato in precedenza in questa guida. Rimuovi il parametro se non hai una condizione per l'attributo.

Kubernetes

  1. Connettiti al tuo cluster Kubernetes e utilizza kubectl per determinare l'URL emittente del cluster:

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

    L'URL dell'emittente deve essere indicato in uno dei seguenti passaggi.

  2. Scarica il set di chiavi web JSON (JWKS) del cluster:

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

    In uno dei passaggi seguenti, dovrai caricare il file JWKS in modo che la federazione delle identità per i carichi di lavoro possa verificare l'autenticità dei token dell'account di servizio Kubernetes emessi dal cluster.

  3. Crea un nuovo pool di identità per i carichi di lavoro:

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

    Sostituisci quanto segue:

    • POOL_ID: l'ID univoco del pool.
    • DISPLAY_NAME: il nome del pool.
    • DESCRIPTION: una descrizione del pool che scegli. Questa descrizione viene visualizzata quando concedi l'accesso alle identità dei pool.
  4. Aggiungi il cluster Kubernetes come provider di pool di identità per i carichi di lavoro e carica il JWKS del 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"
    

    Sostituisci quanto segue:

    • PROVIDER_ID: un ID provider univoco del pool di identità per i carichi di lavoro a tua scelta.
    • POOL_ID: l'ID pool di identità per i carichi di lavoro creato in precedenza.
    • ISSUER: l'URI dell'emittente che hai stabilito in precedenza.
    • MAPPINGS: un elenco separato da virgole di mappature degli attributi che hai creato in precedenza in questa guida.
    • CONDITIONS: una condizione dell'attributo facoltativa che hai creato in precedenza in questa guida. Rimuovi il parametro se non hai una condizione per l'attributo.

Autentica un carico di lavoro Kubernetes

Questa sezione descrive come configurare un carico di lavoro Kubernetes per l'utilizzo della federazione delle identità per i carichi di lavoro.

Devi eseguire questi passaggi una volta per ogni carico di lavoro Kubernetes che richiede l'accesso a Google Cloud.

Creare una coppia di account di servizio

Per consentire a un carico di lavoro Kubernetes di eseguire l'autenticazione in Google Cloud, sono necessarie una coppia di account di servizio:

  • Un account di servizio Kubernetes che colleghi al pod Kubernetes.
  • Un account di servizio IAM che il carico di lavoro Kubernetes può assumere tramite l'account di servizio Kubernetes associato.

Per creare gli account di servizio:

  1. Crea un account di servizio IAM che rappresenta il carico di lavoro.

    L'account di servizio non deve necessariamente trovarsi nello stesso progetto del pool di identità dei carichi di lavoro.

    gcloud iam service-accounts create SA_NAME
    

    Sostituisci quanto segue:

    • SA_NAME: il nome dell'account di servizio.
  2. Crea un account di servizio Kubernetes:

    kubectl create serviceaccount KSA_NAME --namespace NAMESPACE
    

    Sostituisci quanto segue:

    • KSA_NAME: il nome dell'account di servizio.
    • NAMESPACE: lo spazio dei nomi in cui creare l'account di servizio.
  3. Concedi all'account di servizio IAM l'accesso alle risorse a cui vuoi che acceda il carico di lavoro Kubernetes.

  4. Concedi il ruolo Utente Workload Identity (roles/iam.workloadIdentityUser) all'identità esterna dell'account di servizio 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"
    

    Sostituisci quanto segue:

    • SERVICE_ACCOUNT_EMAIL: l'indirizzo email dell'account di servizio
    • PROJECT_NUMBER: il numero di progetto del progetto che contiene il pool di identità per i carichi di lavoro.
    • POOL_ID: l'ID pool del pool di identità per i carichi di lavoro.
    • SUBJECT: il valore previsto per l'attributo che hai mappato a google.subject, ad esempio system:serviceaccount:NAMESPACE:KSA_NAME.

Esegui il deployment del carico di lavoro Kubernetes

Ora esegui il deployment di un carico di lavoro Kubernetes e consenti a quest'ultimo di utilizzare la coppia di account di servizio:

  1. Crea un file di configurazione delle credenziali:

    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
    

    Sostituisci quanto segue:

    • PROJECT_NUMBER: il numero del progetto che contiene il pool di identità per i carichi di lavoro
    • POOL_ID: l'ID del pool di identità per i carichi di lavoro
    • PROVIDER_ID: l'ID del provider del pool di identità per i carichi di lavoro
    • SERVICE_ACCOUNT_EMAIL: indirizzo email dell'account di servizio

    Il file di configurazione delle credenziali consente alle librerie client di Cloud, a gcloud CLI e a Terraform di determinare quanto segue:

    • Da dove ottenere le credenziali esterne
    • Provider di identità e pool di identità per i carichi di lavoro da utilizzare
    • Quale account di servizio utilizzare
  2. Importa il file di configurazione delle credenziali come ConfigMap:

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

    Sostituisci quanto segue:

    • CONFIGMAP_NAME: il nome del ConfigMap.
    • NAMESPACE: lo spazio dei nomi in cui creare l'oggetto ConfigMap.
  3. Eseguire il deployment di un carico di lavoro e consentirgli di utilizzare l'account di servizio Kubernetes e ConfigMap.

    Crea un manifest e configuralo come segue:

    • Monta un volume di token previsto in modo che il carico di lavoro possa ottenere un token dell'account di servizio Kubernetes da un file locale. Configura il volume in modo che il token dell'account di servizio Kubernetes utilizzi il pubblico previsto dal provider del pool di federazione delle identità per i carichi di lavoro.
    • Monta il ConfigMap che contiene il file di configurazione delle credenziali in modo che il carico di lavoro possa accedere alla configurazione necessaria per l'utilizzo della federazione delle identità per i carichi di lavoro.
    • Aggiungi una variabile di ambiente GOOGLE_APPLICATION_CREDENTIALS che contenga il percorso del file di configurazione delle credenziali in modo che i carichi di lavoro possano trovare il file.

    Di seguito è riportato un manifest di esempio che utilizza l'account di servizio Kubernetes e ConfigMap per consentire a Google Cloud CLI di eseguire l'autenticazione in 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
    

    Puoi seguire lo stesso approccio per consentire agli strumenti e ai carichi di lavoro che utilizzano una delle seguenti librerie client di trovare le credenziali automaticamente:

    C++

    Le librerie client di Google Cloud per C++ supportano la federazione delle identità per i carichi di lavoro a partire dalla versione v2.6.0. Per utilizzare la federazione delle identità per i carichi di lavoro, devi creare le librerie client con versione 1.36.0 o successiva di gRPC.

    Go

    Le librerie client per Go supportano la federazione delle identità se utilizzano la versione v0.0.0-20210218202405-ba52d332ba99 o successiva del modulo golang.org/x/oauth2.

    Per verificare quale versione di questo modulo utilizza la tua libreria client, esegui questi comandi:

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

    Java

    Le librerie client per Java supportano la federazione delle identità se utilizzano la versione 0.24.0 o successive dell'artefatto com.google.auth:google-auth-library-oauth2-http.

    Per verificare quale versione di questo artefatto utilizza la tua libreria client, esegui il seguente comando Maven nella directory dell'applicazione:

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

    Node.js

    Le librerie client per Node.js supportano la federazione delle identità per i carichi di lavoro se utilizzano la versione 7.0.2 o successiva del pacchetto google-auth-library.

    Per verificare quale versione di questo pacchetto viene utilizzata dalla tua libreria client, esegui questo comando nella directory dell'applicazione:

    npm list google-auth-library
    

    Quando crei un oggetto GoogleAuth, puoi specificare un ID progetto o consentire a GoogleAuth di trovare automaticamente l'ID progetto. Per trovare automaticamente l'ID progetto, l'account di servizio nel file di configurazione deve avere il ruolo Browser (roles/browser) o un ruolo con autorizzazioni equivalenti nel progetto. Per maggiori dettagli, consulta il documento README per il pacchetto google-auth-library.

    Python

    Le librerie client per Python supportano la federazione delle identità se utilizzano la versione 1.27.0 o successiva del pacchetto google-auth.

    Per verificare quale versione di questo pacchetto viene utilizzata dalla tua libreria client, esegui questo comando nell'ambiente in cui è installato il pacchetto:

    pip show google-auth
    

    Per specificare un ID progetto per il client di autenticazione, puoi impostare la variabile di ambiente GOOGLE_CLOUD_PROJECT o consentire al client di trovare automaticamente l'ID progetto. Per trovare automaticamente l'ID progetto, l'account di servizio nel file di configurazione deve avere il ruolo Browser (roles/browser) o un ruolo con autorizzazioni equivalenti nel progetto. Per i dettagli, consulta la guida dell'utente per il pacchetto google-auth.

    gcloud

    Per eseguire l'autenticazione con la federazione delle identità per i carichi di lavoro, utilizza il comando gcloud auth login:

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

    Sostituisci FILEPATH con il percorso del file di configurazione delle credenziali.

    Il supporto per la federazione delle identità per i carichi di lavoro in gcloud CLI è disponibile nella versione 363.0.0 e successive di gcloud CLI.

    Terraform

    Il provider Google Cloud supporta la federazione delle identità per i carichi di lavoro se utilizzi la versione 3.61.0 o successive:

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

    gsutil

    Per eseguire l'autenticazione con la federazione delle identità per i carichi di lavoro, utilizza uno dei seguenti metodi:

    Quando utilizzi gsutil in combinazione con gcloud, accedi normalmente:

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

    Quando utilizzi gsutil come applicazione a riga di comando autonoma, modifica il file .boto in modo da includere la seguente sezione:

    [Credentials]
    gs_external_account_file = FILEPATH
    

    In entrambi i casi, sostituisci FILEPATH con il percorso del file di configurazione delle credenziali.

    Il supporto per la federazione delle identità per i carichi di lavoro in gsutil è disponibile nella versione 379.0.0 e nelle versioni successive di gcloud CLI.

    bq

    Per eseguire l'autenticazione con la federazione delle identità per i carichi di lavoro, utilizza il comando gcloud auth login come segue:

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

    Sostituisci FILEPATH con il percorso del file di configurazione delle credenziali.

    Il supporto per la federazione delle identità per i carichi di lavoro in bq è disponibile nella versione 390.0.0 e successive di gcloud CLI.

  4. Facoltativamente, verifica che l'autenticazione funzioni correttamente eseguendo questo comando:

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

Passaggi successivi