Probleme beim Starten von Arbeitslasten in Cloud Service Mesh beheben
In diesem Dokument werden häufig auftretende Cloud Service Mesh-Probleme und deren Behebung erläutert. Weitere Informationen finden Sie unter Support.
Gateway kann nicht mit einem distroless-Proxy gestartet werden, wenn ein privilegierter Port freigegeben ist
Der distroless-Proxy wird standardmäßig mit nicht-root-Berechtigungen gestartet, was in einigen Fällen zu Bindungsfehlern auf privilegierten Ports führen kann. Wenn beim Starten des Proxys Fehler wie die folgenden angezeigt werden, muss für die Gateway-Bereitstellung ein zusätzlicher securityContext angewendet werden.
Error adding/updating listener(s) 0.0.0.0_80: cannot bind '0.0.0.0:80': Permission denied
Das folgende Beispiel ist die YAML-Datei für ein Egress-Gateway-Deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
name: istio-egressgateway
spec:
selector:
matchLabels:
app: istio-egressgateway
istio: egressgateway
template:
metadata:
annotations:
# This is required to tell Anthos Service Mesh to inject the gateway with the
# required configuration.
inject.istio.io/templates: gateway
labels:
app: istio-egressgateway
istio: egressgateway
spec:
containers:
- name: istio-proxy
image: auto # The image will automatically update each time the pod starts.
resources:
limits:
cpu: 2000m
memory: 1024Mi
requests:
cpu: 100m
memory: 128Mi
# Allow binding to all ports (such as 80 and 443)
securityContext:
sysctls:
- name: net.ipv4.ip_unprivileged_port_start
value: "0"
serviceAccountName: istio-egressgateway
Verbindung wird 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 die Anwendungslast schneller gestartet 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 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
.
So prüfen Sie, ob dieser Fehler vorliegt:
Prüfen Sie die Stackdriver-Protokolle 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
Suchen Sie nach einem Auftreten des Problems. Wenn Sie Legacy Stackdriver verwenden, verwenden Sie
resource.type="container"
.resource.type="k8s_container" textPayload:"$ERROR_MESSAGE$"
Maximieren Sie die letzte Zeile, um den Namen des Pods zu sehen, und notieren Sie sich die
pod_name
unterresource.labels
.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
Notieren Sie sich den Zeitstempel des ersten Fehlers für diesen Pod.
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}
Anhand der Zeitstempel der Fehler und der Istio-Proxy-Startereignisse können Sie 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, ist es normal, dass Fehlermeldungen zur Verbindungsverweigerung auftreten. Im vorherigen Beispiel hat der Pod bereits ab
2020-03-31T10:41:15.552128897Z
versucht, eine Verbindung zu Redis herzustellen, aber bis2020-03-31T10:41:58Z
hat der Istio-Proxy 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 das bei dir der Fall ist, fahre mit den folgenden Schritten zur Fehlerbehebung fort.
Fügen Sie die Anmerkungen auf Pod-Ebene hinzu. 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 weitere Anfragen an externe Dienste gesendet werden. Sie können beispielsweise beim Starten der Anwendung eine Schleife starten, die Anfragen an den Istio-Proxy-Systemdiagnoseendpunkt sendet und erst fortgesetzt wird, wenn der Statuscode 200 zurückgegeben wird. Der Endpunkt „health“ des Istio-Proxys lautet:http://localhost:15020/healthz/ready
Race Condition bei der Sidecar-Injection 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. Sowohl Istio als auch vault
fügen den Sidecar ein und Istio muss dies als Letztes tun. Der istio
-Proxy wird während der Initialisierung von Containern nicht ausgeführt. 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 zuerst eingefügt wird, funktioniert es nicht.
Um dieses Problem zu beheben, erlauben Sie die IP-Adresse von vault
, damit der Traffic, der an die Vault-IP-Adresse gesendet wird, nicht an den Envoy-Proxy weitergeleitet wird, der noch nicht bereit ist und daher die Kommunikation blockiert. Dazu muss eine neue Anmerkung mit dem Namen 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.