Probleme mit der GKE-Authentifizierung beheben

Auf dieser Seite wird beschrieben, wie Sie Probleme im Zusammenhang mit Sicherheitskonfigurationen in Ihren Autopilot- und Standardclustern in Google Kubernetes Engine (GKE) beheben.

RBAC und IAM

Authentifizierte IAM-Konten können keine Aktionen im Cluster ausführen

Das folgende Problem tritt auf, wenn Sie versuchen, eine Aktion im Cluster auszuführen, GKE aber keine RBAC-Richtlinie finden kann, die die Aktion autorisiert. GKE versucht, eine IAM-Zulassungsrichtlinie zu finden, die dieselbe Berechtigung gewährt. Wenn dies fehlschlägt, wird eine Fehlermeldung wie die folgende angezeigt:

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).

Verwenden Sie zum Beheben dieses Problems eine RBAC-Richtlinie, um die Berechtigungen für die versuchte Aktion zu erteilen. Um das Problem im vorherigen Beispiel zu beheben, weisen Sie eine Rolle mit der Berechtigung list für roles-Objekte im Namespace kube-system zu. Eine Anleitung finden Sie unter Aktionen in Clustern mit rollenbasierter Zugriffssteuerung autorisieren.

Workload Identity Federation for GKE

Pod kann sich nicht bei Google Cloudauthentifizieren

Wenn sich Ihre Anwendung nicht bei Google Cloudauthentifizieren kann, prüfen Sie, ob die folgenden Einstellungen richtig konfiguriert sind:

  1. Achten Sie darauf, dass die IAM Service Account Credentials API in dem Projekt aktiviert ist, das den GKE-Cluster enthält.

    IAM Credentials API aktivieren

  2. Prüfen Sie, ob Workload Identity Federation for GKE im Cluster aktiviert ist. Prüfen Sie dazu, ob ein Workload Identity-Pool festgelegt ist:

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

    Ersetzen Sie dabei CLUSTER_NAME durch den Namen Ihres GKE-Clusters.

    Wenn Sie noch keine Standardzone oder -region für gcloud angegeben haben, müssen Sie beim Ausführen dieses Befehls evtl. das Flag --region oder --zone angeben.

  3. Der GKE-Metadatenserver muss im Knotenpool, in dem Ihre Anwendung ausgeführt wird, konfiguriert sein:

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

    Ersetzen Sie Folgendes:

    • NODEPOOL_NAME durch den Namen Ihres Knotenpools.
    • CLUSTER_NAME ist der Name des GKE-Clusters.
  4. Wenn Sie eine Cluster-Netzwerkrichtlinie haben, muss ausgehender Traffic zu 169.254.169.252/32 an Port 988 zugelassen werden. Für Cluster mit GKE Dataplane V2 müssen Sie ausgehenden Traffic an 169.254.169.254/32 an Port 80 zulassen.

    kubectl describe networkpolicy NETWORK_POLICY_NAME
    

    Ersetzen Sie NETWORK_POLICY_NAME durch den Namen Ihrer GKE-Netzwerkrichtlinie.

Wenn in Ihrer Konfiguration Kubernetes-Dienstkonten mit IAM-Dienstkonten verknüpft sind, prüfen Sie Folgendes:

  1. Prüfen Sie, ob das Kubernetes-Dienstkonto richtig annotiert ist:

    kubectl describe serviceaccount \
        --namespace NAMESPACE KSA_NAME
    

    Ersetzen Sie Folgendes:

    • NAMESPACE durch den Namespace Ihres GKE-Clusters.
    • KSA durch den Namen Ihres Kubernetes-Dienstkontos.

    Die erwartete Ausgabe enthält eine Annotation ähnlich der folgenden:

    iam.gke.io/gcp-service-account: GSA_NAME@PROJECT_ID.iam.gserviceaccount.com
    
  2. Prüfen Sie, ob das IAM-Dienstkonto richtig konfiguriert ist:

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

    Die erwartete Ausgabe enthält eine Bindung, die etwa so aussieht:

    - members:
      - serviceAccount:PROJECT_ID.svc.id.goog[NAMESPACE/KSA_NAME]
      role: roles/iam.workloadIdentityUser
    

Fehler: Ungültige Form der Konto-ID

Der folgende Fehler tritt auf, wenn Sie einen Vorgang ausführen, für den eine E-Mail-Adresse für ein IAM-Dienstkonto erforderlich ist, z. B. manuelles Erstellen einer signierten Cloud Storage-URL:

ERROR: Error: Invalid form of account ID test_account.svc.id.goog. Should be [Gaia ID |Email |Unique ID |] of the account
# Multiple lines are omitted here
command terminated with exit code 137

Dieser Fehler tritt auf, wenn Sie eine Annotation verwenden, um Kubernetes-Dienstkonten mit IAM-Dienstkonten zu verknüpfen, anstatt eine IAM-Hauptkonto-ID zum Konfigurieren von Workload Identity Federation for GKE zu verwenden.

Standardmäßig gibt der GKE-Metadatenserver den Wert SERVICEACCOUNT_NAME.svc.id.goog als Dienstkonto-ID für verknüpfte Dienstkonten zurück. Diese Kennung verwendet nicht die IAM-Hauptkonto-ID-Syntax.

Fügen Sie dem Kubernetes-Dienstkonto des Pods die Annotation iam.gke.io/return-principal-id-as-email="true" hinzu, um diesen Fehler zu beheben:

kubectl annotate serviceaccount KSA_NAME \
    --namespace=NAMESPACE \
    iam.gke.io/return-principal-id-as-email="true"

Ersetzen Sie Folgendes:

  • KSA_NAME: der Name des Kubernetes-ServiceAccount.
  • NAMESPACE: der Namespace des ServiceAccount.

Zugriff auf IAM-Dienstkonto verweigert

Pods können mit der Identitätsföderation von Arbeitslasten für GKE möglicherweise nicht auf eine Ressource zugreifen, nachdem sie IAM-Rollenbindungen hinzugefügt haben. Ein Zugriffsfehler tritt eher in Bereitstellungspipelines oder in deklarativen Google Cloud Konfigurationen auf, in denen Ressourcen wie IAM-Zulassungsrichtlinien, Rollenbindungen und Kubernetes-Pods zusammen erstellt werden. Die folgende Fehlermeldung wird in den Pod-Logs angezeigt:

HTTP/403: generic::permission_denied: loading: GenerateAccessToken("SERVICE_ACCOUNT_NAME@PROJECT_ID.iam.gserviceaccount.com", ""): googleapi: Error 403: Permission 'iam.serviceAccounts.getAccessToken' denied on resource (or it may not exist).

Dieser Fehler kann durch die Weitergabe von Zugriffsänderungen in IAM verursacht werden. Das bedeutet, dass Zugriffsänderungen wie Rollenzuweisungen einige Zeit benötigen, bis sie im gesamten System wirksam werden. Bei Rollenzuweisungen dauert die Weitergabe in der Regel etwa zwei Minuten, kann aber manchmal sieben oder mehr Minuten dauern. Weitere Informationen finden Sie unter Zugriffsänderungsverteilung.

Um diesen Fehler zu beheben, sollten Sie eine Verzögerung hinzufügen, bevor Ihre Pods nach dem Erstellen versuchen, auf Google Cloud -Ressourcen zuzugreifen.

Probleme mit der DNS-Auflösung

In diesem Abschnitt wird beschrieben, wie Sie Verbindungsfehler von Pods zu Google Cloud APIs identifizieren und beheben, die durch DNS-Auflösungsprobleme verursacht werden. Wenn die Schritte in diesem Abschnitt Ihre Verbindungsfehler nicht beheben, lesen Sie den Abschnitt Zeitüberschreitungsfehler beim Pod-Start.

Einige Google Cloud Clientbibliotheken sind für die Verbindung mit den GKE- und Compute Engine-Metadatenservern konfiguriert, indem der DNS-Name metadata.google.internal aufgelöst wird. Für diese Bibliotheken ist eine fehlerfreie DNS-Auflösung im Cluster von entscheidender Bedeutung für die Authentifizierung der Arbeitslasten beiGoogle Cloud -Diensten.

Wie Sie dieses Problem erkennen, hängt von den Details Ihrer bereitgestellten Anwendung ab, einschließlich der Logging-Konfiguration. Suchen Sie nach Fehlermeldungen, in denen Sie aufgefordert werden, GOOGLE_APPLICATION_CREDENTIALS zu konfigurieren, in denen Sie darüber informiert werden, dass Ihre Anfragen an einenGoogle Cloud -Dienst abgelehnt wurden, weil die Anfrage keine Anmeldedaten enthielt, oder in denen Sie darüber informiert werden, dass der Metadatenserver nicht gefunden wurde.

Die folgende Fehlermeldung kann beispielsweise auf ein Problem mit der DNS-Auflösung hinweisen:

ComputeEngineCredentials cannot find the metadata server. This is likely because code is not running on Google Compute Engine

Wenn Probleme mit der DNS-Auflösung von metadata.google.internal auftreten, können einige Google Cloud Clientbibliotheken angewiesen werden, die DNS-Auflösung zu überspringen, indem die Umgebungsvariable GCE_METADATA_HOST auf 169.254.169.254 festgelegt wird:

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"

Dies ist die hartcodierte IP-Adresse, unter der der Metadatendienst auf Google Cloud Computing-Plattformen immer verfügbar ist.

Die folgenden Google Cloud Bibliotheken werden unterstützt:

  • Python
  • Java
  • Node.js
  • Golang

    Standardmäßig stellt die Go-Clientbibliothek eine Verbindung über die IP-Adresse her.

Zeitüberschreitungsfehler beim Starten des Pods

Der GKE-Metadatenserver benötigt einige Sekunden, bevor er Anfragen von einem neuen Pod annehmen kann. Daher können Versuche, sich mithilfe der Workload Identity Federation for GKE innerhalb der ersten Sekunden der Lebensdauer eines Pods zu authentifizieren, bei Anwendungen und Google Cloud Clientbibliotheken, die nur mit einem kurzen Zeitlimit konfiguriert sind, fehlschlagen.

Wenn Zeitüberschreitungsfehler auftreten, versuchen Sie Folgendes:

  • Aktualisieren Sie die Google Cloud Clientbibliotheken, die von Ihren Arbeitslasten verwendet werden.
  • Ändern Sie den Anwendungscode. Warten Sie einige Sekunden und versuchen Sie es dann noch einmal.
  • Ein initContainer, der wartet, bis der GKE-Metadatenserver bereit ist, bevor er den Hauptcontainer des Pods ausführt.

    Das folgende Manifest gilt beispielsweise für einen Pod mit einem 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
    

Die Workload Identity Federation for GKE schlägt aufgrund der Nichtverfügbarkeit der Steuerungsebene fehl

Der Metadatenserver kann die Workload Identity Federation for GKE nicht zurückgeben, wenn die Clustersteuerungsebene nicht verfügbar ist. Aufrufe an den Metadatenserver geben den Statuscode 500 zurück.

Der Logeintrag kann im Log-Explorer etwa so aussehen:

dial tcp 35.232.136.58:443: connect: connection refused

Dieses Verhalten führt zur Nichtverfügbarkeit der Workload Identity Federation for GKE.

Die Steuerungsebene ist möglicherweise in zonalen Clustern bei Clusterwartungen wie dem Rotieren von IPs, dem Upgrade von Steuerungsebenen-VMs oder der Größenanpassung von Clustern oder Knotenpools nicht verfügbar. Weitere Informationen zur Verfügbarkeit der Steuerungsebene finden Sie unter Regionale oder zonale Steuerungsebene auswählen. Durch den Wechsel zu einem regionalen Cluster wird dieses Problem behoben.

Die Authentifizierung für Workload Identity Federation for GKE schlägt in Clustern mit Istio fehl

Möglicherweise werden Fehler wie die folgenden angezeigt, wenn Ihre Anwendung gestartet wird und versucht, mit einem Endpunkt zu kommunizieren:

Connection refused (169.254.169.254:80)
Connection timeout

Diese Fehler können auftreten, wenn Ihre Anwendung versucht, eine Netzwerkverbindung herzustellen, bevor der istio-proxy-Container bereit ist. Standardmäßig können Arbeitslasten in Istio und Cloud Service Mesh Anfragen senden, sobald sie gestartet werden. Das gilt unabhängig davon, ob die Arbeitslast des Service-Mesh-Proxys, die Traffic abfängt und weiterleitet, ausgeführt wird. Bei Pods, die Workload Identity Federation for GKE verwenden, erreichen diese ersten Anfragen, die vor dem Start des Proxys erfolgen, möglicherweise nicht den GKE-Metadatenserver. Daher schlägt die Authentifizierung bei Google Cloud APIs fehl. Wenn Sie Ihre Anwendungen nicht so konfigurieren, dass Anfragen wiederholt werden, schlagen Ihre Arbeitslasten möglicherweise fehl.

Sehen Sie sich Ihre Logs an und prüfen Sie, ob der istio-proxy-Container erfolgreich gestartet wurde, um zu bestätigen, dass dieses Problem die Ursache Ihrer Fehler ist:

  1. Rufen Sie in der Google Cloud Console die Seite Log-Explorer auf:

    Zum Log-Explorer

  2. Geben Sie im Bereich „Abfrage“ die folgende Abfrage ein:

    (resource.type="k8s_container"
    resource.labels.pod_name="POD_NAME"
    textPayload:"Envoy proxy is ready" OR textPayload:"ERROR_MESSAGE")
    OR
    (resource.type="k8s_pod"
    logName:"events"
    jsonPayload.involvedObject.name="POD_NAME")
    

    Ersetzen Sie Folgendes:

    • POD_NAME: Der Name des Pods mit dem betroffenen Arbeitslast.
    • ERROR_MESSAGE: Der Fehler, den die Anwendung erhalten hat (entweder connection timeout oder connection refused).
  3. Klicken Sie auf Abfrage ausführen.

  4. Prüfen Sie die Ausgabe und sehen Sie nach, wann der istio-proxy-Container bereit war.

    Im folgenden Beispiel hat die Anwendung versucht, einen gRPC-Aufruf zu starten. Da der istio-proxy-Container jedoch noch initialisiert wurde, hat die Anwendung einen Connection refused-Fehler erhalten. Der Zeitstempel neben der Meldung Envoy proxy is ready gibt an, wann der istio-proxy-Container für Verbindungsanfragen bereit war:

    2024-11-11T18:37:03Z started container istio-init
    2024-11-11T18:37:12Z started container gcs-fetch
    2024-11-11T18:37:42Z Initializing environment
    2024-11-11T18:37:55Z Started container istio-proxy
    2024-11-11T18:38:06Z StatusCode="Unavailable", Detail="Error starting gRPC call. HttpRequestException: Connection refused (169.254.169.254:80)
    2024-11-11T18:38:13Z Envoy proxy is ready
    

Um dieses Problem zu beheben und zu verhindern, dass es wieder auftritt, können Sie eine der folgenden Konfigurationsoptionen pro Arbeitslast ausprobieren:

  • Verhindern Sie, dass Ihre Anwendungen Anfragen senden, bis die Proxy-Arbeitslast bereit ist. Fügen Sie dem Feld metadata.annotations in der Pod-Spezifikation die folgende Annotation hinzu:

    proxy.istio.io/config: '{ "holdApplicationUntilProxyStarts": true }'
    
  • Konfigurieren Sie Istio oder Cloud Service Mesh so, dass die IP-Adresse des GKE-Metadatenservers nicht umgeleitet wird. Fügen Sie dem Feld metadata.annotations Ihrer Pod-Spezifikation die folgende Annotation hinzu:

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

Im Open-Source-Framework Istio können Sie dieses Problem optional für alle Pods beheben, indem Sie eine der folgenden globalen Konfigurationsoptionen festlegen:

  • IP-Adresse des GKE-Metadatenservers von der Weiterleitung ausschließen: Aktualisieren Sie die globale Konfigurationsoption global.proxy.excludeIPRanges, um den IP-Adressbereich 169.254.169.254/32 hinzuzufügen.

  • Verhindern, dass Anwendungen Anfragen senden, bevor der Proxy gestartet wird: Fügen Sie Ihrer Istio-Konfiguration die globale Konfigurationsoption global.proxy.holdApplicationUntilProxyStarts mit dem Wert true hinzu.

gke-metadata-server-Pod stürzt ab

Der gke-metadata-server-System-DaemonSet-Pod erleichtert Workload Identity Federation for GKE auf Ihren Knoten. Der Pod verwendet Arbeitsspeicherressourcen, die proportional zur Anzahl der Kubernetes-Dienstkonten in Ihrem Cluster sind.

Das folgende Problem tritt auf, wenn die Ressourcennutzung des Pods gke-metadata-server die Limits überschreitet. Das Kubelet entfernt den Pod mit einem Fehler aufgrund fehlenden Arbeitsspeichers. Dieses Problem kann auftreten, wenn Ihr Cluster mehr als 3.000 Kubernetes-Dienstkonten hat.

So erkennen Sie das Problem:

  1. Suchen Sie nach abstürzenden gke-metadata-server-Pods im Namespace kube-system:

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

    Die Ausgabe sieht etwa so aus:

    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. Beschreiben Sie den abstürzenden Pod, um zu bestätigen, dass die Ursache eine Bereinigung Fehler aufgrund fehlenden Arbeitsspeichers war:

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

    Ersetzen Sie POD_NAME durch den Namen des zu prüfenden Pods.

Wenn Sie die Funktion auf dem GKE-Metadatenserver wiederherstellen möchten, reduzieren Sie die Anzahl der Dienstkonten in Ihrem Cluster auf weniger als 3.000.

Workload Identity Federation for GKE kann nicht mit der Fehlermeldung „DeployPatch fehlgeschlagen“ aktiviert werden

GKE verwendet den von Google Cloudverwalteten Kubernetes Engine-Dienst-Agent, um die Identitätsföderation von Arbeitslasten für GKE in Ihren Clustern zu vereinfachen. Google Cloud weist diesem Dienst-Agent automatisch die Rolle des Kubernetes Engine-Dienst-Agents (roles/container.serviceAgent) für Ihr Projekt zu, wenn Sie die Google Kubernetes Engine API aktivieren.

Wenn Sie versuchen, Workload Identity Federation for GKE für Cluster in einem Projekt zu aktivieren, in dem der Dienst-Agent nicht die Rolle „Kubernetes Engine-Dienst-Agent“ hat, schlägt der Vorgang mit einer Fehlermeldung wie der folgenden fehl:

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

Versuchen Sie Folgendes, um dieses Problem zu beheben:

  1. Prüfen Sie, ob der Dienst-Agent in Ihrem Projekt vorhanden und korrekt konfiguriert ist:

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

    Ersetzen Sie PROJECT_ID durch Ihre Google CloudProjekt-ID.

    Wenn der Dienst-Agent ordnungsgemäß konfiguriert ist, zeigt die Ausgabe die vollständige Identität des Dienst-Agents an:

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

    Wenn in der Ausgabe der Dienst-Agent nicht angezeigt wird, müssen Sie ihm die Rolle „Kubernetes Engine-Dienst-Agent“ zuweisen. Zum Gewähren dieser Rolle müssen Sie die folgenden Schritte ausführen.

  2. Rufen Sie Ihre Google Cloud Projektnummer ab:

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

    Die Ausgabe sieht etwa so aus:

    123456789012
    
  3. Gewähren Sie dem Dienst-Agent die Rolle:

    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
    

    Ersetzen Sie PROJECT_NUMBER durch die Google CloudProjektnummer.

  4. Versuchen Sie noch einmal, die Workload Identity Federation for GKE zu aktivieren.

Nächste Schritte

  • Wenn Sie in der Dokumentation keine Lösung für Ihr Problem finden, lesen Sie den Abschnitt Support erhalten. Dort finden Sie weitere Hilfe, z. B. zu den folgenden Themen: