Resuelve problemas relacionados con el proxy en Anthos Service Mesh

En este documento, se explican los problemas comunes de Anthos Service Mesh y cómo resolverlos. Si necesitas asistencia adicional, consulta Obtén asistencia.

Conexión rechazada cuando se llega a un extremo con Istio

Es posible que experimentes errores de conexión rechazada (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 al que deba acceder la carga de trabajo de la aplicación.

Esto puede ocurrir cuando la carga de trabajo de la aplicación se inicia más rápido que el contenedor inclusive-proxy (Envoy) y trata de llegar a un extremo externo. Debido a que, en esta etapa, ist-init (initContainer) ya se ejecutó, existen reglas de iptables que redireccionan todo el tráfico saliente a Envoy. Dado que instales el proxy aún no está listo, las reglas de iptables redireccionarán el tráfico a un proxy de sidecar que aún no se inició y, por lo tanto, la aplicación recibe el error ECONNREFUSED.

En los siguientes pasos, se detalla cómo verificar si este es el error que experimentas:

  1. Verifica los registros de Stackdriver con el siguiente filtro para identificar qué 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
    
  2. Busca un caso del problema. Si usas Stackdriver heredado, usa resource.type="container".

    resource.type="k8s_container"
    textPayload:"$ERROR_MESSAGE$"
    
  3. Expande el caso más reciente para obtener el nombre del Pod y, luego, toma nota del pod_name en resource.labels.

  4. Obtén la primera instancia del problema de ese Pod:

    resource.type="k8s_container"
    resource.labels.pod_name="$POD_NAME$"
    

    Resultado 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
    
  5. Tome nota de la marca de tiempo del primer error de este Pod.

  6. Usa el siguiente filtro para ver los eventos de inicio del Pod.

    resource.type="k8s_container"
    resource.labels.pod_name="$POD_NAME$"
    

    Resultado 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}
    
  7. Usa las marcas de tiempo de los errores y de los eventos de inicio de ini-proxy para confirmar que los errores se producen cuando Envoy no está listo.

    Si los errores se producen mientras el contenedor latino-proxy aún no está listo, es normal que se obtengan errores de conexión rechazada. En el ejemplo anterior, el Pod intentaba conectarse a Redis en cuanto 2020-03-31T10:41:15.552128897Z, pero 2020-03-31T10:41:58Z implementaciones-proxy aún estaba fallando en los sondeos de preparación.

    Si bien el contenedor latino-proxy se inició primero, es posible que no esté listo lo suficientemente rápido antes de que la app ya intentara conectarse al extremo externo.

    Si este es el problema que tienes, continúa con los siguientes pasos para solucionarlos.

  8. Anota la configuración a nivel del Pod. Esto solo está disponible a nivel del Pod y no a nivel global.

    annotations:
    proxy.istio.io/config: '{ "holdApplicationUntilProxyStarts": true }'
    
  9. 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, cuando se inicie la aplicación, inicia un bucle que realice solicitudes al extremo de estado instales-proxy y que solo continúe una vez que se obtenga un valor 200. El extremo de estado de om-proxy es el siguiente:

    http://localhost:15020/healthz/ready
    

Condición de carrera durante la inyección de archivo adicional entre vault y Istio

Cuando se usa vault para la administración de secretos, a veces vault inserta un archivo adicional antes de istio, lo que hace que los Pods queden atascados en el estado Init. Cuando esto sucede, los Pods creados se atascan en el estado Init 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 inyectan el archivo adicional, y Istio debe ser el último que lo haga. El proxy istio no se ejecuta durante los contenedores init. El contenedor de inicialización istio configura reglas de iptables para redireccionar todo el tráfico al proxy. Dado que aún no se está ejecutando, esas reglas no redireccionan a nada y bloquean todo el tráfico. Por eso, el contenedor init debe ser el último para que el proxy esté en funcionamiento de inmediato después de configurar las reglas de iptables. Por desgracia, el orden no es determinista, por lo que, si primero se inserta Istio, se interrumpe.

Para solucionar este problema, permite la dirección IP de vault a fin de que el tráfico que vaya a la IP de Vault no se redireccione al proxy de Envoy que aún no está listo y, por lo tanto, bloquee la comunicación. Para lograrlo, se debe agregar una anotación nueva llamada excludeOutboundIPRanges.

Para Anthos Service Mesh administrado, esto solo es posible a nivel de Deployment o de Pod en spec.template.metadata.annotations, por ejemplo:

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

En Anthos 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 las cargas de trabajo.