Configura filtros Envoy en bruto en Istio con EnvoyFilter
Para las funciones que las propias APIs de Istio no exponen, EnvoyFilter modifica directamente la configuración subyacente de Envoy, con cuidado.
Los recursos de alto nivel de Istio, VirtualService, DestinationRule, AuthorizationPolicy, cubren la mayor parte de la gestión de tráfico del día a día sin que nadie necesite conocer directamente el formato de configuración de Envoy. Pero Envoy tiene muchos más filtros y opciones de los que expone cualquiera de esos recursos, y para ese hueco Istio ofrece EnvoyFilter: un recurso que modifica directamente la configuración de Envoy que genera Istio. Es una auténtica vía de escape, igual de potente que fácil de configurar mal, y esta guía cubre cómo está estructurado, con un ejemplo completo.
Para qué sirve EnvoyFilter
Si lo que necesitas tiene un recurso de Istio dedicado, una regla de enrutamiento, una política de reintentos, ajustes de TLS mutuo, usa ese recurso. EnvoyFilter existe para todo lo demás: filtros como scripting en Lua, request tapping, IP tagging o cualquier otra capacidad de Envoy para la que las APIs de más alto nivel de Istio simplemente no tienen un campo. Recurre a él solo cuando hayas confirmado que lo que necesitas realmente no se puede expresar con los recursos normales, ya que cada EnvoyFilter que añades es una cosa más que mantener sincronizada con la evolución de la propia configuración generada por Istio entre actualizaciones.
Las cuatro preguntas que responde todo EnvoyFilter
Todo recurso EnvoyFilter, sea lo que sea lo que configure, responde a las mismas cuatro preguntas:
- ¿A qué proxies se aplica? Un
workloadSelectorapunta a cargas de trabajo concretas por etiqueta; omitirlo aplica el parche a todo el namespace, o a toda la malla si se coloca en el namespace raíz/de configuración de Istio. - ¿En qué parte de la configuración de Envoy se aplica el parche? El campo
applyTonombra el destino:LISTENER,FILTER_CHAIN,HTTP_FILTER,NETWORK_FILTER,CLUSTER,ROUTE_CONFIGURATIONy unos cuantos más. - Más concretamente, ¿qué instancia de eso? Un bloque
matchlo acota todavía más, por ejemplo un puerto de listener concreto, una cadena de filtros concreta, o si se aplica al tráfico entrante del sidecar, al saliente o a un gateway. - ¿Qué operación debe realizarse y con qué contenido? El bloque
patchespecifica tanto una operación,ADD,REMOVE,MERGE,INSERT_BEFORE,INSERT_AFTERoINSERT_FIRST, como, para cualquier cosa que inserte o fusione configuración, la configuración real del filtro como suvalue.
Los cambios sensibles al orden (insertar un filtro HTTP en un punto concreto de la cadena) usan las operaciones INSERT_* y apuntan a un vecino con nombre, normalmente el filtro terminal envoy.filters.http.router, para decir “antes de este” o “después de este”.
Un ejemplo completo: etiquetar peticiones por IP
Esto añade el filtro HTTP ip_tagging al tráfico entrante del sidecar en el puerto 80, insertado justo antes del filtro router terminal:
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: ip-tagging
namespace: default
spec:
configPatches:
- applyTo: HTTP_FILTER
match:
context: SIDECAR_INBOUND
listener:
portNumber: 80
filterChain:
filter:
name: envoy.filters.network.http_connection_manager
subFilter:
name: envoy.filters.http.router
patch:
operation: INSERT_BEFORE
value:
name: envoy.filters.http.ip_tagging
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.ip_tagging.v3.IPTagging
request_type: BOTH
ip_tags:
- ip_tag_name: hello-envoy-conf
ip_list:
- address_prefix: "0.0.0.0"
prefix_len: 0
Léelo de arriba abajo: sin workloadSelector, esto se aplica a todas las cargas de trabajo del namespace default. applyTo: HTTP_FILTER dice que estamos añadiendo un filtro HTTP. El bloque match lo acota al tráfico entrante del sidecar, en el listener enlazado al puerto 80, específicamente dentro de la cadena de filtros del HTTP Connection Manager, posicionado respecto al filtro router. El patch dice que se inserte un nuevo filtro antes de ese router, y da su configuración completa: el nombre del filtro, su type URL (@type) y los campos específicos del filtro, aquí, etiquetar cada petición con X-Envoy-IP-Tags: hello-envoy-conf sin importar la IP de origen (0.0.0.0/0 coincide con todo).
Aplícalo y confírmalo:
kubectl apply -f ip-tagging-filter.yaml
kubectl exec deploy/httpbin -c istio-proxy -- curl -s -D - http://localhost:80/get -o /dev/null | grep -i x-envoy-ip-tags
Encontrar el nombre, el type URL y los campos de un filtro
El name, el @type de typed_config y los campos que van debajo son específicos de cada filtro, y la propia documentación de filtros de Envoy es de donde salen, aunque está repartida en varias páginas enlazadas en lugar de estar en un solo lugar: la página de resumen de un filtro normalmente enlaza a su referencia de protobuf, que a su vez define cada campo, a menudo con más enlaces para los tipos anidados. Cuenta con bastante cambio de pestañas. Algunas cosas lo agilizan:
- Busca el type URL en GitHub una vez que lo tengas. Para cualquier filtro razonablemente común, alguien probablemente ya haya publicado un
EnvoyFiltero una configuración de Envoy en bruto que lo usa y funciona, lo que suele ser un punto de partida más rápido que armar uno solo a partir de la referencia de campos. - No todos los filtros de Envoy están compilados en el build de proxy de Istio. Istio distribuye un build concreto de Envoy, y un filtro documentado en envoyproxy.io no está garantizado que esté incluido en él. Confirma que un filtro está realmente disponible en el build de Istio antes de diseñar una solución en torno a él.
- Usa JSON en lugar de YAML para el bloque
valuesi te resulta propenso a errores la indentación de YAML para configuraciones muy anidadas; la configuración de Envoy acepta ambos, y una indentación mal colocada en un bloque YAML anidado es una de las formas más habituales de que unEnvoyFilterfalle en silencio y no haga lo que pretendías.
Inspeccionar lo que realmente se está ejecutando
Dos herramientas ayudan a confirmar que un parche aterrizó como esperas, en lugar de adivinarlo solo por el comportamiento:
istioctl proxy-config listener POD_NAME -n NAMESPACE
istioctl proxy-config route POD_NAME -n NAMESPACE
istioctl proxy-config cluster POD_NAME -n NAMESPACE
istioctl proxy-config all POD_NAME -n NAMESPACE -o json
istioctl proxy-config, seguido de bootstrap, clusters, routes, listeners o all, imprime la configuración real de un sidecar dado tal como la han ensamblado Istio y Envoy, como tabla por defecto o como YAML/JSON con -o. Esta es la verdad de base sobre lo que realmente se está ejecutando, a diferencia de lo que pretendías parchear. Para comparar visualmente un volcado completo de configuración, una configuración completa de Envoy es más de lo que la mayoría quiere leer directamente en una terminal; un visor de volcados de configuración que la muestre como una estructura navegable y con enlaces cruzados (la comunidad de Envoy mantiene algunos) suele ser más fácil de recorrer que desplazarse por JSON en bruto.
La advertencia principal
EnvoyFilter parchea configuración que el propio Istio genera y regenera con cada cambio, lo que significa que está intrínsecamente acoplado a los internos de Istio de una manera que los recursos de más alto nivel no lo están. Un EnvoyFilter escrito para una versión de Istio puede dejar de coincidir con nada en silencio, o coincidir con algo no previsto, después de una actualización que cambie cómo Istio estructura sus listeners o cadenas de filtros generados. Trátalo como sugiere su nombre: una herramienta precisa para un hueco específico y verificado, probada tras cada actualización de Istio, no una forma predeterminada de configurar el tráfico.
Guías populares
-
Arquitectura de Envoy: listeners, clusters y cadenas de filtros Cómo se mueve realmente una petición por Envoy, desde el socket por el que llega hasta el upstream al que se envía. -
Dónde encaja Envoy: patrones de edge, front proxy y service mesh El mismo proxy, desplegado de tres formas distintas, y por qué ser 'lo bastante ligero para ejecutarse por instancia' hace posibles las tres. -
El HTTP Connection Manager y las cadenas de filtros HTTP Cómo convierte Envoy los bytes en bruto en peticiones HTTP sobre las que puede actuar, y las formas de conectar tu propia lógica a ese pipeline.