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

Beim Erreichen eines Endpunkts mit Istio wurde die Verbindung abgelehnt

Möglicherweise treten zeitweise Fehler aufgrund einer abgelehnten Verbindung (ECONNREFUSED) auf. mit der Kommunikation von Ihren Clustern zu Ihren Endpunkten, z. B. Memorystore Redis, CloudSQL oder ein anderer externer Dienst, den Ihre Anwendungsarbeitslast benötigt Reichweite.

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. Seit istio-proxy noch nicht bereit ist, leiten die iptables-Regeln den Traffic Sidecar-Proxy, der noch nicht gestartet wurde, sodass die Anwendung den ECONNREFUSED Fehler.

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. Ermitteln, wann das Problem zum ersten Mal für diesen Pod aufgetreten ist:

    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. Verwenden Sie den folgenden Filter, um die Pod-Startereignisse zu 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 hat versucht, eine Verbindung zu Redis herzustellen, sobald 2020-03-31T10:41:15.552128897Z aber durch 2020-03-31T10:41:58Z schlagen istio-proxy immer noch fehlgeschlagen.

    Obwohl der istio-proxy-Container zuerst gestartet wurde, ist es möglich, dass er war nicht schnell genug bereit, bevor die App bereits versuchte, eine Verbindung herzustellen an den externen Endpunkt.

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

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

    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 Sidecar-Einschleusung zwischen Vault und Istio

Bei Verwendung von vault für die Verwaltung von Secrets wird manchmal durch vault eine Sidecar-Datei eingeschleust vor istio, wodurch Pods im Status Init hängen bleiben. In diesem Fall Die erstellten Pods bleiben nach dem Neustart einer Bereitstellung oder die Bereitstellung einer neuen. 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 Init-Container istio richtet iptables-Regeln ein, um den gesamten Traffic an den Proxy weiterleiten. Da sie noch nicht ausgeführt wird, in nichts und den gesamten Traffic blockieren. Aus diesem Grund muss der Init-Container damit der Proxy sofort einsatzbereit ist, nachdem die iptables-Regeln erstellt wurden, einrichten. Leider ist die Reihenfolge nicht deterministisch. Wenn also Istio injiziert wird, und erst einmal kaputt 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.

Beim verwalteten Cloud Service Mesh ist dies nur auf Bereitstellungs- oder Pod-Ebene möglich unter spec.template.metadata.annotations, zum Beispiel:

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

Für clusterinternes Cloud Service Mesh gibt es eine Option, um es als globales Service Mesh festzulegen mit Einen IstioOperator unter spec.values.global.proxy.excludeIPRanges. Beispiel:

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

Starten Sie Ihre Arbeitslasten nach dem Hinzufügen der Annotation neu.