Proxyprobleme in Anthos Service Mesh beheben

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

Verbindung abgelehnt, wenn ein Endpunkt mit Istio erreicht wird

Bei der Kommunikation von Ihren Clustern zu Ihren Endpunkten können zeitweise Fehler aufgrund einer abgelehnten Verbindung (ECONNREFUSED) auftreten, z. B. Memorystore Redis, Cloud SQL oder einem externen Dienst, den Ihre Anwendungsarbeitslast erreichen muss.

Dies kann auftreten, wenn die Arbeitslast Ihrer Anwendung schneller initiiert wird als der istio-Proxy-Container (Envoy) und versucht, einen externen Endpunkt zu erreichen. Da in dieser Phase istio-init (initContainer) bereits ausgeführt wurde, gibt es iptables-Regeln, die den gesamten ausgehenden Traffic an Envoy weiterleiten. Da istio-proxy noch nicht bereit ist, leiten die iptables-Regeln den Traffic an einen noch nicht gestarteten Sidecar-Proxy weiter. Daher erhält die Anwendung den Fehler ECONNREFUSED.

In den folgenden Schritten wird beschrieben, wie Sie überprüfen können, ob dieser Fehler auftritt:

  1. Prüfen Sie die Stackdriver-Logs mit dem folgenden Filter, um zu ermitteln, bei welchen Pods 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 Vorkommen des Problems. Wenn Sie Legacy-Stackdriver verwenden, verwenden Sie 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 den pod_name unter resource.labels.

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

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

    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 von Fehlern und istio-Proxy-Startereignisse, um zu prüfen, ob die Fehler auftreten, wenn Envoy nicht bereit ist.

    Wenn die Fehler auftreten, während der istio-Proxy-Container noch nicht bereit ist, erhalten Sie normalerweise Fehlermeldungen, weil die Verbindung verweigert wurde. Im vorherigen Beispiel versuchte der Pod, eine Verbindung zu Redis herzustellen, sobald 2020-03-31T10:41:15.552128897Z die Bereitschaftsprüfungen von 2020-03-31T10:41:58Z durch den Istio-Proxy fehlschlug.

    Obwohl der istio-Proxy-Container zuerst gestartet wurde, ist er möglicherweise nicht schnell genug bereit, bevor die Anwendung bereits versucht hat, eine Verbindung zum externen Endpunkt herzustellen.

    Wenn dies das Problem ist, fahren Sie mit den folgenden Schritten zur Fehlerbehebung fort.

  8. Annotieren Sie die Konfiguration auf Pod-Ebene. Dies 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 geprüft wird, ob Envoy bereit ist, bevor weitere Anfragen an externe Dienste gesendet werden. Initiieren Sie beispielsweise beim Start der Anwendung eine Schleife, die Anfragen an den istio-Proxy-Gesundheitsendpunkt sendet und erst fortgesetzt wird, wenn ein 200-Fehler vorliegt. Der istio-Proxy-Sicherheitsendpunkt ist so:

    http://localhost:15020/healthz/ready
    

Race-Bedingung während Sidecar-Injektion zwischen Vault und istio

Wenn Sie vault für die Verwaltung von Secrets verwenden, fügt vault manchmal die Sidecar-Datei vor istio ein. Dies führt dazu, dass Pods im Status Init hängen bleiben. In diesem Fall bleiben die erstellten Pods im Init-Status hängen, nachdem ein Deployment neu gestartet oder ein neues Deployment bereitgestellt wurde. 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. Sowohl Istio als auch vault fügen den Sidecar ein und Istio müssen das letzte sein. Der istio-Proxy wird während der Init-Container nicht ausgeführt. Der Init-Container istio richtet iptables-Regeln ein, um den gesamten Traffic an den Proxy weiterzuleiten. Da sie noch nicht ausgeführt wird, leiten diese Regeln zu nichts weiter und blockieren den gesamten Traffic. Aus diesem Grund muss der Init-Container der letzte sein, sodass der Proxy sofort nach dem Einrichten der iptables-Regeln ausgeführt wird. Leider ist die Reihenfolge nicht deterministisch. Wenn Istio also zuerst eingefügt wird, funktioniert es nicht.

Um diesen Fehler zu beheben, lassen Sie die IP-Adresse von vault zu, damit der an die Vault-IP gehende Traffic nicht an den Envoy-Proxy weitergeleitet wird, der noch nicht bereit ist und die Kommunikation daher blockiert. Dazu muss eine neue Annotation mit dem Namen excludeOutboundIPRanges hinzugefügt werden.

Bei verwalteten Anthos Service Mesh ist dies nur auf Deployment- oder Pod-Ebene unter spec.template.metadata.annotations möglich. Beispiel:

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

Für Anthos Service Mesh im Cluster gibt es eine Option, um es als globales mit einem IstioOperator unter spec.values.global.proxy.excludeIPRanges festzulegen. Beispiel:

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

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