Probleme beim Starten von Arbeitslasten in Cloud Service Mesh beheben

In diesem Dokument werden häufige Cloud Service Mesh-Probleme und deren Behebung erläutert . Weitere Informationen finden Sie unter Support.

Verbindung beim Erreichen eines Cloud Service Mesh-Endpunkts abgelehnt

Gelegentlich treten bei der Kommunikation von Ihren Clustern zu Ihren Endpunkten Fehler vom Typ „Verbindung abgelehnt“ (ECONNREFUSED) auf, z. B. bei Memorystore Redis, Cloud SQL oder einem externen Dienst, den Ihre Anwendungslast erreichen muss.

Dies kann auftreten, wenn Ihre Anwendungsarbeitslast schneller gestartet wird als istio-proxy (Envoy) und versucht, einen externen Endpunkt zu erreichen. Weil istio-init (initContainer) bereits ausgeführt, sind iptables-Regeln eingerichtet haben, die den gesamten ausgehenden Traffic an Envoy weiterleiten. Da der Istio-Proxy noch nicht bereit ist, wird der Traffic von den Iptables-Regeln an einen Sidecar-Proxy weitergeleitet, der noch nicht gestartet wurde. Daher erhält die Anwendung den Fehler ECONNREFUSED.

In den folgenden Schritten wird beschrieben, wie Sie prüfen können, ob es sich um Ihren Fehler handelt. erleben:

  1. Prüfen Sie die Stackdriver-Logs mit folgendem Filter, um zu ermitteln, welche Pods dass das Problem aufgetreten ist.

    Das folgende Beispiel zeigt eine typische Fehlermeldung:

    Error: failed to create connection to feature-store redis, err=dial tcp   192.168.9.16:19209: connect: connection refused
    [ioredis] Unhandled error event: Error: connect ECONNREFUSED
    
  2. Suchen Sie nach einem Auftreten des Problems. Wenn Sie Legacy-Stackdriver verwenden, Verwenden Sie dann resource.type="container".

    resource.type="k8s_container"
    textPayload:"$ERROR_MESSAGE$"
    
  3. Maximieren Sie das letzte Vorkommen, um den Namen des Pods zu erhalten, und notieren Sie sich der pod_name unter resource.labels.

  4. Rufen Sie das erste Auftreten des Problems für diesen Pod ab:

    resource.type="k8s_container"
    resource.labels.pod_name="$POD_NAME$"
    

    Beispielausgabe:

    E 2020-03-31T10:41:15.552128897Z
    post-feature-service post-feature-service-v1-67d56cdd-g7fvb failed to create
    connection to feature-store redis, err=dial tcp 192.168.9.16:19209: connect:
    connection refused post-feature-service post-feature-service-v1-67d56cdd-g7fvb
    
  5. Notieren Sie sich den Zeitstempel des ersten Fehlers für diesen Pod.

  6. Mit dem folgenden Filter können Sie die Pod-Startereignisse sehen.

    resource.type="k8s_container"
    resource.labels.pod_name="$POD_NAME$"
    

    Beispielausgabe:

    I 2020-03-31T10:41:15Z spec.containers{istio-proxy} Container image "docker.io/istio/proxyv2:1.3.3" already present on machine  spec.containers{istio-proxy}
    I 2020-03-31T10:41:15Z spec.containers{istio-proxy} Created container  spec.containers{istio-proxy}
    I 2020-03-31T10:41:15Z spec.containers{istio-proxy} Started container  spec.containers{istio-proxy}
    I 2020-03-31T10:41:15Z spec.containers{APP-CONTAINER-NAME} Created container  spec.containers{APP-CONTAINER-NAME}
    W 2020-03-31T10:41:17Z spec.containers{istio-proxy} Readiness probe failed: HTTP probe failed with statuscode: 503  spec.containers{istio-proxy}
    W 2020-03-31T10:41:26Z spec.containers{istio-proxy} Readiness probe failed: HTTP probe failed with statuscode: 503  spec.containers{istio-proxy}
    W 2020-03-31T10:41:28Z spec.containers{istio-proxy} Readiness probe failed: HTTP probe failed with statuscode: 503  spec.containers{istio-proxy}
    W 2020-03-31T10:41:31Z spec.containers{istio-proxy} Readiness probe failed: HTTP probe failed with statuscode: 503  spec.containers{istio-proxy}
    W 2020-03-31T10:41:58Z spec.containers{istio-proxy} Readiness probe failed: HTTP probe failed with statuscode: 503  spec.containers{istio-proxy}
    
  7. Verwenden Sie die Zeitstempel der Fehler und „istio-proxy-Startereignisse“, um zu bestätigen, Fehler auftreten, wenn Envoy nicht bereit ist.

    Wenn die Fehler auftreten, während der istio-proxy-Container noch nicht bereit ist, Fehler beim Abrufen der Verbindung abgelehnt. Im vorherigen Beispiel hat der Pod bereits ab 2020-03-31T10:41:15.552128897Z versucht, eine Verbindung zu Redis herzustellen. Bis zum 2020-03-31T10:41:58Z hat der Istio-Proxy jedoch weiterhin keine Bereitschaftstests bestanden.

    Auch wenn der Istio-Proxy-Container zuerst gestartet wurde, ist es möglich, dass er nicht schnell genug einsatzbereit war, bevor die App bereits versucht hat, eine Verbindung zum externen Endpunkt herzustellen.

    Wenn dies Ihr Problem ist, fahren Sie mit der folgenden Schritten zur Fehlerbehebung.

  8. Annotieren Sie die Konfiguration auf Pod-Ebene. Diese Funktion ist nur auf Pod-Ebene und nicht auf globaler Ebene verfügbar.

    annotations:
    proxy.istio.io/config: '{ "holdApplicationUntilProxyStarts": true }'
    
  9. Ändern Sie den Anwendungscode so, dass vorher geprüft wird, ob Envoy bereit ist. versucht, andere Anfragen an externe Dienste zu senden. Zum Beispiel auf Anwendungsstart, Initiieren einer Schleife, über die Anfragen an den istio-proxy gesendet werden und wird erst fortgesetzt, wenn der Fehler 200 erreicht wird. istio-proxy lautet der Gesundheitsendpunkt:

    http://localhost:15020/healthz/ready
    

Race-Bedingung während der Sidecar-Injektion zwischen Vault und Cloud Service Mesh

Wenn Sie vault für die Secrets-Verwaltung verwenden, fügt vault manchmal Sidecar vor istio ein, was dazu führt, dass Pods im Status Init hängen bleiben. In diesem Fall bleiben die erstellten Pods nach dem Neustart einer Bereitstellung oder der Bereitstellung einer neuen Bereitstellung im Status „Init“ hängen. Beispiel:

E 2020-03-31T10:41:15.552128897Z
post-feature-service post-feature-service-v1-67d56cdd-g7fvb failed to create
connection to feature-store redis, err=dial tcp 192.168.9.16:19209: connect:
connection refused post-feature-service post-feature-service-v1-67d56cdd-g7fvb

Dieses Problem wird durch eine Race-Bedingung verursacht, die sowohl von Istio als auch von vault injiziert wird. Sidecar und Istio müssen dies als Letztes tun. Der istio-Proxy wird nicht ausgeführt. während der Init-Container. Der istio-Init-Container richtet Iptables-Regeln ein, um den gesamten Traffic an den Proxy weiterzuleiten. Da der Dienst noch nicht ausgeführt wird, werden diese Regeln auf nichts weitergeleitet und der gesamte Traffic wird blockiert. Deshalb muss der Init-Container als letzter ausgeführt werden, damit der Proxy sofort nach der Einrichtung der iptables-Regeln einsatzbereit ist. Leider ist die Reihenfolge nicht deterministisch. Wenn also Istio injiziert wird, aber zuerst geht es kaputt.

Um dieses Problem zu beheben, lassen Sie die IP-Adresse von vault zu, damit der Traffic wird nicht an den nicht bereitstehenden Envoy-Proxy weitergeleitet. wodurch die Kommunikation blockiert wird. Um dies zu erreichen, wird eine neue Anmerkung namens excludeOutboundIPRanges hinzugefügt werden.

Bei verwaltetem Cloud Service Mesh ist dies nur auf Bereitstellungs- oder Podebene unter spec.template.metadata.annotations möglich, z. B.:

apiVersion: apps/v1
kind: Deployment
...
...
...
spec:
  template:
    metadata:
      annotations:
        traffic.sidecar.istio.io/excludeOutboundIPRanges:

Für ein clusterinternes Cloud Service Mesh gibt es die Möglichkeit, es unter spec.values.global.proxy.excludeIPRanges als globalen Dienst mit einem IstioOperator festzulegen, z. B.:

apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
  values:
    global:
      proxy:
        excludeIPRanges: ""

Starten Sie Ihre Arbeitslasten neu, nachdem Sie die Anmerkung hinzugefügt haben.