Resuelve problemas de inicio de cargas de trabajo en Cloud Service Mesh

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

Se rechazó la conexión cuando se llega a un extremo de la malla de servicios de Cloud

Es posible que experimentes errores de conexión rechazadas (ECONNREFUSED) de forma intermitente. con la comunicación de los clústeres a los endpoints, por ejemplo Memorystore Redis, Cloud SQL o cualquier servicio externo a tu aplicación la carga de trabajo debe alcanzar.

Esto puede ocurrir cuando la carga de trabajo de tu aplicación se inicia más rápido que la istio-proxy (Envoy) y trata de llegar a un extremo externo. Porque En esta etapa, istio-init (initContainer) ya se ejecutó, existen Reglas de iptables vigentes 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:

  1. 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
    
  2. Busca un caso del problema. Si usas Stackdriver heredado, Luego, 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 de pod_name en resource.labels.

  4. 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
    
  5. Toma 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$"
    

    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}
    
  7. Usa las marcas de tiempo de los errores y los eventos de inicio de istio-proxy para confirmar se producen errores 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 intentó conectarse a Redis en cuanto 2020-03-31T10:41:15.552128897Z pero, por 2020-03-31T10:41:58Z, istio-proxy aún fallaba los sondeos 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.

  8. 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 }'
    
  9. Modifica el código de la aplicación para que verifique si Envoy está listo antes de hacerlo intenta realizar cualquier otra solicitud 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 proxy istio-proxy de estado de Terraform funciona de la siguiente manera:

    http://localhost:15020/healthz/ready
    

Condición de carrera durante la inserción de sidecar entre Vault y Cloud Service Mesh

Cuando se usa vault para la administración de secretos, a veces vault inserta un archivo adicional. antes de istio, lo que provoca que los Pods se detengan en el estado Init. Cuando esto sucede, los Pods creados quedan atascados en el estado Init después de reiniciar cualquier implementación o para 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 el archivo adicional y, además, Istio debe ser lo último que hace esto, ya que el proxy istio no se está ejecutando durante los contenedores init. 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 redireccionar a los usuarios a nada, lo que bloquea todo el tráfico. Por eso, el contenedor init debe para que el proxy funcione inmediatamente después de que se implementen configurar. Desafortunadamente, el orden no es determinista, por lo que, si se inserta Istio primero se rompe.

Para solucionar este problema, permite la dirección IP de vault para que el tráfico ir a la IP de Vault no se redirecciona al proxy de Envoy, que no está listo pero, 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 en Deployment o Pod de nivel inferior en spec.template.metadata.annotations, por ejemplo:

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

Para la malla de servicios de Cloud en el clúster, hay una opción para configurarla como una red global uno con un IstioOperator en spec.values.global.proxy.excludeIPRanges, para 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.