Resuelve problemas de proxy en Cloud Service Mesh
En este documento, se explican los problemas comunes de Cloud Service Mesh y cómo resolverlos. Si necesitas asistencia adicional, consulta Obtén asistencia.
Se rechaza la conexión cuando se llega a un extremo con Istio
Es posible que experimentes errores de conexión rechazadas (ECONNREFUSED
) de forma intermitente.
con la comunicación de los clústeres a los extremos, por ejemplo, Memorystore
Redis, Cloud SQL o cualquier servicio externo que necesite la carga de trabajo de tu aplicación
tu alcance.
Esto puede ocurrir cuando la carga de trabajo de tu aplicación se inicia más rápido que el contenedor istio-proxy (Envoy
) y trata de llegar a un extremo externo. Debido a que, en esta etapa, istio-init (initContainer
) ya se ejecutó, existen reglas de iptables que redireccionan todo el tráfico saliente a Envoy
. Desde
istio-proxy aún no está listo, las reglas iptables redireccionarán el tráfico a un
proxy de sidecar que aún no se inició y que, por lo tanto, la aplicación obtiene
ECONNREFUSED
error.
En los siguientes pasos, se detalla cómo verificar si este es el error que estás que experimenta:
Verifica los registros de Stackdriver con el siguiente filtro para identificar los Pods tuvieron el problema.
En el siguiente ejemplo, se muestra un mensaje de error típico:
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
Busca un caso del problema. Si usas Stackdriver heredado, Luego, usa
resource.type="container"
.resource.type="k8s_container" textPayload:"$ERROR_MESSAGE$"
Expande la ocurrencia más reciente para obtener el nombre del pod y, luego, toma nota de
pod_name
enresource.labels
.Obtén el primer caso del problema para ese Pod:
resource.type="k8s_container" resource.labels.pod_name="$POD_NAME$"
Salida de ejemplo:
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
Anota la marca de tiempo del primer error de este pod.
Usa el siguiente filtro para ver los eventos de inicio del Pod.
resource.type="k8s_container" resource.labels.pod_name="$POD_NAME$"
Salida de ejemplo:
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}
Usa las marcas de tiempo de los errores y los eventos de inicio de istio-proxy para confirmar que los errores ocurren cuando
Envoy
no está listo.Si los errores se producen cuando el contenedor istio-proxy aún no está listo, es normal obtener errores de conexión rechazada. En el ejemplo anterior, el pod intentaba conectarse a Redis en cuanto se iniciaba
2020-03-31T10:41:15.552128897Z
, pero a2020-03-31T10:41:58Z
, istio-proxy aún fallaba en las pruebas de preparación.Aunque el contenedor istio-proxy se inició primero, es posible que no se preparaba lo suficientemente rápido antes de que la app ya intentaba conectarse al extremo externo.
Si este es el problema que tienes, continúa con el siguiendo los pasos para solucionar problemas.
Anota la configuración a nivel del Pod. Esta opción solo está disponible en el grupo de anuncios. y no a nivel global.
annotations: proxy.istio.io/config: '{ "holdApplicationUntilProxyStarts": true }'
Modifica el código de la aplicación para que verifique si
Envoy
está listo antes de intentar realizar otras solicitudes a servicios externos. Por ejemplo, en inicio de la aplicación, iniciar un bucle que realice solicitudes al istio-proxy de estado y continúa una vez que se obtiene un 200. El extremo de estado de istio-proxy es el siguiente:http://localhost:15020/healthz/ready
Condición de carrera durante la inyección de sidecar entre Vault y Istio
Cuando se usa vault
para la administración de secretos, a veces vault
inyecta el contenedor secundario antes que istio
, lo que hace que los Pods se bloqueen en el estado Init
. Cuando esto sucede, los Pods creados se bloquean en el estado de inicialización después de reiniciar cualquier implementación o de implementar una nueva. Por ejemplo:
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
Este problema se debe a una condición de carrera. Tanto Istio como vault
insertan el contenedor lateral, y Istio debe ser el último en hacerlo. El proxy de istio
no se ejecuta durante los contenedores de inicio. El contenedor init istio
configura las reglas de iptables para
redireccionar todo el tráfico al proxy. Como aún no se ejecuta, esas reglas no redireccionan a nada y bloquean todo el tráfico. Por este motivo, el contenedor init debe ser el último, de modo que el proxy esté en funcionamiento inmediatamente después de que se configuren las reglas de iptables. Lamentablemente, el orden no es determinista, por lo que, si se inyecta Istio primero, se produce un error.
Para solucionar este problema, permite la dirección IP de vault
para que el tráfico que se dirige a la IP de Vault no se redireccione al proxy de Envoy, que aún no está listo y, por lo tanto, bloquea la comunicación. Para lograrlo, se creó una nueva anotación
con el nombre excludeOutboundIPRanges
.
Para Cloud Service Mesh administrado, esto solo es posible a nivel de Deployment o Pod
en spec.template.metadata.annotations
, por ejemplo:
apiVersion: apps/v1
kind: Deployment
...
...
...
spec:
template:
metadata:
annotations:
traffic.sidecar.istio.io/excludeOutboundIPRanges:
En el caso de Cloud Service Mesh en el clúster, existe la opción de configurarlo como uno global con un IstioOperator en spec.values.global.proxy.excludeIPRanges
, por ejemplo:
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
values:
global:
proxy:
excludeIPRanges: ""
Después de agregar la anotación, reinicia tus cargas de trabajo.