Risolvere i problemi di autenticazione di GKE


Questa pagina mostra come risolvere i problemi relativi alle configurazioni di sicurezza nei cluster Google Kubernetes Engine (GKE) Autopilot e Standard.

Se hai bisogno di ulteriore aiuto, contatta l'assistenza clienti Google Cloud.

RBAC e IAM

Gli account IAM autenticati non riescono a eseguire azioni nel cluster

Il seguente problema si verifica quando provi a eseguire un'azione nel cluster, ma GKE non riesce a trovare un criterio RBAC che autorizza l'azione. GKE cerca di trovare un criterio di autorizzazione IAM che conceda la stessa autorizzazione. Se il problema persiste, verrà visualizzato un messaggio di errore simile al seguente:

Error from server (Forbidden): roles.rbac.authorization.k8s.io is forbidden:
User "example-account@example-project.iam.gserviceaccount.com" cannot list resource "roles" in
API group "rbac.authorization.k8s.io" in the namespace "kube-system": requires
one of ["container.roles.list"] permission(s).

Per risolvere il problema, utilizza un criterio RBAC per concedere le autorizzazioni per l'azione tentata. Ad esempio, per risolvere il problema nell'esempio precedente, concedi un ruolo con l'autorizzazione list per gli oggetti roles nello spazio dei nomi kube-system. Per le istruzioni, consulta Autorizzare le azioni nei cluster utilizzando il controllo dell'accesso basato sui ruoli.

Federazione delle identità per i carichi di lavoro per GKE

Il pod non può eseguire l'autenticazione su Google Cloud

Se la tua applicazione non può eseguire l'autenticazione con Google Cloud, assicurati che le seguenti impostazioni siano configurate correttamente:

  1. Verifica di aver abilitato l'API IAM Service Accounts nel progetto contenente il cluster GKE.

    Abilita l'API IAM Credentials

  2. Conferma che la federazione di Workload Identity per GKE sia abilitata sul cluster verificando che sia impostato un pool di identità per i carichi di lavoro:

    gcloud container clusters describe CLUSTER_NAME \
        --format="value(workloadIdentityConfig.workloadPool)"
    

    Sostituisci CLUSTER_NAME con il nome del tuo cluster GKE.

    Se non hai ancora specificato una zona o una regione predefinita per gcloud, potresti dover specificare anche un flag --region o --zone quando esegui questo comando.

  3. Assicurati che il server metadati GKE sia configurato nel pool di nodi su cui è in esecuzione l'applicazione:

    gcloud container node-pools describe NODEPOOL_NAME \
        --cluster=CLUSTER_NAME \
        --format="value(config.workloadMetadataConfig.mode)"
    

    Sostituisci quanto segue:

    • NODEPOOL_NAME con il nome del tuo pool di nodi.
    • CLUSTER_NAME con il nome del tuo cluster GKE.
  4. Verifica che l'account di servizio Kubernetes sia annotato correttamente:

    kubectl describe serviceaccount \
        --namespace NAMESPACE KSA_NAME
    

    Sostituisci quanto segue:

    • NAMESPACE con lo spazio dei nomi del tuo cluster GKE.
    • KSA con il nome del tuo account di servizio Kubernetes.

    L'output previsto contiene un'annotazione simile alla seguente:

    iam.gke.io/gcp-service-account: GSA_NAME@PROJECT_ID.iam.gserviceaccount.com
    
  5. Verifica che l'account di servizio IAM sia configurato correttamente:

    gcloud iam service-accounts get-iam-policy \
        GSA_NAME@GSA_PROJECT.iam.gserviceaccount.com
    

    L'output previsto contiene un'associazione simile alla seguente:

    - members:
      - serviceAccount:PROJECT_ID.svc.id.goog[NAMESPACE/KSA_NAME]
      role: roles/iam.workloadIdentityUser
    
  6. Se hai un criterio di rete di cluster, devi consentire il traffico in uscita verso 127.0.0.1/32 sulla porta 988 per i cluster che eseguono versioni GKE precedenti alla 1.21.0-gke.1000 oppure verso 169.254.169.252/32 sulla porta 988 per i cluster che eseguono GKE versione 1.21.0-gke.1000 e successive. Per i cluster che eseguono GKE Dataplane V2, devi consentire il traffico in uscita verso 169.254.169.254/32 sulla porta 80.

    kubectl describe networkpolicy NETWORK_POLICY_NAME
    

    Sostituisci NETWORK_POLICY_NAME con il nome del tuo criterio di rete GKE.

Problemi di risoluzione DNS

Alcune librerie client di Google Cloud sono configurate per la connessione ai server di metadati GKE e Compute Engine risolvendo il nome DNS metadata.google.internal. Per queste librerie, la risoluzione del DNS nel cluster integro è una dipendenza fondamentale per l'autenticazione dei carichi di lavoro ai servizi Google Cloud.

La modalità di rilevamento di questo problema dipende dai dettagli dell'applicazione di cui è stato eseguito il deployment, inclusa la configurazione del logging. Cerca i messaggi di errore che:

  • ti chiede di configurare GOOGLE_APPLICATION_CREDENTIALS oppure
  • che le tue richieste a un servizio Google Cloud sono state respinte perché non avevano credenziali.

Se si verificano problemi con la risoluzione DNS di metadata.google.internal, è possibile indicare ad alcune librerie client di Google Cloud di ignorare la risoluzione DNS impostando la variabile di ambiente GCE_METADATA_HOST su 169.254.169.254:

apiVersion: v1
kind: Pod
metadata:
  name: example-pod
  namespace: default
spec:
  containers:
  - image: debian
    name: main
    command: ["sleep", "infinity"]
    env:
    - name: GCE_METADATA_HOST
      value: "169.254.169.254"

Si tratta dell'indirizzo IP hardcoded in cui il servizio di metadati è sempre disponibile sulle piattaforme di computing di Google Cloud.

Librerie Google Cloud supportate:

  • Python
  • Java
  • Node.js
  • Golang (Tieni presente, tuttavia, che la libreria client Golang preferisce già connettersi tramite IP, anziché tramite nome DNS).

Errori di timeout all'avvio del pod

Il server di metadati GKE ha bisogno di qualche secondo prima di poter iniziare ad accettare richieste su un nuovo pod. I tentativi di autenticazione utilizzando la federazione delle identità di Workload per GKE entro i primi secondi del ciclo di vita di un pod potrebbero non riuscire per le applicazioni e le librerie client di Google Cloud configurate con un breve timeout.

Se si verificano errori di timeout, prova a procedere nel seguente modo:

  • Aggiorna le librerie client di Google Cloud utilizzate dai carichi di lavoro.
  • Modifica il codice dell'applicazione per attendere qualche secondo e riprova.
  • Esegui il deployment di un initContainer che attende fino a quando il server di metadati GKE è pronto prima di eseguire il container principale del pod.

    Ad esempio, il manifest seguente è per un pod con initContainer:

    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-with-initcontainer
    spec:
      serviceAccountName: KSA_NAME
      initContainers:
      - image:  gcr.io/google.com/cloudsdktool/cloud-sdk:alpine
        name: workload-identity-initcontainer
        command:
        - '/bin/bash'
        - '-c'
        - |
          curl -sS -H 'Metadata-Flavor: Google' 'http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/token' --retry 30 --retry-connrefused --retry-max-time 60 --connect-timeout 3 --fail --retry-all-errors > /dev/null && exit 0 || echo 'Retry limit exceeded. Failed to wait for metadata server to be available. Check if the gke-metadata-server Pod in the kube-system namespace is healthy.' >&2; exit 1
      containers:
      - image: gcr.io/your-project/your-image
        name: your-main-application-container
    

La federazione delle identità per i carichi di lavoro per GKE non riesce a causa dell'indisponibilità del piano di controllo

Il server dei metadati non può restituire la federazione delle identità dei carichi di lavoro per GKE quando il piano di controllo del cluster non è disponibile. Le chiamate al server dei metadati restituiscono il codice di stato 500.

Potrebbe essere visualizzata una voce di log simile alla seguente in Esplora log:

dial tcp 35.232.136.58:443: connect: connection refused

Questo comportamento comporta l'indisponibilità della federazione di Workload Identity per GKE.

Il piano di controllo potrebbe non essere disponibile sui cluster di zona durante la manutenzione dei cluster, ad esempio la rotazione degli IP, l'upgrade delle VM del piano di controllo o il ridimensionamento dei cluster o dei pool di nodi. Per scoprire di più sulla disponibilità del piano di controllo, consulta Scelta di un piano di controllo a livello di regione o zona. Il passaggio a un cluster a livello di regione elimina questo problema.

La federazione delle identità per i carichi di lavoro per l'autenticazione GKE non riesce nei cluster che utilizzano Istio

Se per qualsiasi motivo il server di metadati GKE è bloccato, la federazione delle identità di Workload per l'autenticazione GKE non va a buon fine.

Se utilizzi Istio o Anthos Service Mesh, aggiungi la seguente annotazione a livello di pod a tutti i carichi di lavoro che utilizzano la federazione delle identità per i carichi di lavoro per GKE per escludere l'IP dal reindirizzamento:

traffic.sidecar.istio.io/excludeOutboundIPRanges: 169.254.169.254/32

Puoi modificare la chiave global.proxy.excludeIPRanges Istio ConfigMap per fare lo stesso.

In alternativa, puoi anche aggiungere la seguente annotazione a livello di pod a tutti i carichi di lavoro che utilizzano la federazione delle identità per i carichi di lavoro per GKE, in modo da ritardare l'avvio del container dell'applicazione finché il file collaterale non è pronto:

proxy.istio.io/config: '{ "holdApplicationUntilProxyStarts": true }'

Puoi modificare la chiave global.proxy.holdApplicationUntilProxyStarts Istio ConfigMap per fare lo stesso.

gke-metadata-server pod si arresta in modo anomalo

Il pod DaemonSet del sistema gke-metadata-server facilita la federazione delle identità dei carichi di lavoro per GKE sui tuoi nodi. Il pod utilizza risorse di memoria in proporzione al numero di account di servizio Kubernetes nel cluster.

Il seguente problema si verifica quando l'utilizzo delle risorse del pod gke-metadata-server supera i limiti. Il kubelet rimuove il pod con un errore di memoria insufficiente. Potresti riscontrare questo problema se il cluster ha più di 3000 account di servizio Kubernetes.

Per identificare il problema:

  1. Trova pod gke-metadata-server con arresto anomalo nello spazio dei nomi kube-system:

    kubectl get pods -n=kube-system | grep CrashLoopBackOff
    

    L'output è simile al seguente:

    NAMESPACE     NAME                        READY     STATUS             RESTARTS   AGE
    kube-system   gke-metadata-server-8sm2l   0/1       CrashLoopBackOff   194        16h
    kube-system   gke-metadata-server-hfs6l   0/1       CrashLoopBackOff   1369       111d
    kube-system   gke-metadata-server-hvtzn   0/1       CrashLoopBackOff   669        111d
    kube-system   gke-metadata-server-swhbb   0/1       CrashLoopBackOff   30         136m
    kube-system   gke-metadata-server-x4bl4   0/1       CrashLoopBackOff   7          15m
    
  2. Descrivi il pod in arresto anomalo per confermare che la causa sia l'eliminazione della memoria:

    kubectl describe pod POD_NAME --namespace=kube-system | grep OOMKilled
    

    Sostituisci POD_NAME con il nome del pod da verificare.

Per ripristinare la funzionalità al server di metadati GKE, riduci il numero di account di servizio nel cluster a meno di 3000.

Messaggio di errore di abilitazione della federazione di Workload Identity per GKE con DeployPatch non riuscito

GKE utilizza l'agente di servizio Kubernetes Engine gestito da Google Cloud per facilitare la federazione di Workload Identity per GKE nei tuoi cluster. Google Cloud concede automaticamente a questo agente di servizio il ruolo Agente di servizio Kubernetes Engine (roles/container.serviceAgent) sul tuo progetto quando abiliti l'API Google Kubernetes Engine.

Se provi ad abilitare la federazione delle identità per i carichi di lavoro per GKE sui cluster in un progetto in cui l'agente di servizio non ha il ruolo Agente di servizio Kubernetes Engine, l'operazione non va a buon fine e viene visualizzato un messaggio di errore simile al seguente:

Error waiting for updating GKE cluster workload identity config: DeployPatch failed

Per risolvere il problema, prova a procedere nel seguente modo:

  1. Controlla se l'agente di servizio esiste nel progetto e sia configurato correttamente:

    gcloud projects get-iam-policy PROJECT_ID \
        --flatten=bindings \
        --filter=bindings.role=roles/container.serviceAgent \
        --format="value[delimiter='\\n'](bindings.members)"
    

    Sostituisci PROJECT_ID con l'ID progetto Google Cloud.

    Se l'agente di servizio è configurato correttamente, l'output mostra l'identità completa dell'agente di servizio:

    serviceAccount:service-PROJECT_NUMBER@container-engine-robot.iam.gserviceaccount.com
    

    Se nell'output non viene visualizzato l'agente di servizio, devi concedergli il ruolo Agente di servizio Kubernetes Engine. Per concedere questo ruolo, completa i passaggi seguenti.

  2. Recupera il numero del tuo progetto Google Cloud:

    gcloud projects describe PROJECT_ID \
        --format="value(projectNumber)"
    

    L'output è simile al seguente:

    123456789012
    
  3. Concedi all'agente di servizio il ruolo:

    gcloud projects add-iam-policy-binding PROJECT_ID \
        --member=serviceAccount:service-PROJECT_NUMBER@container-engine-robot.iam.gserviceaccount.com \
        --role=roles/container.serviceAgent \
        --condition=None
    

    Sostituisci PROJECT_NUMBER con il numero del tuo progetto Google Cloud.

  4. Prova ad abilitare di nuovo la federazione di Workload Identity per GKE.

Passaggi successivi

Se hai bisogno di ulteriore aiuto, contatta l'assistenza clienti Google Cloud.