Proxyprobleme in Anthos Service Mesh beheben
In diesem Dokument werden häufige Probleme mit Anthos Service Mesh und deren Behebung erläutert. 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 einen externen Dienst, den Ihre Anwendungsarbeitslast erreichen muss.
Dieser Fehler kann auftreten, wenn Ihre Anwendungsarbeitslast schneller initiiert wird als deristio-Proxy-Container (Envoy
) und versucht, einen externen Endpunkt zu erreichen. Da in dieser Phase istio-init (initContainer
) bereits ausgeführt wurde, sind iptables-Regeln vorhanden, 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 prüfen können, ob dieser Fehler auftritt:
Prüfen Sie die Google Cloud-Beobachtbarkeitslogs mit dem folgenden Filter, um herauszufinden, 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
Prüfen Sie die Google Cloud-Beobachtbarkeitslogs mit dem folgenden Filter, um zu bestätigen, dass der Istio-Proxy-Container (
Envoy
) nicht bereit ist.resource.labels.pod_name="$POD_FROM_STEP_1$" resource.type="k8s_container" resource.labels.container_name="istio-proxy" textPayload:"Envoy proxy is NOT ready"
Suchen Sie nach einem Vorkommen des Problems. Wenn Sie Legacy-Stackdriver verwenden, verwenden Sie
resource.type="container"
.resource.type="k8s_container" textPayload:"$ERROR_MESSAGE$"
Maximieren Sie das letzte Vorkommen, um den Namen des Pods zu erhalten, und notieren Sie sich dann den
pod_name
unterresource.labels
.Ermitteln Sie, 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
Notieren Sie sich den Zeitstempel des ersten Fehlers für diesen Pod.
Verwenden Sie den folgenden Filter, um die Pod-Startereignisse aufzurufen.
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}
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 abgelehnt wurde. Im vorherigen Beispiel versuchte der Pod, eine Verbindung zu Redis herzustellen, sobald
2020-03-31T10:41:15.552128897Z
, aber von2020-03-31T10:41:58Z
istio-proxy immer noch die Bereitschaftsprüfungen fehlschlug.Obwohl der istio-proxy-Container zuerst gestartet wurde, ist es möglich, dass er nicht schnell genug bereit war, bevor die Anwendung bereits versuchte, eine Verbindung zum externen Endpunkt herzustellen.
Wenn dies das Problem ist, fahren Sie mit den folgenden Schritten zur Fehlerbehebung fort.
Versehen Sie die Konfiguration auf Pod-Ebene. Diese Option ist nur auf Pod-Ebene und nicht auf globaler Ebene verfügbar.
annotations: proxy.istio.io/config: '{ "holdApplicationUntilProxyStarts": true }'
Ändern Sie den Anwendungscode so, dass geprüft wird, ob
Envoy
bereit ist, bevor versucht wird, weitere Anfragen an externe Dienste zu senden. Initiieren Sie beispielsweise beim Start der Anwendung eine Schleife, die Anfragen an den istio-proxy-Gesundheitsendpunkt sendet und erst dann fortgesetzt wird, wenn ein 200-Fehler empfangen wird. Der istio-proxy-Systemdiagnoseendpunkt ist so:http://localhost:15020/healthz/ready
Race-Bedingung während Sidecar-Injektion zwischen Vault und Istio
Wenn Sie vault
für die Secret-Verwaltung verwenden, fügt vault
manchmal die Sidecar-Datei vor istio
ein. Dadurch bleiben Pods im Status Init
hängen. In diesem Fall verbleiben die erstellten Pods nach dem Neustart einer Bereitstellung oder der Bereitstellung einer neuen Bereitstellung im Init-Status. 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 das Sidecar und Istio als Letztes ein. Der istio
-Proxy wird in Init-Containern 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, werden durch diese Regeln keine Weiterleitungen ausgeführt, sodass der gesamte Traffic blockiert wird. Aus diesem Grund muss der Init-Container der letzte sein, sodass der Proxy sofort nach dem Einrichten der iptables-Regeln aktiv ist und ausgeführt wird. Leider ist die Reihenfolge nicht deterministisch. Wenn Istio also zuerst eingeschleust wird, funktioniert es nicht.
Um diesen Fehler zu beheben, müssen Sie die IP-Adresse vault
zulassen, damit der an die Vault-IP-Adresse 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 einem 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:
Anthos Service Mesh im Cluster kann mit einem IstioOperator unter spec.values.global.proxy.excludeIPRanges
als globales Netzwerk festgelegt werden. 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.