Fehlerbehebung


Hier finden Sie Informationen zur Fehlerbehebung, die bei Problemen mit Google Kubernetes Engine (GKE) hilfreich sein können.

Wenn Sie weitere Unterstützung benötigen, wenden Sie sich an den Cloud Customer Care.

Kubernetes-Ressourcen debuggen

Wenn bei Ihrem Cluster ein Problem auftritt, lesen Sie den Abschnitt Fehlerbehebung bei Clustern in der Kubernetes-Dokumentation.

Falls bei Ihrer Anwendung, den zugehörigen Pods oder dem Controllerobjekt ein Problem auftritt, lesen Sie die Fehlerbehebung für Anwendungen.

Wenn Sie ein Problem mit der Verbindung zwischen Compute Engine-VMs haben, die sich im selben Virtual Private Cloud-Netzwerk (VPC) oder zwei VPC-Netzwerken befinden, die mit VPC-Netzwerk-Peering verbunden sind, lesen Sie die Informationen unter Fehlerbehebung Verbindung zwischen VM-Instanzen mit internen IP-Adressen

Wenn Paketverluste beim Senden von Traffic von einem Cluster an eine externe IP-Adresse mit Cloud NAT, VPC-nativen Clustern oder IP-Masquerade-Agent auftreten, finden Sie Informationen unter Fehlerbehebung bei Cloud NAT-Paketverlusten aus einem GKE-Cluster.

Fehlerbehebung mit dem Befehl kubectl

Befehl kubectl wurde nicht gefunden

  1. Installieren Sie die Binärdatei kubectl mit dem folgenden Befehl:

    gcloud components update kubectl
    
  2. Antworten Sie mit "yes" (Ja), wenn das Installationsprogramm Sie dazu auffordert, Ihre Umgebungsvariable $PATH zu ändern. Durch die Änderung dieser Variablen können Sie kubectl-Befehle verwenden, ohne den vollständigen Dateipfad eingeben zu müssen.

    Alternativ können Sie in ~/.bashrc (oder ~/.bash_profile unter macOS oder am jeweiligen Speicherort für Umgebungsvariablen in der verwendeten Shell) die folgende Zeile hinzufügen:

    export PATH=$PATH:/usr/local/share/google/google-cloud-sdk/bin/
    
  3. Führen Sie den folgenden Befehl aus, um die aktualisierte Datei .bashrc oder .bash_profile zu laden:

    source ~/.bashrc
    

kubectl-Befehle geben den Fehler "Verbindung verweigert" aus

Legen Sie den Cluster-Kontext mit folgendem Befehl fest:

gcloud container clusters get-credentials CLUSTER_NAME

Wenn Sie nicht sicher sind, welchen Wert Sie für CLUSTER_NAME eingeben sollen, können Sie den folgenden Befehl verwenden, um die vorhandenen Cluster aufzulisten:

gcloud container clusters list

kubectl-Befehl überschreitet das Zeitlimit

Nach dem Erstellen eines Clusters wird beim Versuch, den Befehl kubectl für den Cluster auszuführen, ein Fehler wie Unable to connect to the server: dial tcp IP_ADDRESS: connect: connection timed out oder Unable to connect to the server: dial tcp IP_ADDRESS: i/o timeout zurückgegeben.

Das kann passieren, wenn kubectl nicht mit der Cluster-Steuerungsebene kommunizieren kann.

Prüfen Sie zur Behebung dieses Problems, ob der Kontext für den Cluster festgelegt ist:

  1. Rufen Sie $HOME/.kube/config auf oder führen Sie den Befehl kubectl config view aus, um zu prüfen, ob die Konfigurationsdatei den Clusterkontext und die externe IP-Adresse der Steuerungsebene enthält.

  2. Legen Sie die Clusteranmeldedaten fest:

    gcloud container clusters get-credentials CLUSTER_NAME \
        --location=COMPUTE_LOCATION \
        --project=PROJECT_ID
    

    Ersetzen Sie Folgendes:

    • CLUSTER_NAME: Der Name Ihres Clusters.
    • COMPUTE_LOCATION: der Compute Engine-Standort.
    • PROJECT_ID ist die ID des Projekts, in dem der GKE-Cluster erstellt wurde.
  3. Wenn der Cluster ein privater GKE-Cluster ist, prüfen Sie, ob die ausgehende IP-Adresse der Maschine, von der Sie eine Verbindung herstellen möchten, in der Liste der vorhandenen autorisierten Netzwerke enthalten ist. Sie finden Ihre autorisierten Netzwerke in der Console oder durch Ausführen des folgenden Befehls:

    gcloud container clusters describe CLUSTER_NAME \
        --location=COMPUTE_LOCATION \
        --project=PROJECT_ID \
        --format "flattened(masterAuthorizedNetworksConfig.cidrBlocks[])"
    

Wenn die ausgehende IP-Adresse des Computers nicht in der Liste der autorisierten Netzwerke aus der Ausgabe des obigen Befehls enthalten ist, führen Sie die Schritte unter Steuerungsebenen eines privaten Clusters können nicht erreicht werden oder Mit Cloud Shell auf einen privaten Cluster zugreifen aus, wenn Sie eine Verbindung von Cloud Shell aus herstellen.

kubectl-Befehle geben den Fehler "Es konnte keine API-Version festgelegt werden" aus

Achten Sie darauf, dass kubectl über die Anmeldedaten für die Authentifizierung verfügt:

gcloud auth application-default login

Die Befehle kubectl logs, attach, exec und port-forward reagieren nicht mehr

Diese Befehle sind davon abhängig, dass die Cluster-Steuerungsebene (Master) mit den Knoten im Cluster kommunizieren kann. Da sich die Steuerungsebene jedoch nicht im gleichen Compute Engine-Netzwerk befindet wie die Knoten des Clusters, sind für die Aktivierung entweder SSH- oder Konnectivity-Proxy-Tunnel für eine sichere Kommunikation erforderlich.

GKE speichert eine Datei mit dem öffentlichen SSH-Schlüssel in den Metadaten Ihres Compute Engine-Projekts. Alle Compute Engine-VMs, die von Google bereitgestellte Images verwenden, prüfen regelmäßig die allgemeinen Metadaten ihres Projekts und die Instanzmetadaten auf SSH-Schlüssel, um diese der Liste mit autorisierten Nutzern der VM hinzuzufügen. GKE fügt dem Compute Engine-Netzwerk außerdem eine Firewallregel hinzu, mit der der SSH-Zugriff von der IP-Adresse der Steuerungsebene auf jeden Knoten im Cluster möglich ist.

Wenn einer der oben aufgeführten kubectl-Befehle nicht funktioniert, kann der API-Server wahrscheinlich nicht mit den Knoten kommunizieren. Prüfen Sie folgenden möglichen Ursachen:

  • Der Cluster hat keine Knoten.

    Wenn Sie die Anzahl der Knoten in Ihrem Cluster bis auf null reduziert haben, funktionieren SSH-Tunnel nicht.

    Passen Sie die Größe Ihres Clusters an, um das Problem zu beheben. Es muss mindestens ein Knoten vorhanden sein.

SSH

  • Die Firewallregeln Ihres Netzwerks lassen keinen SSH-Zugriff auf die Steuerungsebene zu.

    Alle Compute Engine-Netzwerke werden mit einer Firewallregel mit dem Namen default-allow-ssh erstellt, die den SSH-Zugriff über alle IP-Adressen ermöglicht (erfordert selbstverständlich einen gültigen privaten Schlüssel). Von GKE wird darüber hinaus für jeden öffentlichen Cluster eine SSH-Regel der Form gke-CLUSTER_NAME-RANDOM_CHARACTERS-ssh eingefügt, mit der der SSH-Zugriff speziell von der Steuerungsebene des Clusters auf dessen Knoten möglich ist. Wenn keine dieser Regeln existiert, kann die Steuerungsebene keine SSH-Tunnel öffnen.

    Fügen Sie zum Beheben des Problems noch einmal eine Firewallregel hinzu, die den Zugriff auf VMs mit dem Tag ermöglicht, das sich auf allen Clusterknoten von der IP-Adresse der Steuerungsebene befindet.

  • Der allgemeine Metadateneintrag Ihres Projekts für "ssh-keys" ist voll.

    Wenn der Metadateneintrag "ssh-keys" des Projekts nahe der maximalen Größe liegt, kann GKE keinen eigenen SSH-Schlüssel hinzufügen, um SSH-Tunnel zu öffnen. Sie können die Metadaten Ihres Projekts mit dem folgenden Befehl aufrufen:

    gcloud compute project-info describe [--project=PROJECT_ID]
    

    Prüfen Sie dann die Länge der Liste "ssh-keys".

    Löschen Sie zum Beheben dieses Problems einige SSH-Schlüssel, die nicht mehr benötigt werden.

  • Sie haben auf den VMs im Cluster für ein Metadatenfeld den Schlüssel „ssh-keys“ festgelegt.

    Der Knoten-Agent auf VMs bevorzugt pro Instanz zugewiesene SSH-Schlüssel gegenüber projektweiten SSH-Schlüsseln. Wenn Sie also speziell auf den Clusterknoten SSH-Schlüssel eingerichtet haben, dann wird der SSH-Schlüssel der Steuerungsebene in den Projektmetadaten von den Knoten nicht beachtet. Führen Sie zum Prüfen gcloud compute instances describe VM_NAME aus und suchen Sie in den Metadaten das Feld ssh-keys.

    Löschen Sie zum Beheben des Problems die pro Instanz zugewiesenen SSH-Schlüssel aus den Instanzmetadaten.

Konnektivitätsproxy

  • Ermitteln Sie, ob Ihr Cluster den Konnectivity-Proxy verwendet. Prüfen Sie dazu die folgende Systembereitstellung:

    kubectl get deployments konnectivity-agent --namespace kube-system
    
  • Die Firewallregeln Ihres Netzwerks lassen keinen Zugriff des Konnectivity-Agents auf die Steuerungsebene zu.

    Beim Erstellen des Clusters stellen die Konnectivity-Agent-Pods eine Verbindung zur Steuerungsebene an Port 8132 her und aufrechterhalten. Wenn einer der kubectl-Befehle ausgeführt wird, verwendet der API-Server diese Verbindung, um mit dem Cluster zu kommunizieren.

    Wenn die Firewallregeln Ihres Netzwerks Regeln zum Ablehnen von ausgehendem Traffic enthalten, kann der Agent keine Verbindung herstellen. Sie müssen ausgehenden Traffic zur Steuerungsebene des Clusters an Port 8132 zulassen. (Zum Vergleich: Der API-Server verwendet 443).

  • Die Netzwerkrichtlinie Ihres Clusters blockiert eingehenden Traffic vom Namespace kube-system zum Namespace workload. Führen Sie den folgenden Befehl aus, um Netzwerkrichtlinien im betroffenen Namespace zu suchen:

    kubectl get networkpolicy --namespace AFFECTED_NAMESPACE
    

    Fügen Sie dem Feld spec.ingress der Netzwerkrichtlinien Folgendes hinzu, um das Problem zu beheben:

    - from:
      - namespaceSelector:
          matchLabels:
            kubernetes.io/metadata.name: kube-system
        podSelector:
          matchLabels:
            k8s-app: konnectivity-agent
    

Diese Funktionen sind für ein korrektes Funktionieren des Clusters nicht erforderlich. Wenn Sie es vorziehen, Ihr Clusternetzwerk für alle externen Zugriffe zu sperren, können Sie Funktionen wie diese nicht mehr verwenden.

Fehler 4xx beheben

Authentifizierungs- und Autorisierungsfehler beim Herstellen einer Verbindung zu GKE-Clustern

Dieses Problem kann auftreten, wenn Sie versuchen, einen kubectl-Befehl in Ihrem GKE-Cluster von einer lokalen Umgebung aus auszuführen. Der Befehl schlägt fehl und zeigt eine Fehlermeldung an, normalerweise mit dem HTTP-Statuscode 401 (Unauthorized).

Mögliche Ursachen für das Problem:

  • Das Authentifizierungs-Plug-in gke-gcloud-auth-plugin ist nicht ordnungsgemäß installiert oder konfiguriert.
  • Sie sind nicht berechtigt, eine Verbindung zum Cluster-API-Server herzustellen und kubectl-Befehle auszuführen.

So diagnostizieren Sie die Ursache:

Mit curl eine Verbindung zum Cluster herstellen

Mit curl werden die kubectl CLI und das Plug-in gke-gcloud-auth-plugin umgangen.

  1. Legen Sie Umgebungsvariablen fest:

    APISERVER=https://$(gcloud container clusters describe CLUSTER_NAME --location=COMPUTE_LOCATION --format "value(endpoint)")
    TOKEN=$(gcloud auth print-access-token)
    
  2. Prüfen Sie, ob Ihr Zugriffstoken gültig ist:

    curl https://oauth2.googleapis.com/tokeninfo?access_token=$TOKEN
    
  3. Prüfen Sie, ob Sie eine Verbindung zum Kern-API-Endpunkt auf dem API-Server herstellen können:

    gcloud container clusters describe CLUSTER_NAME --location=COMPUTE_LOCATION --format "value(masterAuth.clusterCaCertificate)" | base64 -d > /tmp/ca.crt
    curl -s -X GET "${APISERVER}/api/v1/namespaces" --header "Authorization: Bearer $TOKEN" --cacert /tmp/ca.crt
    

Wenn der Befehl curl mit einer Ausgabe wie der folgenden fehlschlägt, prüfen Sie, ob Sie die erforderlichen Berechtigungen für den Zugriff auf den Cluster haben:

{
"kind": "Status",
"apiVersion": "v1",
"metadata": {},
"status": "Failure",
"message": "Unauthorized",
"reason": "Unauthorized",
"code": 401
}

Wenn der Befehl curl erfolgreich ist, prüfen Sie, ob das Plug-in die Ursache ist.

Plug-in in kubeconfig konfigurieren

Mit den folgenden Schritten wird Ihre lokale Umgebung so konfiguriert, dass die Binärdatei gke-gcloud-auth-plugin bei der Authentifizierung beim Cluster ignoriert wird. In Kubernetes-Clients mit Version 1.25 und höher ist die Binärdatei gke-gcloud-auth-plugin erforderlich. Führen Sie daher die folgenden Schritte aus, wenn Sie ohne das Plug-in auf Ihren Cluster zugreifen möchten.

  1. Installieren Sie die Version 1.24 der kubectl CLI mit curl:

    curl -LO https://dl.k8s.io/release/v1.24.0/bin/linux/amd64/kubectl
    

    Sie können eine beliebige kubectl-CLI-Version 1.24 oder früher verwenden.

  2. Öffnen Sie die Shell-Startskriptdatei, z. B. .bashrc für die Bash-Shell, in einem Texteditor:

    vi ~/.bashrc
    
  3. Fügen Sie der Datei die folgende Zeile hinzu und speichern Sie sie:

    export USE_GKE_GCLOUD_AUTH_PLUGIN=False
    
  4. Führen Sie das Startskript aus:

    source ~/.bashrc
    
  5. Rufen Sie die Anmeldedaten für Ihren Cluster ab, mit dem die .kube/config-Datei eingerichtet wird:

    gcloud container clusters get-credentials CLUSTER_NAME \
        --location=COMPUTE_LOCATION
    

    Ersetzen Sie Folgendes:

  6. Führen Sie einen kubectl-Befehl aus:

    kubectl cluster-info
    

Wenn Sie einen 401-Fehler oder einen ähnlichen Autorisierungsfehler erhalten, prüfen Sie, ob Sie die erforderlichen Berechtigungen zum Ausführen des Vorgangs haben.

Fehler 400: Knotenpool muss neu erstellt werden

Das folgende Problem tritt auf, wenn Sie versuchen, eine Aktion auszuführen, mit der Ihre Steuerungsebene und Ihre Knoten neu erstellt werden, z. B. wenn Sie eine laufende Rotation von Anmeldedaten durchführen.

Der Vorgang schlägt fehl, da GKE keinen oder mehrere Knotenpools in Ihrem Cluster neu erstellt hat. Im Back-End werden Knotenpools zur Neuerstellung markiert. Der eigentliche Neuerstellungsvorgang kann jedoch einige Zeit in Anspruch nehmen.

Die Fehlermeldung sieht etwa so aus:

ERROR: (gcloud.container.clusters.update) ResponseError: code=400, message=Node pool "test-pool-1" requires recreation.

Führen Sie einen der folgenden Schritte aus, um das Problem zu lösen:

  • Warten Sie, bis die Neuerstellung abgeschlossen ist. Dies kann je nach Faktoren wie vorhandenen Wartungsfenstern und -ausschlüssen Stunden, Tage oder Wochen dauern.
  • Starten Sie eine Neuerstellung der betroffenen Knotenpools manuell. Starten Sie dazu ein Versionsupgrade auf dieselbe Version wie die Steuerungsebene. Führen Sie den folgenden Befehl aus, um eine Neuerstellung zu starten:

    gcloud container clusters upgrade CLUSTER_NAME \
        --node-pool=POOL_NAME
    

    Führen Sie den Vorgang nach Abschluss des Upgrades noch einmal aus.

Fehler 403: Unzureichende Berechtigungen

Der folgende Fehler tritt auf, wenn Sie versuchen, mit gcloud container clusters get-credentials eine Verbindung zu einem GKE-Cluster herzustellen, das Konto aber keine Berechtigung für den Zugriff auf den Kubernetes API-Server hat.

ERROR: (gcloud.container.clusters.get-credentials) ResponseError: code=403, message=Required "container.clusters.get" permission(s) for "projects/<your-project>/locations/<region>/clusters/<your-cluster>".

So beheben Sie das Problem:

  1. Ermitteln Sie das Konto mit dem Zugriffsproblem:

    gcloud auth list
    
  2. Gewähren Sie den erforderlichen Zugriff auf das Konto. Folgen Sie dazu der Anleitung unter Authentifizierung beim Kubernetes API-Server.

Fehler 404: Ressource "nicht gefunden" nach Aufrufen von gcloud container-Befehlen

Authentifizieren Sie sich noch einmal bei der Google Cloud CLI:

gcloud auth login

Fehler 400/403: Dem Konto fehlen Bearbeitungsberechtigungen

Ihr Compute Engine-Standarddienstkonto, der Google APIs-Dienst-Agent oder das GKE zugeordnete Dienstkonto wurden gelöscht oder manuell bearbeitet.

Wenn Sie die Compute Engine API oder die Kubernetes Engine API aktivieren, erstellt Google Cloud die folgenden Dienstkonten und Agents:

  • Compute Engine-Standarddienstkonto mit Bearbeitungsberechtigungen für Ihr Projekt
  • Google APIs-Dienst-Agent mit Bearbeitungsberechtigungen für Ihr Projekt
  • Google Kubernetes Engine-Dienstkonto mit der Rolle Kubernetes Engine-Dienst-Agent für Ihr Projekt.

Falls Sie diese Berechtigungen bearbeiten, die Rollenbindungen für das Projekt entfernen, das Dienstkonto vollständig entfernen oder die API deaktivieren, schlagen das Erstellen des Clusters und sämtliche Verwaltungsfunktionen fehl.

Der Name Ihres Google Kubernetes Engine-Dienstkontos lautet folgendermaßen, wobei PROJECT_NUMBER Ihre Projektnummer ist:

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

Mit dem folgenden Befehl können Sie prüfen, ob dem Google Kubernetes Engine-Dienstkonto die Rolle Kubernetes Engine-Dienst-Agent für das Projekt zugewiesen ist:

gcloud projects get-iam-policy PROJECT_ID

Ersetzen Sie PROJECT_ID durch Ihre Projekt-ID.

Falls Sie die Rolle Kubernetes Engine-Dienst-Agent aus Ihrem Google Kubernetes Engine-Dienstkonto entfernt haben, fügen Sie sie wieder hinzu, um das Problem zu beheben. Andernfalls müssen Sie die Kubernetes Engine API wieder aktivieren, damit die Dienstkonten und Berechtigungen korrekt wiederhergestellt werden.

Console

  1. Rufen Sie in der Google Cloud Console die Seite APIs & Dienste auf.

    Rufen Sie "APIs & Dienste" auf.

  2. Wählen Sie Ihr Projekt aus.

  3. Klicken Sie auf APIs und Dienste aktivieren.

  4. Suchen Sie "Kubernetes" und wählen Sie anschließend in den Suchergebnissen die API aus.

  5. Klicken Sie auf Aktivieren. Wenn Sie die API bereits aktiviert hatten, deaktivieren Sie sie und aktivieren Sie sie dann noch einmal. Es kann einige Minuten dauern, bis die API und zugehörige Dienste aktiviert werden.

gcloud

Führen Sie den folgenden Befehl in der gcloud CLI aus, um das Dienstkonto wieder hinzuzufügen:

PROJECT_NUMBER=$(gcloud projects describe "PROJECT_ID" --format 'get(projectNumber)')
gcloud projects add-iam-policy-binding PROJECT_ID \
 --member "serviceAccount:service-${PROJECT_NUMBER?}@container-engine-robot.iam.gserviceaccount.com" \
 --role roles/container.serviceAgent

Probleme bei der Erstellung von GKE-Clustern beheben

Fehler CONDITION_NOT_MET: Verstoß gegen die Einschränkung constraints/compute.vmExternalIpAccess

Sie haben die Organisationsrichtlinien-Einschränkung constraints/compute.vmExternalIpAccess auf Deny All konfiguriert oder die externen IP-Adressen auf bestimmte VM-Instanzen auf Organisations-, Ordner- oder Projektebene beschränkt, in der Sie versuchen, einen öffentlichen GKE-Cluster zu erstellen.

Wenn Sie öffentliche GKE-Cluster erstellen, werden den zugrunde liegenden Compute Engine-VMs, aus denen die Worker-Knoten dieses Clusters bestehen, externe IP-Adressen zugewiesen. Wenn Sie die Organisationsrichtlinien-Einschränkung constraints/compute.vmExternalIpAccess auf Deny All konfigurieren oder externe IP-Adressen auf bestimmte VM-Instanzen beschränken, verhindert die Richtlinie, dass die GKE-Worker-Knoten externe IP-Adressen abrufen. Dies führt zu Fehlschlägen bei der Clustererstellung.

Um die Logs der Clustererstellung zu finden, können Sie die Audit-Logs für GKE-Clustervorgänge mit dem Log-Explorer mit einer Suchanfrage ähnlich der folgenden prüfen:

resource.type="gke_cluster"
logName="projects/test-last-gke-sa/logs/cloudaudit.googleapis.com%2Factivity"
protoPayload.methodName="google.container.v1beta1.ClusterManager.CreateCluster"
resource.labels.cluster_name="CLUSTER_NAME"
resource.labels.project_id="PROJECT_ID"

Achten Sie zur Behebung dieses Problems darauf, dass die geltende Richtlinie für die Einschränkung constraints/compute.vmExternalIpAccess für das Projekt Allow All ist, in dem Sie einen öffentlichen GKE-Cluster erstellen möchten. Informationen zum Arbeiten mit dieser Einschränkung finden Sie unter Externe IP-Adressen auf bestimmte VM-Instanzen beschränken. Nachdem Sie die Einschränkung auf Allow All gesetzt haben, löschen Sie den fehlgeschlagenen Cluster und erstellen Sie einen neuen Cluster. Dies ist erforderlich, da der fehlgeschlagene Cluster nicht repariert werden kann.

Probleme mit bereitgestellten Arbeitslasten beheben

Bei Problemen mit den Pods einer Arbeitslast wird von GKE ein Fehler zurückgegeben. Sie können den Status eines Pods mit dem kubectl-Befehlszeilentool oder der Google Cloud Console prüfen.

kubectl

Führen Sie den folgenden Befehl aus, um alle in Ihrem Cluster ausgeführten Pods anzusehen:

kubectl get pods

Ausgabe:

NAME       READY  STATUS             RESTARTS  AGE
POD_NAME   0/1    CrashLoopBackOff   23        8d

Führen Sie den folgenden Befehl aus, um weitere Details zu einem bestimmten Pod abzurufen:

kubectl describe pod POD_NAME

Ersetzen Sie POD_NAME durch den Namen des gewünschten Pods.

Console

Führen Sie diese Schritte aus:

  1. Rufen Sie in der Google Cloud Console die Seite Arbeitslasten auf.

    Zu Arbeitslasten

  2. Wählen Sie die gewünschte Arbeitslast aus. Auf dem Tab Übersicht wird der Status der Arbeitslast angezeigt.

  3. Klicken Sie im Abschnitt Verwaltete Pods auf die Fehlerstatusmeldung.

In den folgenden Abschnitten werden einige häufig von Arbeitslasten zurückgegebene Fehler erläutert und ihre Behebung erklärt.

CrashLoopBackOff

Der Fehler CrashLoopBackOff gibt an, dass ein Container nach dem Neustart wiederholt abstürzt. Ein Container kann aus verschiedenen Gründen abstürzen. Hier kann ein Blick in die Logs eines Pods helfen, die Ursache zu beheben.

Abgestürzte Container werden standardmäßig mit einer auf fünf Minuten begrenzten exponentiellen Verzögerung neu gestartet. Dieses Verhalten können Sie dadurch ändern, dass Sie in der Pod-Spezifikation des Deployments unter spec: restartPolicy das Feld restartPolicy definieren. Der Standardwert des Felds ist Always.

Sie können CrashLoopBackOff-Fehler mit der Google Cloud Console beheben:

  1. Rufen Sie das interaktive Playbook zu Crashlooping auf:

    Zum Playbook

  2. Geben Sie unter Cluster den Namen des Clusters ein, für den Sie eine Fehlerbehebung ausführen möchten.

  3. Geben Sie unter Namespace für den Namespace ein, für den Sie eine Fehlerbehebung ausführen möchten.

  4. (Optional) Erstellen Sie eine Benachrichtigung, um über zukünftige CrashLoopBackOff-Fehler informiert zu werden:

    1. Wählen Sie im Abschnitt Tipps zur zukünftigen Risikominderung die Option Benachrichtigung erstellen aus.

Logs prüfen

Mithilfe des kubectl-Befehlszeilentools oder der Cloud Console können Sie ermitteln, weshalb der Container des Pods abstürzt.

kubectl

Führen Sie den folgenden Befehl aus, um alle in Ihrem Cluster ausgeführten Pods anzusehen:

kubectl get pods

Suchen Sie nach dem Pod mit dem Fehler CrashLoopBackOff.

Führen Sie den folgenden Befehl aus, um die Logs des Pods abzurufen:

kubectl logs POD_NAME

Ersetzen Sie POD_NAME durch den Namen des problematischen Pods.

Wenn Sie das Flag -p übergeben, können Sie außerdem die Logs der vorherigen Instanz des Containers eines Pods abrufen, falls vorhanden.

Console

Führen Sie diese Schritte aus:

  1. Rufen Sie in der Google Cloud Console die Seite Arbeitslasten auf.

    Zu Arbeitslasten

  2. Wählen Sie die gewünschte Arbeitslast aus. Auf dem Tab Übersicht wird der Status der Arbeitslast angezeigt.

  3. Klicken Sie im Abschnitt Verwaltete Pods auf den problematischen Pod.

  4. Klicken Sie im Menü des Pods auf den Tab Logs.

Exit-Code des abgestürzten Containers prüfen

Sie finden den Exit-Code durch Ausführen der folgenden Aufgaben:

  1. Führen Sie diesen Befehl aus:

    kubectl describe pod POD_NAME
    

    Ersetzen Sie POD_NAME durch den Namen des Pods.

  2. Prüfen Sie den Wert im Feld containers: CONTAINER_NAME: last state: exit code:

    • Lautet der Exit-Code 1, ist ein Absturz der Anwendung der Grund dafür, dass der Container abgestürzt ist.
    • Lautet der Exit-Code 0, stellen Sie fest, wie lange die Anwendung ausgeführt wurde.

    Container werden beendet, wenn der Hauptprozess der Anwendung beendet wird. Wird die Ausführung einer Anwendung sehr schnell beendet, ist es möglich, dass der Container weiter neu gestartet wird.

Verbindung zu einem ausgeführten Container herstellen

Stellen Sie eine Shell-Verbindung zum Pod her:

kubectl exec -it POD_NAME -- /bin/bash

Wenn sich in Ihrem Pod mehrere Container befinden, fügen Sie -c CONTAINER_NAME hinzu.

Jetzt können Sie Bash-Befehle aus dem Container ausführen und so beispielsweise das Netzwerk testen oder prüfen, ob Sie Zugriff auf Dateien oder Datenbanken haben, die von der Anwendung verwendet werden.

ImagePullBackOff und ErrImagePull

Die Fehler ImagePullBackOff und ErrImagePull zeigen an, dass das von einem Container verwendete Image nicht aus der Image-Registry geladen werden kann.

Sie können dieses Problem mithilfe der Google Cloud Console oder des kubectl-Befehlszeilentools prüfen.

kubectl

Führen Sie den folgenden Befehl aus, um weitere Informationen zum Container-Image eines Pods zu erhalten:

kubectl describe pod POD_NAME

Console

Führen Sie diese Schritte aus:

  1. Rufen Sie in der Google Cloud Console die Seite Arbeitslasten auf.

    Zu Arbeitslasten

  2. Wählen Sie die gewünschte Arbeitslast aus. Auf dem Tab Übersicht wird der Status der Arbeitslast angezeigt.

  3. Klicken Sie im Abschnitt Verwaltete Pods auf den problematischen Pod.

  4. Klicken Sie im Menü des Pods auf den Tab Ereignisse.

Wenn das Image nicht gefunden wird

Wenn Ihr Image nicht gefunden wird, gehen Sie so vor:

  1. Prüfen Sie, ob der Name des Images korrekt ist.
  2. Prüfen Sie dann, ob das Tag des Images korrekt ist. Versuchen Sie es mit :latest oder keinem Tag, um das neueste Image per Pull abzurufen.
  3. Wenn das Image einen vollständigen Registry-Pfad hat, schauen Sie nach, ob es in der von Ihnen verwendeten Docker-Registry vorhanden ist. Falls Sie nur den Image-Namen angegeben haben, prüfen Sie die Docker Hub-Registry.
  4. Versuchen Sie, das Docker-Image manuell herunterzuladen:

    • Stellen Sie eine SSH-Verbindung zum Knoten her:

      So stellen Sie beispielsweise eine SSH-Verbindung zu einer VM her:

      gcloud compute ssh VM_NAME --zone=ZONE_NAME
      

      Ersetzen Sie Folgendes:

    • Führen Sie docker-credential-gcr configure-docker aus. Dieser Befehl generiert eine Konfigurationsdatei unter /home/[USER]/.docker/config.json. Achten Sie darauf, dass diese Datei die Registry des Images im Feld credHelpers enthält. Die folgende Datei enthält beispielsweise Authentifizierungsinformationen für Images, die auf asia.gcr.io, eu.gcr.io, gcr.io, marketplace.gcr.io und us.gcr.io gehostet werden:

      {
        "auths": {},
        "credHelpers": {
          "asia.gcr.io": "gcr",
          "eu.gcr.io": "gcr",
          "gcr.io": "gcr",
          "marketplace.gcr.io": "gcr",
          "us.gcr.io": "gcr"
        }
      }
      
    • Führen Sie docker pull IMAGE_NAME aus.

    Wenn dies funktioniert, müssen Sie möglicherweise ImagePullSecrets für einen Pod angeben. Pods können nur auf Image-Pull-Secrets in ihrem eigenen Namespace verweisen. Daher muss dieser Prozess pro Namespace einmal ausgeführt werden.

Fehler „Berechtigung verweigert“

Wenn ein Fehler des Typs "Berechtigung verweigert" oder "Kein Pull-Zugriff" auftritt, überprüfen Sie, ob Sie angemeldet sind und/oder Zugriff auf das Image haben. Probieren Sie je nach Registry, in der Sie Ihre Images hosten, eine der folgenden Methoden aus.

Artifact Registry

Wenn sich Ihr Image in Artifact Registry befindet, benötigt das Dienstkonto Ihres Knotenpools Lesezugriff auf das Repository, das das Image enthält.

Weisen Sie dem Dienstkonto die Rolle artifactregistry.reader zu.

gcloud artifacts repositories add-iam-policy-binding REPOSITORY_NAME \
    --location=REPOSITORY_LOCATION \
    --member=serviceAccount:SERVICE_ACCOUNT_EMAIL \
    --role="roles/artifactregistry.reader"

Ersetzen Sie Folgendes:

  • REPOSITORY_NAME: der Name Ihres Artifact Registry-Repositorys
  • REPOSITORY_LOCATION: die Region Ihres Artifact Registry-Repositorys
  • SERVICE_ACCOUNT_EMAIL: die E-Mail-Adresse des IAM-Dienstkontos, das Ihrem Knotenpool zugeordnet ist.

Container Registry

Wenn sich das Image in Container Registry befindet, benötigt das Dienstkonto Ihres Knotenpools Lesezugriff auf den Cloud Storage-Bucket, der das Image enthält.

Weisen Sie dem Dienstkonto die Rolle roles/storage.objectViewer zu, damit es aus dem Bucket lesen kann:

gsutil iam ch \
serviceAccount:SERVICE_ACCOUNT_EMAIL:roles/storage.objectViewer \
  gs://BUCKET_NAME

Ersetzen Sie Folgendes:

  • SERVICE_ACCOUNT_EMAIL ist die E-Mail-Adresse des Dienstkontos, das Ihrem Knotenpool zugeordnet ist. Sie können alle Dienstkonten in Ihrem Projekt mit gcloud iam service-accounts list auflisten.
  • BUCKET_NAME: der Name des Cloud Storage-Buckets, der Ihre Bilder enthält. Sie können alle Buckets in Ihrem Projekt mit gsutil ls auflisten.

Wenn Ihr Registry-Administrator gcr.io-Repositories in Artifact Registry eingerichtet hat, um Images für die Domain gcr.io anstelle von Container Registry zu speichern, müssen Sie Artifact Registry anstelle von Container Registry Lesezugriff gewähren.

Private Registry

Wenn sich Ihr Image in einer Private Registry befindet, benötigen Sie möglicherweise Schlüssel für den Zugriff auf die Images. Weitere Informationen finden Sie unter Private Registrys verwenden.

401 Nicht autorisiert: Images können nicht aus privatem Container Registry-Repository abgerufen werden

Ein Fehler wie der folgende kann auftreten, wenn Sie ein Image aus einem privaten Container Registry-Repository herunterladen:

gcr.io/PROJECT_ID/IMAGE:TAG: rpc error: code = Unknown desc = failed to pull and
unpack image gcr.io/PROJECT_ID/IMAGE:TAG: failed to resolve reference
gcr.io/PROJECT_ID/IMAGE]:TAG: unexpected status code [manifests 1.0]: 401 Unauthorized

Warning  Failed     3m39s (x4 over 5m12s)  kubelet            Error: ErrImagePull
Warning  Failed     3m9s (x6 over 5m12s)   kubelet            Error: ImagePullBackOff
Normal   BackOff    2s (x18 over 5m12s)    kubelet            Back-off pulling image
  1. Ermitteln Sie den Knoten, auf dem der Pod ausgeführt wird:

    kubectl describe pod POD_NAME | grep "Node:"
    
  2. Prüfen Sie, ob der Knoten den Speicherbereich hat:

    gcloud compute instances describe NODE_NAME \
        --zone=COMPUTE_ZONE --format="flattened(serviceAccounts[].scopes)"
    

    Der Zugriffsbereich des Knotens sollte mindestens einen der folgenden Werte enthalten:

    serviceAccounts[0].scopes[0]: https://www.googleapis.com/auth/devstorage.read_only
    serviceAccounts[0].scopes[0]: https://www.googleapis.com/auth/cloud-platform
    
  3. Erstellen Sie den Knotenpool, zu dem der Knoten gehört, mit ausreichendem Bereich neu. Sie können vorhandene Knoten nicht ändern. Sie müssen den Knoten mit dem richtigen Bereich neu erstellen.

    • Empfohlen: Erstellen Sie einen neuen Knotenpool mit dem Bereich gke-default:

      gcloud container node-pools create NODE_POOL_NAME \
          --cluster=CLUSTER_NAME \
          --zone=COMPUTE_ZONE \
          --scopes="gke-default"
      
    • Erstellen Sie einen neuen Knotenpool nur mit Speicherbereich:

      gcloud container node-pools create NODE_POOL_NAME \
          --cluster=CLUSTER_NAME \
          --zone=COMPUTE_ZONE \
          --scopes="https://www.googleapis.com/auth/devstorage.read_only"
      

Pod nicht planbar

Der Fehler PodUnschedulable gibt an, dass Ihr Pod aufgrund unzureichender Ressourcen oder eines Konfigurationsfehlers nicht geplant werden kann.

Wenn Sie Ihren GKE-Cluster so konfiguriert haben, dass er Kubernetes API-Server-Messwerte und Kubernetes-Planermesswerte an Cloud Monitoring sendet, finden Sie weitere Informationen zu diesen Fehlern unter Planermesswerte und API-Servermesswerte.

Sie können PodUnschedulable-Fehler mit der Google Cloud Console beheben:

  1. Rufen Sie das interaktive Playbook für nicht planbare Pods auf:

    Zum Playbook

  2. Geben Sie unter Cluster den Namen des Clusters ein, für den Sie eine Fehlerbehebung ausführen möchten.

  3. Geben Sie unter Namespace für den Namespace ein, für den Sie eine Fehlerbehebung ausführen möchten.

  4. (Optional) Erstellen Sie eine Benachrichtigung, um über zukünftige PodUnschedulable-Fehler informiert zu werden:

    1. Wählen Sie im Abschnitt Tipps zur zukünftigen Risikominderung die Option Benachrichtigung erstellen aus.

Unzureichende Ressourcen

Möglicherweise stoßen Sie auf einen Fehler, der auf zu wenig CPU-Kapazität, Arbeitsspeicher oder andere Ressourcen hinweist. Beispiel: "Es sind keine Knoten verfügbar, die mit allen Prädikaten übereinstimmen: Unzureichende CPU (2)". Dies weist darauf hin, dass auf zwei Knoten nicht genügend CPU-Kapazität verfügbar ist, um die Anfragen eines Pods zu erfüllen.

Wenn Ihre Pod-Ressourcenanfragen die eines einzelnen Knotens aus einem der zulässigen Knotenpools überschreiten, plant GKE den Pod nicht und löst auch kein Hochskalieren zum Hinzufügen eines neuen Knotens aus. Damit GKE den Pod planen kann, müssen Sie entweder weniger Ressourcen für den Pod anfordern oder einen neuen Knotenpool mit ausreichenden Ressourcen erstellen.

Sie können auch die automatische Knotenbereitstellung aktivieren, damit GKE automatisch Knotenpools mit Knoten erstellen kann, auf denen die nicht geplanten Pods ausgeführt werden können.

Die Standard-CPU-Anfrage beträgt 100 MB oder 10 % einer CPU bzw. eines Kerns. Wenn Sie mehr oder weniger Ressourcen anfordern möchten, geben Sie den Wert in der Pod-Spezifikation unter spec: containers: resources: requests an.

MatchNodeSelector

Der Fehler MatchNodeSelector gibt an, dass keine Knoten vorhanden sind, die mit der Labelauswahl des Pods übereinstimmen.

Sehen Sie sich in der Pod-Spezifikation unter spec: nodeSelector die im Feld nodeSelector angegebenen Labels an, um das zu prüfen.

Führen Sie den folgenden Befehl aus, um sich die Labels von Knoten in Ihrem Cluster anzusehen:

kubectl get nodes --show-labels

Führen Sie den folgenden Befehl aus, um einem Knoten ein Label hinzuzufügen:

kubectl label nodes NODE_NAME LABEL_KEY=LABEL_VALUE

Dabei gilt:

  • NODE_NAME: der gewünschte Knoten
  • LABEL_KEY: der Schlüssel des Labels
  • LABEL_VALUE: der Wert des Labels

Weitere Informationen finden Sie unter Pods zu Knoten zuweisen.

PodToleratesNodeTaints

Der Fehler PodToleratesNodeTaints gibt an, dass der Pod für keinen Knoten geplant werden kann, da aktuell kein Knoten die Knotenmarkierung des Pods toleriert.

Führen Sie den folgenden Befehl aus, um dies zu ermitteln:

kubectl describe nodes NODE_NAME

Prüfen Sie in der Ausgabe das Feld Taints. Darin sind Schlüssel/Wert-Paare und Planungseffekte aufgeführt.

Lautet der aufgeführte Effekt NoSchedule, können Pods auf diesem Knoten nur geplant werden, wenn sie eine übereinstimmende Toleranz haben.

Eine Möglichkeit zur Behebung dieses Problems ist, die Markierung zu entfernen. Führen Sie beispielsweise den folgenden Befehl aus, um eine NoSchedule-Markierung zu entfernen:

kubectl taint nodes NODE_NAME key:NoSchedule-

PodFitsHostPorts

Der Fehler PodFitsHostPorts gibt an, dass ein Port, den ein Knoten zu verwenden versucht, bereits in Gebrauch ist.

Prüfen Sie in der Pod-Spezifikation unter spec: containers: ports: hostPort den Wert hostPort, um dieses Problem zu beheben. Es kann sein, dass dieser Wert in einen anderen Port geändert werden muss.

Keine Mindestverfügbarkeit vorhanden

Wenn für einen Knoten genügend Ressourcen vorhanden sind, die Meldung Does not have minimum availability jedoch immer noch angezeigt wird, prüfen Sie den Status des Pods. Wenn er SchedulingDisabled oder Cordoned lautet, kann der Knoten keine neuen Pods planen. Sie können den Status eines Knotens in der Google Cloud Console oder dem kubectl-Befehlszeilentool prüfen.

kubectl

Führen Sie den folgenden Befehl aus, um die Status der Knoten abzurufen:

kubectl get nodes

Die Planung auf dem Knoten aktivieren Sie mit folgendem Befehl:

kubectl uncordon NODE_NAME

Console

Führen Sie diese Schritte aus:

  1. Rufen Sie in der Google Cloud Console die Seite Google Kubernetes Engine auf.

    Zur Seite "Google Kubernetes Engine"

  2. Wählen Sie den gewünschten Cluster aus. Auf dem Tab Knoten werden die Knoten und ihr Status angezeigt.

Führen Sie die folgenden Schritte aus, um die Planung auf dem Knoten zu aktivieren:

  1. Klicken Sie in der Liste auf den gewünschten Knoten.

  2. Klicken Sie dann in den Knotendetails auf Entsperren.

Maximale Anzahl von Pods pro Knoten erreicht

Wenn das Limit Maximale Anzahl von Pods pro Knoten von allen Knoten im Cluster erreicht wird, bleiben die Pods im Zustand "Nicht planbar". Im Tab Pod-Ereignisse wird eine Nachricht mit der Wortgruppe Too many pods angezeigt.

  1. Prüfen Sie die Maximum pods per node-Konfiguration auf dem Tab "Knoten" in den GKE-Clusterdetails in der Google Cloud Console.

  2. Rufen Sie eine Liste der Knoten ab:

    kubectl get nodes
    
  3. Prüfen Sie für jeden Knoten die Anzahl der Pods, die auf dem Knoten ausgeführt werden:

    kubectl get pods -o wide | grep NODE_NAME | wc -l
    
  4. Wenn das Limit erreicht wurde, fügen Sie einen neuen Knotenpool hinzu oder fügen Sie dem vorhandenen Knotenpool weitere Knoten hinzu.

Maximale Größe des Knotenpools erreicht, wenn Cluster Autoscaler aktiviert ist

Wenn der Knotenpool seine Maximalgröße gemäß der Cluster-Autoscaling-Konfiguration erreicht hat, löst GKE keine vertikale Skalierung für den Pod aus, der andernfalls mit diesem Knotenpool geplant wäre. Wenn der Pod mit diesem Knotenpool geplant werden soll, ändern Sie die Cluster Autoscaler-Konfiguration.

Maximale Größe des Knotenpools erreicht, wenn Cluster Autoscaler deaktiviert ist

Wenn der Knotenpool die maximale Anzahl von Knoten erreicht hat und Cluster Autoscaler deaktiviert ist, kann GKE den Pod mit dem Knotenpool nicht planen. Erhöhen Sie die Größe des Knotenpools oder aktivieren Sie Cluster Autoscaler für GKE, um die Größe des Clusters automatisch anzupassen.

Ungebundene PersistentVolumeClaims

Der Fehler Unbound PersistentVolumeClaims gibt an, dass der Pod auf einen nicht gebundenen PersistentVolumeClaim verweist. Dieser Fehler kann auftreten, wenn das PersistentVolume nicht bereitgestellt werden konnte. Sie können prüfen, ob die Bereitstellung fehlgeschlagen ist. Dazu rufen Sie die Ereignisse für den PersistentVolumeClaim ab und untersuchen sie auf Fehler.

Führen Sie den folgenden Befehl aus, um Ereignisse abzurufen:

kubectl describe pvc STATEFULSET_NAME-PVC_NAME-0

Dabei gilt:

  • STATEFULSET_NAME: Name des StatefulSet-Objekts.
  • PVC_NAME: Name des PersistentVolumeClaim-Objekts.

Dies kann auch passieren, wenn während der manuellen Vorabbereitstellung eines PersistentVolume und der Bindung an einen PersistentVolumeClaim ein Konfigurationsfehler aufgetreten ist. Sie können versuchen, das Volume noch einmal vorab bereitzustellen.

Unzureichendes Kontingent

Prüfen Sie, ob Ihr Projekt ein ausreichendes Compute Engine-Kontingent hat, damit GKE den Cluster vertikal skalieren kann. Wenn GKE versucht, Ihrem Cluster einen Knoten hinzuzufügen, um den Pod zu planen, und das Hochskalieren das verfügbare Kontingent Ihres Projekts überschreiten würde, erhalten Sie die Fehlermeldung scale.up.error.quota.exceeded.

Weitere Informationen finden Sie unter ScaleUp-Fehler.

Verworfene APIs

Achten Sie darauf, keine verworfenen APIs zu verwenden, die mit der Nebenversion des Clusters entfernt werden. Weitere Informationen finden Sie unter Verworfene Komponenten von GKE.

Verbindungsprobleme

Damit Sie Fehler erfolgreich beheben können, sollten Sie wissen, wie die Netzwerk-Namespaces von Pods mit dem Stamm-Namespace auf dem Knoten verbunden sind (siehe Netzwerkübersicht). Gehen Sie bei der folgenden Erläuterung davon aus, dass der Cluster das native CNI von GKE und nicht das CNI von Calico verwendet (sofern nicht anders angegeben). Das heißt, es wurde keine Netzwerkrichtlinie angewendet.

Pods auf bestimmten Knoten sind nicht verfügbar

Wenn Pods auf bestimmten Knoten keine Netzwerkverbindung haben, prüfen Sie, ob die Linux-Bridge aktiv ist:

ip address show cbr0

Wenn die Linux-Bridge nicht aktiv ist, starten Sie sie:

sudo ip link set cbr0 up

Prüfen Sie, ob der Knoten Pod-MAC-Adressen in Erfahrung bringt, die zu cbr0 gehören:

arp -an

Pods auf bestimmten Knoten haben nur minimale Konnektivität

Wenn Pods auf bestimmten Knoten nur minimale Konnektivität haben, sollten Sie zuerst prüfen, ob Pakete verloren gegangen sind. Führen Sie dazu tcpdump im Toolbox-Container aus:

sudo toolbox bash

Installieren Sie tcpdump in der Toolbox, wenn nicht bereits geschehen:

apt install -y tcpdump

Führen Sie tcpdump für cbr0 aus:

tcpdump -ni cbr0 host HOSTNAME and port PORT_NUMBER and [TCP|UDP|ICMP]

Wenn es so aussieht, als würden große Pakete nach der Bridge verloren gehen (der TCP-Handshake wird beispielsweise abgeschlossen, es gehen aber keine SSL-Hellos ein), prüfen Sie, ob die MTU für jede Linux-Pod-Schnittstelle richtig auf die die MTU des VPC-Netzwerks des Clusters festgelegt ist.

ip address show cbr0

Wenn Overlays verwendet werden (z. B. Weave oder Flannel), muss dieser MTU-Wert weiter reduziert werden, um Kapselungsoverhead für das Overlay aufzufangen.

GKE-MTU

Die für eine Pod-Schnittstelle ausgewählte MTU hängt von der von den Clusterknoten verwendeten Container Network Interface (CNI) und der zugrunde liegenden VPC-MTU-Einstellung ab. Weitere Informationen finden Sie unter Pods.

Der MTU-Wert der Pod-Schnittstelle ist entweder 1460 oder wird von der primären Schnittstelle des Knotens übernommen.

CNI MTU GKE Standard
kubenet 1460 Default
kubenet
(GKE-Version 1.26.1 und höher)
Übernommen Default
Calico 1460

Aktiviert mit --enable-network-policy.

Weitere Informationen finden Sie unter Kommunikation zwischen Pods und Services mithilfe von Netzwerkrichtlinien steuern.

netd Übernommen Aktiviert durch Verwendung einer der folgenden Optionen:
GKE Dataplane V2 Übernommen

Aktiviert mit --enable-dataplane-v2.

Weitere Informationen finden Sie unter GKE Dataplane V2 verwenden.

Zeitweise fehlgeschlagene Verbindungen

Verbindungen zu und von den Pods werden von iptables weitergeleitet. Datenflüsse werden als Einträge in der Conntrack-Tabelle verfolgt. Wenn viele Arbeitslasten pro Knoten vorhanden sind, kann die Überfüllung der Conntrack-Tabelle zu einem Fehler führen. Solche Fehler können in der seriellen Konsole des Knotens protokolliert werden. Beispiel:

nf_conntrack: table full, dropping packet

Wenn sich zeitweise auftretende Probleme auf eine volle Conntrack-Tabelle zurückführen lassen, können Sie die Größe des Clusters erhöhen, um die Anzahl der Arbeitslasten und Datenflüsse pro Knoten zu reduzieren, oder nf_conntrack_max erhöhen:

new_ct_max=$(awk '$1 == "MemTotal:" { printf "%d\n", $2/32; exit; }' /proc/meminfo)
sysctl -w net.netfilter.nf_conntrack_max="${new_ct_max:?}" \
  && echo "net.netfilter.nf_conntrack_max=${new_ct_max:?}" >> /etc/sysctl.conf

Sie können auch NodeLocal DNSCache verwenden, um die Verbindungs-Tracking-Einträge zu reduzieren.

"bind: Address already in use" wird für einen Container gemeldet

Aus den Containerlogs geht hervor, dass ein Container in einem Pod nicht gestartet werden kann, da der Port, an den sich die Anwendung binden möchte, bereits reserviert ist. Der Container gerät in eine Absturzschleife. Zum Beispiel in Cloud Logging:

resource.type="container"
textPayload:"bind: Address already in use"
resource.labels.container_name="redis"

2018-10-16 07:06:47.000 CEST 16 Oct 05:06:47.533 # Creating Server TCP listening socket *:60250: bind: Address already in use
2018-10-16 07:07:35.000 CEST 16 Oct 05:07:35.753 # Creating Server TCP listening socket *:60250: bind: Address already in use

Wenn Docker abstürzt, wird manchmal ein veralteter Container weiterhin ausgeführt. Der Prozess läuft im Netzwerk-Namespace weiter, der dem Pod zugewiesen ist, und überwacht seinen Port. Da Docker und das kubelet nichts von dem veralteten Container wissen, versuchen sie, einen neuen Container mit einem neuen Prozess zu starten. Dieser Prozess kann sich jedoch nicht an den Port binden, da er dem Netzwerk-Namespace hinzugefügt wird, der bereits mit dem Pod verknüpft ist.

So diagnostizieren Sie dieses Problem:

  1. Sie benötigen die UUID des Pods im Feld .metadata.uuid:

    kubectl get pod -o custom-columns="name:.metadata.name,UUID:.metadata.uid" ubuntu-6948dd5657-4gsgg
    
    name                      UUID
    ubuntu-6948dd5657-4gsgg   db9ed086-edba-11e8-bdd6-42010a800164
    
  2. Rufen Sie die Ausgabe der folgenden Befehle vom Knoten ab:

    docker ps -a
    ps -eo pid,ppid,stat,wchan:20,netns,comm,args:50,cgroup --cumulative -H | grep [Pod UUID]
    
  3. Prüfen Sie die laufenden Prozesse von diesem Pod. Da die UUID der cgroup-Namespaces die UUID des Pods enthält, können Sie die Pod-UUID mit grep in ps ausgeben. Rufen Sie auch die Zeile davor mit grep ab, sodass Sie die docker-containerd-shim-Prozesse erhalten, die auch die Container-ID im Argument haben. Schneiden Sie den Rest der cgroup-Spalte ab, um die Ausgabe zu vereinfachen:

    # ps -eo pid,ppid,stat,wchan:20,netns,comm,args:50,cgroup --cumulative -H | grep -B 1 db9ed086-edba-11e8-bdd6-42010a800164 | sed s/'blkio:.*'/''/
    1283089     959 Sl   futex_wait_queue_me  4026531993       docker-co       docker-containerd-shim 276e173b0846e24b704d4 12:
    1283107 1283089 Ss   sys_pause            4026532393         pause           /pause                                     12:
    1283150     959 Sl   futex_wait_queue_me  4026531993       docker-co       docker-containerd-shim ab4c7762f5abf40951770 12:
    1283169 1283150 Ss   do_wait              4026532393         sh              /bin/sh -c echo hello && sleep 6000000     12:
    1283185 1283169 S    hrtimer_nanosleep    4026532393           sleep           sleep 6000000                            12:
    1283244     959 Sl   futex_wait_queue_me  4026531993       docker-co       docker-containerd-shim 44e76e50e5ef4156fd5d3 12:
    1283263 1283244 Ss   sigsuspend           4026532393         nginx           nginx: master process nginx -g daemon off; 12:
    1283282 1283263 S    ep_poll              4026532393           nginx           nginx: worker process
    
  4. Dieser Liste können Sie die Container-IDs entnehmen, die auch in docker ps sichtbar sein sollten.

    In diesem Fall:

    • docker-containerd-shim 276e173b0846e24b704d4 für pause
    • docker-containerd-shim ab4c7762f5abf40951770 für sh mit sleep (sleep-ctr)
    • docker-containerd-shim 44e76e50e5ef4156fd5d3 für nginx (echoserver-ctr)
  5. Prüfen Sie diese in der Ausgabe von docker ps:

    # docker ps --no-trunc | egrep '276e173b0846e24b704d4|ab4c7762f5abf40951770|44e76e50e5ef4156fd5d3'
    44e76e50e5ef4156fd5d383744fa6a5f14460582d0b16855177cbed89a3cbd1f   gcr.io/google_containers/echoserver@sha256:3e7b182372b398d97b747bbe6cb7595e5ffaaae9a62506c725656966d36643cc                   "nginx -g 'daemon off;'"                                                                                                                                                                                                                                                                                                                                                                     14 hours ago        Up 14 hours                             k8s_echoserver-cnt_ubuntu-6948dd5657-4gsgg_default_db9ed086-edba-11e8-bdd6-42010a800164_0
    ab4c7762f5abf40951770d3e247fa2559a2d1f8c8834e5412bdcec7df37f8475   ubuntu@sha256:acd85db6e4b18aafa7fcde5480872909bd8e6d5fbd4e5e790ecc09acc06a8b78                                                "/bin/sh -c 'echo hello && sleep 6000000'"                                                                                                                                                                                                                                                                                                                                                   14 hours ago        Up 14 hours                             k8s_sleep-cnt_ubuntu-6948dd5657-4gsgg_default_db9ed086-edba-11e8-bdd6-42010a800164_0
    276e173b0846e24b704d41cf4fbb950bfa5d0f59c304827349f4cf5091be3327   registry.k8s.io/pause-amd64:3.1
    

    Normalerweise werden alle Container-IDs aus ps in docker ps angezeigt. Wenn Sie eine ID nicht sehen, ist der Container veraltet. Wahrscheinlich sehen Sie dann einen untergeordneten Prozess von docker-containerd-shim process, der den TCP-Port überwacht, der als bereits verwendet gemeldet wird.

    Damit Sie das prüfen können, führen Sie netstat im Netzwerk-Namespace des Containers aus. Rufen Sie die PID eines beliebigen Containerprozesses (jedoch NICHT docker-containerd-shim) für den Pod ab.

    Aus dem obigen Beispiel:

    • 1283107 – pause
    • 1283169 – sh
    • 1283185 – sleep
    • 1283263 – nginx-Master
    • 1283282 – nginx-Worker
    # nsenter -t 1283107 --net netstat -anp
    Active Internet connections (servers and established)
    Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
    tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN      1283263/nginx: mast
    Active UNIX domain sockets (servers and established)
    Proto RefCnt Flags       Type       State         I-Node   PID/Program name     Path
    unix  3      [ ]         STREAM     CONNECTED     3097406  1283263/nginx: mast
    unix  3      [ ]         STREAM     CONNECTED     3097405  1283263/nginx: mast
    
    gke-zonal-110-default-pool-fe00befa-n2hx ~ # nsenter -t 1283169 --net netstat -anp
    Active Internet connections (servers and established)
    Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
    tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN      1283263/nginx: mast
    Active UNIX domain sockets (servers and established)
    Proto RefCnt Flags       Type       State         I-Node   PID/Program name     Path
    unix  3      [ ]         STREAM     CONNECTED     3097406  1283263/nginx: mast
    unix  3      [ ]         STREAM     CONNECTED     3097405  1283263/nginx: mast
    

    Sie können auch netstat mit ip netns ausführen, müssen jedoch den Netzwerk-Namespace des Prozesses manuell verbinden, da Docker die Verbindung nicht herstellt:

    # ln -s /proc/1283169/ns/net /var/run/netns/1283169
    gke-zonal-110-default-pool-fe00befa-n2hx ~ # ip netns list
    1283169 (id: 2)
    gke-zonal-110-default-pool-fe00befa-n2hx ~ # ip netns exec 1283169 netstat -anp
    Active Internet connections (servers and established)
    Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
    tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN      1283263/nginx: mast
    Active UNIX domain sockets (servers and established)
    Proto RefCnt Flags       Type       State         I-Node   PID/Program name     Path
    unix  3      [ ]         STREAM     CONNECTED     3097406  1283263/nginx: mast
    unix  3      [ ]         STREAM     CONNECTED     3097405  1283263/nginx: mast
    gke-zonal-110-default-pool-fe00befa-n2hx ~ # rm /var/run/netns/1283169
    

Abhilfe:

Zur vorläufigen Abhilfe können Sie veraltete Prozesse mit der oben beschriebenen Methode identifizieren und die Prozesse mit dem Befehl kill [PID] beenden.

Zur langfristigen Abhilfe müssen Sie feststellen, warum Docker abstürzt, und dieses Problem beheben. Mögliche Gründe:

  • Es sammeln sich Zombie-Prozesse an, sodass PID-Namespaces ausgehen
  • Programmfehler in Docker
  • Ressourcenknappheit/nicht genügend Arbeitsspeicher

Fehler: "Es konnte keine Zuweisung für den Bereich 0: keine IP-Adressen im Bereich festgelegt werden"

In der GKE-Version 1.18.17 und höher wurde ein Problem behoben, bei dem OOM-Ereignisse (Out-of-Memory) zu einer falschen Pod-Bereinigung führten, wenn der Pod vor dem Start der Container gelöscht wurde. Diese falsche Bereinigung kann zu verwaisten Pods führen, für die weiterhin IP-Adressen aus dem zugewiesenen Knotenbereich reserviert waren. Im Laufe der Zeit gingen GKE aufgrund der Anhäufung verwaister Pods die IP-Adressen aus, um neuen Pods zuzuweisen. Dies führte zur Fehlermeldung failed to allocate for range 0: no IP addresses in range set, da der zugewiesene Knotenbereich keine verfügbaren IP-Adressen hatte, die neuen Pods zugewiesen werden konnten.

Aktualisieren Sie Ihren Cluster und Ihre Knotenpools auf die GKE-Version 1.18.17 oder höher, um dieses Problem zu beheben.

Um dieses Problem zu vermeiden und es in Clustern mit GKE-Versionen vor 1.18.17 zu beheben, erhöhen Sie Ihre Ressourcenlimits, um in Zukunft OOM-Ereignisse zu vermeiden und die IP-Adressen dann durch Entfernen verwaister Pods zu reklamieren.

Sie können auch Statistiken zur GKE-IP-Adressauslastung ansehen.

Verwaiste Pods aus den betroffenen Knoten entfernen

Sie können die verwaisten Pods entfernen, indem Sie den Knoten leeren, den Knotenpool aktualisieren oder die betroffenen Verzeichnisse verschieben.

Knoten per Drain beenden (empfohlen)

  1. Sperren Sie den Knoten, um zu verhindern, dass neue Pods darauf geplant werden:

     kubectl cordon NODE
    

    Ersetzen Sie NODE durch den Namen des Knotens, den Sie per Drain beenden möchten.

  2. Leeren Sie den Knoten. GKE verschiebt Pods, die von Deployments verwaltet werden, automatisch auf andere Knoten. Mit dem Flag --force können Sie verwaiste Pods per Drain beenden, die keine Verwaltungsressource haben.

     kubectl drain NODE --force
    
  3. Trennen Sie den Knoten, damit GKE neue Pods darauf planen kann:

     kubectl uncordon NODE
    

Betroffene Verzeichnisse verschieben

Sie können verwaiste Pod-Verzeichnisse in /var/lib/kubelet/pods identifizieren und aus dem Hauptverzeichnis verschieben, damit GKE die Pods beenden kann.

Probleme beim Beenden von Ressourcen beheben

Namespace hängt im Status Terminating fest

Namespaces verwenden Kubernetes-Finalizer, um zu verhindern, dass eine oder mehrere Ressourcen in einem Namespace gelöscht werden. Wenn Sie einen Namespace mit dem Befehl kubectl delete löschen, wechselt der Namespace in den Status Terminating, bis Kubernetes seine abhängigen Ressourcen löscht und alle Finalizer löscht. Der Namespace-Lebenszyklus-Controller listet zuerst alle Ressourcen im Namespace auf, die GKE löschen muss. Wenn GKE eine abhängige Ressource nicht löschen kann oder der Namespace-Lebenszyklus-Controller nicht prüfen kann, ob der Namespace leer ist, verbleibt der Namespace im Status Terminating, bis das Problem behoben ist. “

Zum Beheben eines Namespace, der im Status Terminating hängen bleibt, müssen Sie die fehlerhaften Komponenten identifizieren und entfernen, die den Löschvorgang blockieren. Versuchen Sie es mit einer der folgenden Lösungen:

Nicht verfügbare API-Dienste suchen und entfernen

  1. Listen Sie nicht verfügbare API-Dienste auf:

    kubectl get apiservice | grep False
    
  2. Beheben Sie Fehler bei nicht reagierenden Diensten:

    kubectl describe apiservice API_SERVICE
    

    Ersetzen Sie API_SERVICE durch den Namen des nicht reagierenden Dienstes.

  3. Prüfen Sie, ob der Namespace noch beendet wird:

    kubectl get ns | grep Terminating
    

Verbleibende Ressourcen suchen und entfernen

  1. Listen Sie alle Ressourcen auf, die im beendenden Namespace verbleiben:

    kubectl api-resources --verbs=list --namespaced -o name | xargs -n 1 kubectl get -n NAMESPACE
    

    Ersetzen Sie NAMESPACE durch den Namen des Namespace, den Sie löschen möchten.

  2. Entfernen Sie alle in der Ausgabe angezeigten Ressourcen.

  3. Prüfen Sie, ob der Namespace noch beendet wird:

    kubectl get ns | grep Terminating
    

Löschen des Namespace erzwingen

Sie können die Finalizer entfernen, die das Löschen des Namespace blockieren, um die Beendigung des Namespace zu erzwingen.

  1. Speichern Sie das folgende Manifest als YAML-Datei:

    kubectl get ns NAMESPACE -o yaml > ns-terminating.yml
    
  2. Öffnen Sie das Manifest in einem Texteditor und entfernen Sie alle Werte im Feld spec.finalizers:

    vi ns-terminating.yml
    
  3. Prüfen Sie, ob das Feld "Finalizer" leer ist:

    cat ns-terminating.yml
    

    Die Ausgabe sollte so aussehen:

    apiVersion: v1
    kind: Namespace
    metadata:
      annotations:
      name: NAMESPACE
    spec:
      finalizers:
    status:
      phase: Terminating
    
  4. Starten Sie einen HTTP-Proxy für den Zugriff auf die Kubernetes API:

    kubectl proxy
    
  5. Ersetzen Sie das Namespace-Manifest mit curl:

    curl -H "Content-Type: application/yaml" -X PUT --data-binary @ns-terminating.yml http://127.0.0.1:8001/api/v1/namespaces/NAMESPACE/finalize
    
  6. Prüfen Sie, ob der Namespace noch beendet wird:

    kubectl get ns | grep Terminating
    

Fehlerbehebung beim Cloud NAT-Paketverlust aus einem GKE-Cluster

Knoten-VMs in VPC-nativen privaten GKE-Clustern haben keine externen IP-Adressen und können nicht allein eine Verbindung zum Internet herstellen. Sie können Cloud NAT verwenden, um die externen IP-Adressen und Ports zuzuweisen, mit denen private Cluster öffentliche Verbindungen herstellen können.

Wenn eine Knoten-VM keine externen Ports und IP-Adressen von Cloud NAT mehr hat, werden Pakete verworfen. Dies können Sie vermeiden, wenn Sie die Rate des ausgehenden Pakets reduzieren oder die Zuweisung der verfügbaren Cloud NAT-Quell-IP-Adressen und -Ports erhöhen. In den folgenden Abschnitten wird beschrieben, wie Sie Paketverluste aus Cloud NAT im Kontext von privaten GKE-Clustern diagnostizieren und beheben.

Paketverlust diagnostizieren

In diesem Abschnitt wird erläutert, wie Sie verworfene Pakete mit Cloud Logging protokollieren und die Ursache für verworfene Pakete mit Cloud Monitoring diagnostizieren.

Verworfene Pakete protokollieren

Mit der folgenden Abfrage in Cloud Logging können Sie Pakete protokollieren:

resource.type="nat_gateway"
resource.labels.region=REGION
resource.labels.gateway_name=GATEWAY_NAME
jsonPayload.allocation_status="DROPPED"
  • REGION ist der Name der Region, in der sich der Cluster befindet.
  • GATEWAY_NAME: Der Name des Cloud NAT-Gateways.

Dieser Befehl gibt eine Liste aller Pakete zurück, die von einem Cloud NAT-Gateway verworfen wurden, identifiziert jedoch nicht die Ursache.

Ursachen für Paketverluste überwachen

Fragen Sie den Metrics Beobachter in Cloud Monitoring ab, um Ursachen für verworfene Pakete zu ermitteln. Pakete aus einem von drei Gründen:

Verwenden Sie die folgende Abfrage, um Pakete zu identifizieren, die aufgrund der Fehlercodes OUT_OF_RESOURCES oder ENDPOINT_ALLOCATION_FAILED verworfen wurden:

fetch nat_gateway
  metric 'router.googleapis.com/nat/dropped_sent_packets_count'
  filter (resource.gateway_name == NAT_NAME)
  align rate(1m)
  every 1m
  group_by [metric.reason],
    [value_dropped_sent_packets_count_aggregate:
       aggregate(value.dropped_sent_packets_count)]

Verwenden Sie die folgende Abfrage, um Pakete zu identifizieren, die aufgrund des Fehlercodes NAT_ALLOCATION_FAILED verworfen wurden:

fetch nat_gateway
  metric 'router.googleapis.com/nat/nat_allocation_failed'
  group_by 1m,
    [value_nat_allocation_failed_count_true:
       count_true(value.nat_allocation_failed)]
  every 1m

Fehlerbehebung bei Cloud NAT mit GKE-IP-Maskierung

Wenn die vorherigen Abfragen leere Ergebnisse zurückgeben und GKE-Pods nicht mit externen IP-Adressen kommunizieren können, beheben Sie die Fehlerbehebung:

Konfiguration Fehlerbehebung
Cloud NAT, das so konfiguriert ist, dass es nur auf den primären IP-Adressbereich des Subnetzes angewendet wird. Wenn Cloud NAT nur für den primären IP-Adressbereich des Subnetzes konfiguriert ist, müssen Pakete, die vom Cluster an externe IP-Adressen gesendet werden, eine IP-Adresse des Quellknotens haben. In dieser Cloud NAT-Konfiguration gilt:
  • Pods können Pakete an externe IP-Adressen senden, wenn diese externen IP-Adressziele der IP-Maskierung unterliegen. Achten Sie beim Bereitstellen von ip-masq-agent darauf, dass die Liste nonMasqueradeCIDRs nicht die Ziel-IP-Adresse und den Zielport enthält. Pakete, die an diese Ziele gesendet werden, werden zuerst in IP-Adressen des Quellknotens konvertiert, bevor sie von Cloud NAT verarbeitet werden.
  • Damit die Pods mit dieser Cloud NAT-Konfiguration eine Verbindung zu allen externen IP-Adressen herstellen können, muss ip-masq-agent bereitgestellt sein und die Liste nonMasqueradeCIDRs darf nur die Knoten- und Pod-IP-Adressbereiche des Clusters enthalten. Pakete, die an Ziele außerhalb des Clusters gesendet werden, werden zuerst in Quellknoten-IP-Adressen konvertiert, bevor sie von Cloud NAT verarbeitet werden.
  • Wenn Sie verhindern möchten, dass Pods Pakete an einige externe IP-Adressen senden, müssen Sie diese Adressen explizit blockieren, damit sie nicht maskiert werden. Fügen Sie, wenn ip-masq-agent bereitgestellt ist, der Liste nonMasqueradeCIDRs die externen IP-Adressen hinzu, die Sie blockieren möchten. Pakete, die an diese Ziele gesendet werden, verlassen den Knoten mit ihren ursprünglichen Pod-IP-Adressquellen. Die Pod-IP-Adressen stammen aus einem sekundären IP-Adressbereich des Subnetzes des Clusters. In dieser Konfiguration wird Cloud NAT in diesem sekundären Bereich nicht ausgeführt.
Cloud NAT, das so konfiguriert ist, dass es nur auf den sekundären IP-Adressbereich des Subnetzes angewendet wird, der für Pod-IP-Adressen verwendet wird.

Wenn Cloud NAT nur für den sekundären IP-Adressbereich des Subnetzes konfiguriert ist, der von den Pod-IPs des Clusters verwendet wird, müssen Pakete, die vom Cluster an externe IP-Adressen gesendet werden, eine Quell-Pod-IP-Adresse haben. In dieser Cloud NAT-Konfiguration gilt:

  • Die Verwendung eines IP-Masquerade-Agents führt dazu, dass Pakete bei der Verarbeitung von Cloud NAT ihre Quell-Pod-IP-Adresse verlieren. Wenn Sie die IP-Adresse des Quell-Pods beibehalten möchten, geben Sie Ziel-IP-Adressbereiche in einer nonMasqueradeCIDRs-Liste an. Wenn ip-masq-agent bereitgestellt ist, behalten alle Pakete, die an Ziele in der Liste nonMasqueradeCIDRs gesendet werden, ihre Quell-Pod-IP-Adressen bei, bevor sie von Cloud NAT verarbeitet werden.
  • Damit die Pods mit dieser Cloud NAT-Konfiguration eine Verbindung zu allen externen IP-Adressen herstellen können, muss Folgendes gewährleistet sein: ip-masq-agent ist bereitgestellt und die nonMasqueradeCIDRs-Liste ist so groß wie möglich (0.0.0.0/0 gibt alle IP-Adressziele an). Pakete, die an alle Ziele gesendet werden, behalten die Quell-Pod-IP-Adressen bei, bevor sie von Cloud NAT verarbeitet werden.

Optimierungen zur Vermeidung von Paketverlusten

Sie können den Paketverlust verhindern, indem Sie:

Anwendung optimieren

Wenn eine Anwendung mehrere ausgehende Verbindungen zu derselben Ziel-IP-Adresse und demselben Zielport herstellt, kann sie mit der Anzahl der zugewiesenen NAT-Quelladressen und Quellport-Tupel schnell alle Verbindungen nutzen, die Cloud NAT zu diesem Ziel herstellen kann. “ In diesem Szenario hilft die Reduzierung der ausgehenden Paketrate der Anwendung, den Paketverlust zu reduzieren.

Ausführliche Informationen dazu, wie Cloud NAT NAT-Quelladressen und Quellports für Verbindungen verwendet, einschließlich Limits für die Anzahl gleichzeitiger Verbindungen zu einem Ziel finden Sie unter Ports und Verbindungen

Wenn Sie die Rate ausgehender Verbindungen von der Anwendung reduzieren, können Sie den Paketverlust verringern. Sie können dies erreichen, indem Sie offene Verbindungen wiederverwenden. Zu den gängigen Methoden zur Wiederverwendung von Verbindungen gehören Verbindungs-Pooling, Multiplex-Verbindungen mit Protokollen wie HTTP/2 oder das Erstellen von nichtflüchtigen Verbindungen, die für mehrere Anfragen wiederverwendet werden. Weitere Informationen finden Sie unter Ports und Verbindungen.

Knotenversion ist nicht mit Version der Steuerungsebene kompatibel.

Sehen Sie nach, welche Version von Kubernetes auf der Steuerungsebene Ihres Clusters ausgeführt wird, und prüfen Sie dann, welche Kubernetes-Version die Knotenpools des Clusters ausführt. Wenn einer der Knotenpools eines Clusters mehr als zwei Nebenversionen älter als die Steuerungsebene ist, kann dies zu Problemen mit Ihrem Cluster führen.

Das GKE-Team führt regelmäßig Upgrades der Cluster-Steuerungsebene in Ihrem Namen durch. Steuerebenen werden auf neuere stabile Versionen von Kubernetes aktualisiert. Für die Knoten eines Clusters ist standardmäßig das automatische Upgrade aktiviert. Wir empfehlen, dies nicht zu deaktivieren.

Wenn die automatischen Upgrades für die Knoten eines Clusters deaktiviert sind und Sie die Knotenpoolversion nicht manuell auf eine Version aktualisieren, die mit der Steuerungsebene kompatibel ist, wird Ihre Steuerungsebene nicht mehr mit Ihren Knoten kompatibel sein, da die Steuerungsebene im Laufe der Zeit automatisch aktualisiert wird. Inkompatibilität zwischen der Steuerungsebene des Clusters und den Knoten kann zu unerwarteten Problemen führen.

Die Supportrichtlinie für Kubernetes-Versionen und Versionsinkompatibilität sorgt dafür, dass Steuerungsebenen mit Knoten kompatibel sind, die bis zu zwei Nebenversionen älter sind als die Steuerungsebene. Die Steuerungsebenen von Kubernetes 1.19 sind beispielsweise mit Kubernetes 1.19-, 1.18- und 1.17-Knoten kompatibel. Aktualisieren Sie die Knotenpoolversion auf eine Version, die mit der Steuerungsebene kompatibel ist, um dieses Problem zu beheben.

Wenn Sie befürchten, dass der Upgradeprozess zu Arbeitslasten führt, die auf den betroffenen Knoten ausgeführt werden, führen Sie die folgenden Schritte aus, um Ihre Arbeitslasten in einen neuen Knotenpool zu migrieren:

  1. Erstellen Sie einen neuen Knotenpool mit einer kompatiblen Version.
  2. Sperren Sie die Knoten des vorhandenen Knotenpools.
  3. Optional können Sie Ihre Arbeitslasten aktualisieren, die im vorhandenen Knotenpool ausgeführt werden, um einen nodeSelector für das Label cloud.google.com/gke-nodepool:NEW_NODE_POOL_NAME hinzuzufügen, wobei NEW_NODE_POOL_NAME der Name des neuen Knotenpools ist. Dadurch wird sichergestellt, dass GKE diese Arbeitslasten auf Knoten im neuen Knotenpool platziert.
  4. Leeren Sie den vorhandenen Knotenpool.
  5. Prüfen Sie, ob die Arbeitslasten im neuen Knotenpool erfolgreich ausgeführt werden. Wenn dies der Fall ist, können Sie den alten Knotenpool löschen. Wenn Sie Unterbrechungen der Arbeitslast feststellen, planen Sie die Arbeitslasten auf den vorhandenen Knoten neu. Heben Sie dazu die Knoten im vorhandenen Knotenpool auf und leeren Sie die neuen Knoten. Beheben Sie das Problem und versuchen Sie es noch einmal.

Messwerte aus Ihrem Cluster werden nicht in Cloud Monitoring angezeigt

Achten Sie darauf, dass Sie die Cloud Monitoring API und die Cloud Logging API in Ihrem Projekt aktiviert haben und Sie das Projekt in Cloud Monitoring aufrufen können.

Wenn das Problem weiterhin besteht, prüfen Sie folgende mögliche Ursachen:

  1. Vergewissern Sie sich, dass Sie das Monitoring für Ihren Cluster aktiviert haben.

    Monitoring ist standardmäßig für Cluster aktiviert, die über die Google Cloud Console und das Google Cloud-Befehlszeilentool erstellt wurden. Zur Prüfung können Sie den folgenden Befehl ausführen oder in der Cloud Console auf die Clusterdetails klicken:

    gcloud container clusters describe CLUSTER_NAME
    

    Die Ausgabe dieses Befehls sollte SYSTEM_COMPONENTS in der Liste der enableComponents im Abschnitt monitoringConfig enthalten, ähnlich wie diese:

    monitoringConfig:
      componentConfig:
        enableComponents:
        - SYSTEM_COMPONENTS
    

    Aktivieren Sie das Monitoring gegebenenfalls mithilfe des folgenden Befehls:

    gcloud container clusters update CLUSTER_NAME --monitoring=SYSTEM
    
  2. Wie lange ist es her, dass Ihr Cluster erstellt oder das Monitoring aktiviert wurde?

    Es kann bis zu einer Stunde dauern, bis die Messwerte eines neuen Clusters in Cloud Monitoring angezeigt werden.

  3. Wird in Ihrem Cluster im Namespace "kube-system" ein heapster oder gke-metrics-agent (der OpenTelemetry Collector) ausgeführt?

    Unter Umständen kann der Pod keine Arbeitslasten planen, weil die Ressourcen im Cluster zur Neige gehen. Prüfen Sie, ob Heapster oder OpenTelemetry ausgeführt wird. Rufen Sie dazu kubectl get pods --namespace=kube-system auf und suchen Sie nach Pods mit heapster oder gke-metrics-agent im Namen.

  4. Kann Ihre Cluster-Steuerungsebene mit den Knoten kommunizieren?

    Dies ist entscheidend für die Funktion von Cloud Monitoring. Mit dem folgenden Befehl können Sie prüfen, ob dies der Fall ist:

    kubectl logs POD_NAME
    

    Wenn dieser Befehl einen Fehler zurückgibt, wird das Problem möglicherweise von den SSH-Tunnels verursacht. Weitere Informationen finden Sie in diesem Abschnitt.

Wenn ein Problem mit dem Cloud Logging-Agent besteht, lesen Sie die Dokumentation zur Fehlerbehebung.

Weitere Informationen finden Sie in der Dokumentation zu Logging.

Fehlende Berechtigungen für das Konto für freigegebene VPC-Cluster

Achten Sie bei Clustern der freigegebenen VPC darauf, dass das GKE-Dienstkonto des Dienstprojekts eine Bindung für die Rolle Nutzer des Dienst-Agents für Host im Hostprojekt hat. Dies können Sie über die gcloud CLI tun.

Führen Sie den folgenden Befehl in Ihrem Hostprojekt aus, um zu prüfen, ob die Rollenbindung vorhanden ist:

gcloud projects get-iam-policy PROJECT_ID \
  --flatten="bindings[].members" \
  --format='table(bindings.role)' \
  --filter="bindings.members:SERVICE_ACCOUNT_NAME

Dabei gilt:

  • PROJECT_ID ist die ID Ihres Hostprojekts.
  • SERVICE_ACCOUNT_NAME: Der Name des GKE-Dienstkontos

Suchen Sie in der Ausgabe nach dem Rolle roles/container.hostServiceAgentUser.

ROLE
...
roles/container.hostServiceAgentUser
...

Wenn die Rolle hostServiceAgentUser nicht in der Liste enthalten ist, folgen Sie der Anleitung unter Rolle "Nutzer des Dienst-Agents für Host“ zuweisen, um die Bindung zum Dienstkonto hinzuzufügen.

Standarddienstkonto für Ihr Google Cloud-Projekt wiederherstellen

Die Verknüpfung des GKE-Standarddienstkontos container-engine-robot mit einem Projekt kann versehentlich aufgehoben werden. GKE-Dienst-Agent ist eine IAM-Rolle (Identity and Access Management), mit der dem Dienstkonto Berechtigungen zum Verwalten von Clusterressourcen erteilt werden. Wenn Sie diese Rollenbindung aus dem Dienstkonto entfernen, wird die Verknüpfung des Standarddienstkontos mit dem Projekt aufgehoben. Dies kann verhindern, dass Anwendungen bereitgestellt und andere Clustervorgänge ausgeführt werden.

Mit der gcloud CLI oder der Google Cloud Console können Sie prüfen, ob das Dienstkonto aus Ihrem Projekt entfernt wurde.

gcloud

Führen Sie diesen Befehl aus:

gcloud projects get-iam-policy PROJECT_ID

Ersetzen Sie PROJECT_ID durch Ihre Projekt-ID.

Console

Öffnen Sie in der Google Cloud Console die Seite IAM und Verwaltung.

Wenn im Befehl oder im Dashboard unter Ihren Dienstkonten container-engine-robot nicht angezeigt wird, wurde die Verknüpfung mit dem Dienstkonto aufgehoben.

Wenn Sie die Rollenbindung des GKE-Dienst-Agents entfernt haben, führen Sie die folgenden Befehle aus, um die Rollenbindung wiederherzustellen:

PROJECT_NUMBER=$(gcloud projects describe "PROJECT_ID" --format 'get(projectNumber)')
gcloud projects add-iam-policy-binding PROJECT_ID \
  --member "serviceAccount:service-${PROJECT_NUMBER?}@container-engine-robot.iam.gserviceaccount.com" \
  --role roles/container.serviceAgent

Mit dem folgenden Befehl bestätigen Sie, dass die Rollenbindung erteilt wurde:

gcloud projects get-iam-policy $PROJECT_ID

Wenn der Name des Dienstkontos zusammen mit der Rolle container.serviceAgent angezeigt wird, wurde die Rollenbindung erteilt. Beispiel:

- members:
  - serviceAccount:service-1234567890@container-engine-robot.iam.gserviceaccount.com
  role: roles/container.serviceAgent

Compute Engine-Standarddienstkonto aktivieren

Ihre Knoten können sich möglicherweise nicht beim Cluster registrieren, wenn das für den Knotenpool verwendete Dienstkonto deaktiviert ist. Dabei handelt es sich in der Regel um das Compute Engine-Standarddienstkonto.

Mit der gcloud CLI oder der Google Cloud Console können Sie prüfen, ob das Dienstkonto in Ihrem Projekt deaktiviert wurde.

gcloud

Führen Sie diesen Befehl aus:

gcloud iam service-accounts list  --filter="NAME~'compute' AND disabled=true"

Console

Öffnen Sie in der Google Cloud Console die Seite IAM & Verwaltung.

Wenn der Befehl oder das Dashboard anzeigt, dass das Dienstkonto deaktiviert ist, führen Sie den folgenden Befehl aus, um das Dienstkonto zu aktivieren:

gcloud iam service-accounts enable PROJECT_ID-compute@developer.gserviceaccount.com

Ersetzen Sie PROJECT_ID durch Ihre Projekt-ID.

Wenn die Probleme bei der Knotenregistrierung nicht behoben werden, finden Sie unter Fehlerbehebung bei der Knotenregistrierung weitere Informationen zur Fehlerbehebung.

Pods bleiben nach der Aktivierung der Option „Node Allocatable“ im Status „Ausstehend“

Wenn Pods nach der Aktivierung von Nodes Allocatable im Status Ausstehend hängen bleiben, beachten Sie Folgendes:

Ab Version 1.7.6 reserviert GKE CPU und Arbeitsspeicher für Kubernetes-Overhead, darunter auch für Docker und das Betriebssystem. Unter Clusterarchitektur finden Sie Informationen dazu, wie viel von jedem Maschinentyp durch Pods belegt werden kann.

Wenn Pods nach einem Upgrade ausstehen, empfehlen wir Folgendes:

  • Achten Sie darauf, dass die CPU- und Speicheranforderungen Ihrer Pods die maximale Auslastung nicht überschreiten. Da GKE CPU und Arbeitsspeicher für Overhead reserviert, können Pods diese Ressourcen nicht anfordern. Pods, die mehr CPU oder Arbeitsspeicher anfordern, als sie verwenden, verhindern, dass andere Pods diese Ressourcen anfordern. Der Cluster ist somit möglicherweise nicht optimal ausgelastet. Weitere Informationen finden Sie unter Pods mit Ressourcenanfragen planen.

  • Ziehen Sie eine Anpassung der Clustergröße in Betracht. Eine Anleitung finden Sie unter Clustergröße anpassen.

  • Führen Sie ein Downgrade des Clusters aus, um diese Änderung rückgängig zu machen. Eine Anleitung finden Sie unter Manuelles Upgrade eines Clusters oder Knotenpools.

Stammzertifizierungsstelle des Clusters läuft bald ab

Die Stammzertifizierungsstelle Ihres Clusters läuft bald ab. Damit der normale Clusterbetrieb nicht unterbrochen wird, müssen Sie die Rotation von Anmeldedaten durchführen.

Fehlermeldung "Instanz 'Foo' enthält nicht 'Instanzvorlage' Metadaten"

Möglicherweise wird die Fehlermeldung "Instanz 'Foo' enthält keine 'Instanzvorlage'-Metadaten" angezeigt. Dies ist der Status eines Knotenpools, der nicht aktualisiert, skaliert oder keine automatische Knotenreparatur durchgeführt wird.

Diese Meldung zeigt an, dass die Metadaten von VM-Instanzen, die von GKE zugewiesen wurden, beschädigt waren. Dies ist in der Regel der Fall, wenn benutzerdefinierte Automatisierungen oder Skripts versuchen, neue Instanzmetadaten wie block-project-ssh-keys hinzuzufügen. Statt nur Werte hinzuzufügen oder zu aktualisieren, werden vorhandene Metadaten ebenfalls gelöscht. Weitere Informationen zu VM-Instanzmetadaten finden Sie unter Benutzerdefinierte Metadaten einrichten.

Wenn einer der wichtigsten Metadatenwerte (darunter instance-template ,kube-labels ,kubelet-config ,kubeconfig ,cluster-name ,configure-sh ,cluster-uid ) gelöscht wurde, kann sich der Knoten oder der gesamte Knotenpool in einen instabilen Zustand versetzen, da diese Werte für GKE-Vorgänge entscheidend sind.

Wenn die Instanzmetadaten beschädigt waren, können Sie die Metadaten am besten wiederherstellen, indem Sie den Knotenpool mit den beschädigten VM-Instanzen neu erstellen. Sie müssen Ihrem Cluster einen Knotenpool hinzufügen und die Anzahl der Knoten im neuen Knotenpool erhöhen, während Sie Knoten in einem anderen Knotenpool sperren und entfernen. Weitere Informationen finden Sie in der Anleitung unter Arbeitslasten zwischen Knotenpools migrieren.

Informationen dazu, wer und wann Instanzmetadaten bearbeitet wurden, können Sie sich die Informationen zum Audit-Logging in Compute Engine ansehen oder Logs mithilfe des Log-Explorer einer ähnlichen Suchanfrage finden:

resource.type="gce_instance_group_manager"
protoPayload.methodName="v1.compute.instanceGroupManagers.setInstanceTemplate"

In den Protokollen finden Sie möglicherweise die IP-Adresse des Anfrageurhebers und den User-Agent:

requestMetadata: {
  callerIp: "REDACTED"
  callerSuppliedUserAgent: "google-api-go-client/0.5 GoogleContainerEngine/v1"
}

Cloud KMS-Schlüssel ist deaktiviert

Die folgende Fehlermeldung wird angezeigt, wenn das GKE-Standarddienstkonto nicht auf den Cloud KMS-Schlüssel zugreifen kann.

Cluster problem detected (Kubernetes Engine Service Agent account unable to use CloudKMS key configured for Application Level encryption).

Aktivieren Sie den deaktivierten Schlüssel noch einmal, um dieses Problem zu beheben.

Weitere Informationen zu Secrets in GKE finden Sie unter Secrets auf Anwendungsebene verschlüsseln.