Fehlerbehebung beim Load-Balancing in GKE


Auf dieser Seite wird beschrieben, wie Sie Probleme im Zusammenhang mit dem Load-Balancing in Google Kubernetes Engine-Clustern (GKE) mithilfe von Dienst-, Ingress- oder Gateway-Ressourcen beheben.

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

BackendConfig wurde nicht gefunden

Dieser Fehler tritt auf, wenn in der Dienstannotation eine BackendConfig-Ressource für einen Dienstport angegeben wurde, die eigentliche BackendConfig-Ressource jedoch nicht gefunden werden konnte.

Führen Sie den folgenden Befehl aus, um ein Kubernetes-Ereignis auszuwerten:

kubectl get event

Die folgende Ausgabe zeigt an, dass Ihre BackendConfig nicht gefunden wurde:

KIND    ... SOURCE
Ingress ... loadbalancer-controller

MESSAGE
Error during sync: error getting BackendConfig for port 80 on service "default/my-service":
no BackendConfig for service port exists

Achten Sie zur Behebung dieses Problems darauf, dass Sie die BackendConfig-Ressource nicht im falschen Namespace erstellt oder ihren Verweis in der Dienstannotation falsch geschrieben haben.

Ingress-Sicherheitsrichtlinie nicht gefunden

Wenn die Sicherheitsrichtlinie nach der Erstellung des Ingress-Objekts nicht ordnungsgemäß dem Load-Balancer-Dienst zugeordnet wird, sollten Sie das Kubernetes-Ereignis auf Konfigurationsfehler prüfen. Wenn Ihre BackendConfig eine Sicherheitsrichtlinie angibt, die nicht vorhanden ist, wird regelmäßig ein Warnungsereignis ausgegeben.

Führen Sie den folgenden Befehl aus, um ein Kubernetes-Ereignis auszuwerten:

kubectl get event

Die folgende Ausgabe zeigt an, dass Ihre Sicherheitsrichtlinie nicht gefunden wurde:

KIND    ... SOURCE
Ingress ... loadbalancer-controller

MESSAGE
Error during sync: The given security policy "my-policy" does not exist.

Geben Sie zur Behebung dieses Problems den richtigen Namen der Sicherheitsrichtlinie in Ihrer BackendConfig an.

500er-Fehler bei NEGs während der Arbeitslastskalierung in GKE beheben

Symptom:

Wenn Sie von GKE bereitgestellte NEGs für das Load-Balancing verwenden, können während der Herunterskalierung der Arbeitslast 502- oder 503-Fehler für die Dienste auftreten. 502-Fehler treten auf, wenn Pods beendet werden, bevor vorhandene Verbindungen geschlossen werden. Die 503-Fehler treten auf, wenn der Traffic an gelöschte Pods weitergeleitet wird.

Dieses Problem kann sich auf Cluster auswirken, wenn Sie von GKE verwaltete Load-Balancing-Produkte verwenden, die NEGs verwenden, einschließlich Gateway, Ingress und eigenständiger NEGs. Wenn Sie Ihre Arbeitslasten häufig skalieren, besteht ein höheres Risiko, dass Ihr Cluster betroffen ist.

Diagnose:

Das Entfernen eines Pods in Kubernetes, ohne seinen Endpunkt zu leeren und ihn aus der NEG zu entfernen, führt zu 500-Fehlern. Beachten Sie die Reihenfolge der Vorgänge, um Probleme während der Beendigung von Pods zu vermeiden. Die folgenden Abbildungen zeigen Szenarien, wenn BackendService Drain Timeout nicht festgelegt und BackendService Drain Timeout mit BackendConfig festgelegt ist.

Szenario 1: BackendService Drain Timeout ist nicht festgelegt.

In der folgenden Abbildung sehen Sie ein Szenario, in dem BackendService Drain Timeout nicht festgelegt ist.

BackendService-Drain-Zeitlimit ist nicht festgelegt

Szenario 2: BackendService Drain Timeout ist festgelegt.

Die folgende Abbildung zeigt ein Szenario, in dem BackendService Drain Timeout festgelegt ist.

Zeitlimit für Back-End-Drain ist festgelegt

Die genaue Zeit, zu der die 500er-Fehler auftreten, hängt von folgenden Faktoren ab:

  • NEG API-Trennlatenz: Die NEG API-Trennlatenz stellt die aktuelle Zeit dar, die für den Abschluss des Trennvorgangs in Google Cloud benötigt wird. Dies wird durch eine Vielzahl von Faktoren außerhalb von Kubernetes beeinflusst, einschließlich der Art des Load-Balancers und der jeweiligen Zone.

  • Drain-Latenz: Die Drain-Latenz stellt die Zeit dar, die für das Load-Balancing benötigt wird, um anzufangen, Traffic von einem bestimmten Teil Ihres Systems wegzuleiten. Nach dem Start des Leerens sendet der Load-Balancer keine neuen Anfragen an den Endpunkt mehr. Es besteht jedoch weiterhin eine Latenz beim Auslösen des Leerens (Drain-Latenz), was zu temporären 503-Fehlern führen kann, wenn der Pod nicht mehr vorhanden ist.

  • Konfiguration der Systemdiagnose: Sensible Schwellenwerte für Systemdiagnosen verringern die Dauer von 503-Fehlern, da dies dem Load-Balancer signalisieren kann, dass er keine Anfragen mehr an Endpunkte senden soll, auch wenn der Trennvorgang nicht abgeschlossen ist.

  • Kulanzzeitraum für die Beendigung: Der Kulanzzeitraum für die Beendigung bestimmt die maximale Zeit, die einem Pod zum Beenden gewährt wird. Ein Pod kann jedoch vor Ablauf des Kulanzzeitraums für die Beendigung beendet werden. Wenn ein Pod länger als dieser Zeitraum dauert, wird der Pod zum Beenden am Ende dieses Zeitraums gezwungen. Dies ist eine Einstellung auf dem Pod, die in der Arbeitslastdefinition konfiguriert werden muss.

Mögliche Lösung:

Wenden Sie die folgenden Einstellungen an, um diese 5XX-Fehler zu vermeiden. Die Zeitüberschreitungswerte sind Vorschläge und Sie müssen sie möglicherweise für Ihre spezifische Anwendung anpassen. Im folgenden Abschnitt werden Sie durch den Prozess der Anpassung geführt.

Die folgende Abbildung zeigt, wie Sie den Pod mit preStopHook aktiv halten:

Zeitlimit für Back-End-Drain ist festgelegt

Führen Sie die folgenden Schritte aus, um Fehler der 500er-Serie zu vermeiden:

  1. Legen Sie für BackendService Drain Timeout für Ihren Dienst eine Minute fest.

  2. Erweitern Sie terminationGracePeriod auf dem Pod.

    Legen Sie die terminationGracePeriodSeconds für den Pod auf 3,5 Minuten fest. In Kombination mit den empfohlenen Einstellungen haben Ihre Pods dadurch ein Fenster von 30 bis 45 Sekunden für ein ordnungsgemäßes Herunterfahren, nachdem der Endpunkt des Pods aus der NEG entfernt wurde. Wenn Sie mehr Zeit für das ordnungsgemäße Herunterfahren benötigen, können Sie den Kulanzzeitraum verlängern oder der Anleitung im Abschnitt Zeitüberschreitungen anpassen folgen.

    Das folgende Pod-Manifest gibt ein Zeitlimit von 210 Sekunden (3,5 Minuten) für den Verbindungsausgleich an:

    spec:
      terminationGracePeriodSeconds: 210
      containers:
      - name: my-app
        ...
      ...
    
  3. Wenden Sie eine preStopHook auf alle Container an.

    Wenden Sie eine preStopHook an, die dafür sorgt, dass der Pod 120 Sekunden länger aktiv ist, während der Endpunkt des Pods im Load-Balancer per Drain beendet und der Endpunkt aus der NEG entfernt wird.

    spec:
      containers:
      - name: my-app
        ...
        lifecycle:
          preStopHook:
            exec:
              command: ["/bin/sh", "-c", "sleep 120s"]
      ...
    

Zeitlimits anpassen

Zur Gewährleistung der Pod-Kontinuität und zur Vermeidung von 500-Fehlern muss der Pod aktiv sein, bis der Endpunkt aus der NEG entfernt wird. Insbesondere zur Vermeidung von 502- und 503-Fehlern sollten Sie eine Kombination aus Zeitüberschreitungen und einem preStopHook implementieren.

Fügen Sie dem Pod einen preStopHook hinzu, um den Pod während des Herunterfahrens länger aktiv zu halten. Führen Sie den preStopHook aus, bevor einem Pod das Beenden signalisiert wird. Damit kann preStopHook den Pod so lange behalten, bis der entsprechende Endpunkt aus der NEG entfernt wird.

Um die Dauer zu verlängern, die ein Pod während des Herunterfahrens aktiv bleibt, fügen Sie einen preStopHook in die Pod-Konfiguration so ein:

spec:
  containers:
  - name: my-app
    ...
    lifecycle:
      preStopHook:
        exec:
          command: ["/bin/sh", "-c", "sleep <latency time>"]

Sie können Zeitlimits und zugehörige Einstellungen konfigurieren, um das ordnungsgemäße Herunterfahren von Pods beim Herunterskalieren von Arbeitslasten zu verwalten. Sie können Zeitlimits anhand bestimmter Anwendungsfälle anpassen. Wir empfehlen, mit längeren Zeitlimits zu beginnen und die Dauer nach Bedarf zu verkürzen. Sie können die Zeitlimits anpassen, indem Sie Zeitüberschreitungsparameter und das preStopHook so konfigurieren:

Zeitlimit für Back-End-Dienst-Drain

Der Parameter Backend Service Drain Timeout ist standardmäßig nicht festgelegt und hat keine Auswirkungen. Wenn Sie den Parameter Backend Service Drain Timeout festlegen und aktivieren, beendet der Load Balancer das Routing neuer Anfragen an den Endpunkt und wartet das Zeitlimit, bevor vorhandene Verbindungen beendet werden.

Sie können den Parameter Backend Service Drain Timeout mit BackendConfig mit Ingress, mit GCPBackendPolicy mit Gateway oder manuell auf dem BackendService mit eigenständigen NEGs festlegen. eine Das Zeitlimit sollte 1,5- bis 2-mal länger sein als die Zeit, die für die Verarbeitung einer Anfrage benötigt wird. Dadurch wird sichergestellt, dass eine Anfrage, die kurz vor dem Drain eingegangen ist, abgeschlossen wird, bevor die Zeitüberschreitung beendet ist. Wenn Sie den Parameter Backend Service Drain Timeout auf einen Wert größer als 0 setzen, können Sie 503-Fehler beheben, da keine neuen Anfragen an Endpunkte gesendet werden, die zum Entfernen vorgemerkt sind. Damit dieses Zeitlimit wirksam ist, müssen Sie es in Verbindung mit preStopHook verwenden. So bleibt der Pod während des Drains aktiv. Ohne diese Kombination erhalten vorhandene Anfragen, die nicht abgeschlossen wurden, den Fehler 502.

Zeit preStopHook

preStopHook muss das Herunterfahren des Pods so lange verzögern, bis sowohl die Drain-Latenz als auch die Zeitüberschreitung für den Drain des Back-End-Dienstes abgeschlossen sind, sodass ein ordnungsgemäßer Verbindungsausgleich und die Entfernung des Endpunkts vom NEG gewährleistet sind, bevor der Pod heruntergefahren wird.

Für optimale Ergebnisse sollte die Ausführungszeit preStopHook kleiner oder gleich der Summe von Backend Service Drain Timeout- und Drain-Latenz sein.

Der Wert wird mit der folgenden Formel berechnet:

preStopHook >= Backend Service Drain Timeout + Drain Latency

Wir empfehlen, die Drain-Latenz auf eine Minute zu setzen. Wenn 500-Fehler bestehen bleiben, schätzen Sie die Gesamtdauer des Vorkommens und fügen Sie der Latenz das Doppelte davon hinzu. Dadurch wird sichergestellt, dass der Pod ausreichend Zeit zum ordnungsgemäßen Drain hat, bevor er aus dem Dienst entfernt wird. Sie können diesen Wert anpassen, wenn er für Ihren spezifischen Anwendungsfall zu lang ist.

Alternativ können Sie den Zeitpunkt schätzen, indem Sie den Löschzeitstempel aus dem Pod und den Zeitstempel prüfen, zu dem der Endpunkt in den Cloud-Audit-Logs aus der NEG entfernt wurde.

Parameter für den Kulanzzeitraum für Beendigung

Sie müssen den Parameter terminationGracePeriod so konfigurieren, dass genügend Zeit bleibt, damit der preStopHook abgeschlossen und der Pod ordnungsgemäß heruntergefahren werden kann.

Wenn nicht explizit festgelegt, beträgt die terminationGracePeriod standardmäßig 30 Sekunden. Sie können den optimalen terminationGracePeriod mit der folgenden Formel berechnen:

terminationGracePeriod >= preStopHook Time + Pod shutdown time

So definieren Sie terminationGracePeriod in der Pod-Konfiguration:

  spec:
    terminationGracePeriodSeconds: <terminationGracePeriod>
    containers:
    - name: my-app
      ...
    ...

NEG beim Erstellen einer internen Ingress-Ressource nicht gefunden

Der folgende Fehler kann auftreten, wenn Sie ein internes Ingress in GKE erstellen:

Error syncing: error running backend syncing routine: googleapi: Error 404: The resource 'projects/PROJECT_ID/zones/ZONE/networkEndpointGroups/NEG' was not found, notFound

Dieser Fehler tritt auf, weil Ingress für interne Anwendungs-Load-Balancer Netzwerk-Endpunktgruppen (NEGs) als Back-Ends erfordert.

Fügen Sie in Umgebungen mit freigegebener VPC oder Clustern mit aktivierten Netzwerkrichtlinien dem Servicemanifest die Annotation cloud.google.com/neg: '{"ingress": true}' hinzu.

504 Gateway-Zeitüberschreitung: Upstream-Zeitüberschreitung bei Anfrage

Der folgende Fehler kann auftreten, wenn Sie über einen internen Ingress in GKE auf einen Dienst zugreifen:

HTTP/1.1 504 Gateway Timeout
content-length: 24
content-type: text/plain

upsteam request timeout

Dieser Fehler tritt auf, weil Traffic, der an interne Anwendungs-Load-Balancer gesendet wird, von Envoy-Proxys im Nur-Proxy-Subnetzbereich weitergeleitet wird.

Erstellen Sie eine Firewallregel im targetPort des Dienstes, um Traffic aus dem Nur-Proxy-Subnetzbereich zuzulassen.

Fehler 400: Ungültiger Wert für das Feld "resource.target"

Der folgende Fehler kann auftreten, wenn Sie über einen internen Ingress in GKE auf einen Dienst zugreifen:

Error syncing:LB_NAME does not exist: googleapi: Error 400: Invalid value for field 'resource.target': 'https://www.googleapis.com/compute/v1/projects/PROJECT_NAME/regions/REGION_NAME/targetHttpProxies/LB_NAME. A reserved and active subnetwork is required in the same region and VPC as the forwarding rule.

Stellen Sie ein Nur-Proxy-Subnetz bereit, um dieses Problem zu beheben.

Fehler während der Synchronisierung: Fehler beim Ausführen der Synchronisierungsroutine des Load-Balancers: Load-Balancer existiert nicht

Einer der folgenden Fehler kann auftreten, wenn die GKE-Steuerungsebene aktualisiert wird oder Sie ein Ingress-Objekt ändern:

"Error during sync: error running load balancer syncing routine: loadbalancer
INGRESS_NAME does not exist: invalid ingress frontend configuration, please
check your usage of the 'kubernetes.io/ingress.allow-http' annotation."

oder:

Error during sync: error running load balancer syncing routine: loadbalancer LOAD_BALANCER_NAME does not exist:
googleapi: Error 400: Invalid value for field 'resource.IPAddress':'INGRESS_VIP'. Specified IP address is in-use and would result in a conflict., invalid

Um diese Probleme zu beheben, führen Sie die folgenden Schritte aus:

  • Fügen Sie das Feld hosts im Abschnitt tls des Ingress-Manifests hinzu und löschen Sie dann das Ingress-Objekt. Warten Sie fünf Minuten, bis GKE die nicht verwendeten Ingress-Ressourcen gelöscht hat. Erstellen Sie dann das Ingress neu. Weitere Informationen finden Sie unter Feld „Hosts“ eines Ingress-Objekts.
  • Setzen Sie die Änderungen zurück, die Sie am Ingress-Objekt vorgenommen haben. Fügen Sie dann ein Zertifikat mit einer Annotation oder einem Kubernetes-Secret hinzu.

Externer Ingress erzeugt HTTP-502-Fehler

Folgen Sie der nachstehenden Anleitung, um HTTP-502-Fehler mit externen Ingress-Ressourcen zu beheben:

  1. Aktivieren Sie Logs für jeden Backend-Dienst, der jedem GKE-Dienst zugeordnet ist, auf den der Ingress verweist.
  2. Verwenden Sie Statusdetails, um Ursachen für HTTP-502-Antworten zu identifizieren. Statusdetails, die angeben, dass die HTTP-502-Antwort vom Backend stammt, erfordern eine Fehlerbehebung innerhalb der Bereitstellungs-Pods, nicht im Load-Balancer.

Nicht verwaltete Instanzgruppen

Es können HTTP-502-Fehler mit externen Ingress-Ressourcen auftreten, wenn Ihr externes Ingress nicht verwaltete Instanzgruppen-Back-Ends verwendet. Dieses Problem tritt auf, wenn alle der folgenden Bedingungen erfüllt sind:

  • Der Cluster hat eine große Gesamtzahl von Knoten unter allen Knotenpools.
  • Die Bereitstellungs-Pods für einen oder mehrere Services, auf die vom Ingress verwiesen wird, befinden sich nur auf wenigen Knoten.
  • Dienste, auf die vom Ingress verwiesen wird, verwenden externalTrafficPolicy: Local.

So ermitteln Sie, ob Ihr externes Ingress nicht verwaltete Instanzgruppen-Back-Ends verwendet:

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

    Zum Ingress

  2. Klicken Sie auf den Namen Ihres externen Ingress.

  3. Klicken Sie auf den Namen des Load-Balancers. Die Seite Details zum Load-Balancing wird angezeigt.

  4. Prüfen Sie in der Tabelle im Abschnitt Backend-Dienste, ob Ihr externes Ingress NEGs oder Instanzgruppen verwendet.

Verwenden Sie eine der folgenden Lösungen, um dieses Problem zu beheben.

  • Verwenden Sie einen VPC-nativen Cluster.
  • Verwenden Sie externalTrafficPolicy: Cluster für jeden Service, auf den der externe Ingress verweist. Bei dieser Lösung gehen die ursprüngliche Client-IP-Adresse in den Quellen des Pakets verloren.
  • Verwenden Sie die Annotation node.kubernetes.io/exclude-from-external-load-balancers=true. Fügen Sie den Knoten oder Knotenpools, die keinen Bereitstellungs-Pod ausführen, die Annotation für einen Dienst hinzu, auf den von einem externen Ingress- oder LoadBalancer-Dienst in Ihrem Cluster verwiesen wird.

Load-Balancer-Logs zur Fehlerbehebung verwenden

Sie können Logs von internen Passthrough-Netzwerk-Load-Balancers und Logs von externen Passthrough-Netzwerk-Load-Balancer dazu verwenden, Probleme mit Load-Balancern zu beheben und Traffic von Load-Balancern mit GKE-Ressourcen zu korrelieren.

Logs werden pro Verbindung zusammengefasst und nahezu in Echtzeit exportiert. Logs werden sowohl für eingehenden als auch für ausgehenden Traffic für jeden GKE-Knoten generiert, der am Datenpfad eines LoadBalancer-Dienstes beteiligt ist. Logeinträge umfassen zusätzliche Felder für GKE-Ressourcen, z. B.: – Clustername – Clusterstandort – Dienstname – Dienstname – Pod-Name – Pod-Namespace

Preise

Für die Verwendung von Logs fallen keine zusätzlichen Gebühren an. Je nachdem, wie Sie Logs aufnehmen, gelten die Standardpreise für Cloud Logging, BigQuery oder Pub/Sub. Das Aktivieren von Logs hat keine Auswirkungen auf die Leistung des Load-Balancers.

Diagnosetools zur Fehlerbehebung verwenden

Das Diagnosetool check-gke-ingress prüft Ingress-Ressourcen auf häufige Fehlkonfigurationen. Sie können das check-gke-ingress-Tool auf folgende Arten verwenden:

  • Führen Sie das gcpdiag-Befehlszeilentool in Ihrem Cluster aus. Ergebnisse für eingehenden Traffic werden im Abschnitt der Prüfregel gke/ERR/2023_004 angezeigt.
  • Verwenden Sie das check-gke-ingress-Tool allein oder als kubectl-Plug-in. Folgen Sie dazu der Anleitung unter check-gke-ingress.

Nächste Schritte

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