Resuelve los 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 solucionarlos. Si necesitas asistencia adicional, consulta Obtén asistencia.
No se puede iniciar la puerta de enlace con el proxy sin distribución cuando se expone un puerto con privilegios
De forma predeterminada, el proxy sin distribución se inicia con permisos que no son de administrador, lo que, en algunos casos, puede causar fallas de vinculación en puertos con privilegios. Si ves errores similares a los siguientes durante el inicio del proxy, se debe aplicar securityContext adicional para una implementación de puerta de enlace.
Error adding/updating listener(s) 0.0.0.0_80: cannot bind '0.0.0.0:80': Permission denied
En el siguiente ejemplo, se muestra el archivo YAML para una implementación de puerta de enlace de salida:
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
Se rechazó la conexión cuando se llegó a un extremo de Cloud Service Mesh
Es posible que, de forma intermitente, experimentes errores de conexión rechazada (ECONNREFUSED) con la comunicación de tus clústeres a tus extremos, por ejemplo, Memorystore Redis, Cloud SQL o cualquier servicio externo al que deba llegar la carga de trabajo de tu aplicación.
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. Como istio-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 obtiene el error ECONNREFUSED.
En los siguientes pasos, se detalla cómo verificar si este es el error que estás experimentando:
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 ECONNREFUSEDBusca una instancia del problema. Si usas Stackdriver heredado, usa
resource.type="container".resource.type="k8s_container" textPayload:"$ERROR_MESSAGE$"Expande la instancia más reciente para obtener el nombre del pod y, luego, toma nota del
pod_nameenresource.labels.Obtén la primera instancia del problema para 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-g7fvbToma nota de la marca de tiempo del primer error para este pod.
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}Usa las marcas de tiempo de los errores y los eventos de inicio de istio-proxy para confirmar que los errores ocurren cuando
Envoyno está listo.Si los errores ocurren mientras 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 tan pronto como
2020-03-31T10:41:15.552128897Z, pero, para2020-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 haya preparado lo suficientemente rápido antes de que la app ya intentara conectarse al extremo externo.
Si este es el problema que estás experimentando, continúa con los siguientes pasos de solución de problemas.
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 }'Modifica el código de la aplicación para que verifique si
Envoyestá listo antes de intentar realizar cualquier otra solicitud a servicios externos. Por ejemplo, cuando se inicia la aplicación, inicia un bucle que realiza solicitudes al extremo de estado de istio-proxy y solo 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 Cloud Service Mesh
Cuando se usa vault para la administración de secretos, a veces vault inyecta sidecar antes de istio, lo que hace que los pods se queden atascados en el estado Init. Cuando esto sucede, los pods creados se quedan atascados en el estado Init después de reiniciar cualquier implementación o 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 sidecar, y Istio debe ser el último en hacerlo. El proxy istio no se ejecuta durante los contenedores init. El contenedor init istio configura reglas de iptables para redireccionar todo el tráfico al proxy. Como aún no se está ejecutando, esas reglas no redireccionan a nada, lo que bloquea todo el tráfico. Por eso, 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 Istio se inyecta primero, se interrumpe.
Para solucionar esta condición, permite la dirección IP de vault para que el tráfico que va 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 lograr esto, se debe agregar una nueva anotación llamada excludeOutboundIPRanges.
Para Cloud 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:
Para Cloud Service Mesh en el clúster, existe una opción para configurarlo como 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.
Identifica el tipo de imagen de proxy que se usa en el clúster
Para identificar qué tipo de imagen de proxy (default o distroless) usa un pod específico, puedes inspeccionar la especificación del pod.
Ejecuta el siguiente comando para verificar la imagen que usa el contenedor istio-proxy:
kubectl get pod POD_NAME -n NAMESPACE -o jsonpath='{.spec.containers[?(@.name=="istio-proxy")].image}'
- Si la ruta de acceso de la imagen no contiene
-distrolessen la etiqueta o el sufijo, usa la imagendefault. - Si la ruta de acceso de la imagen contiene
-distrolessen la etiqueta o el sufijo, usa la imagendistroless.
Verifica la intención de configuración
El tipo de imagen se puede configurar de dos maneras (la anotación tiene prioridad sobre MeshConfig):
Anotación de pod: Verifica si el pod tiene la anotación
sidecar.istio.io/proxyImageType.kubectl get pod POD_NAME -n NAMESPACE -o jsonpath='{.metadata.annotations["sidecar.istio.io/proxyImageType"]}'MeshConfig: Verifica la configuración
defaultConfig.image.imageTypeen tu ConfigMapistio-RELEASE_CHANNELen el espacio de nombresistio-system.
Nota: Para clústeres con el plano de control administrado TRAFFIC_DIRECTOR:
- Para los clústeres aprovisionados directamente con un plano de control
TRAFFIC_DIRECTORadministrado, solo se admiten imágenesdistroless. Se ignoran las anulaciones de otros tipos de imágenes. - Para los clústeres migrados al plano de control
TRAFFIC_DIRECTOR(como los migrados de CSM-ISTIOD), el tipo de imagen predeterminado es la imagendefault, pero puedes habilitardistrolessconMeshConfigo la anotación de pod. No se admiten anulaciones de otros tipos de imágenes (comodebug).