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.
El diseño de Envoy se deriva directamente de su objetivo fundacional: hacer que la red sea transparente para las aplicaciones y que sea rápido distinguir un problema de red de un problema de aplicación. Ese objetivo da forma al vocabulario, listeners, clusters, filtros, con el que se construye toda la configuración de Envoy. Esta guía cubre qué hace cada uno y cómo se mueve una petición a través de ellos.
Downstream y upstream
Envoy llama downstream a lo que le envía una petición y upstream a aquello a lo que reenvía esa petición. Downstream puede ser el navegador de un usuario final, otro servicio de la malla, cualquier cosa que abra una conexión hacia Envoy. Upstream es el lugar al que Envoy decide enrutar la petición: una instancia de aplicación, otro servicio, una API externa. Cada pieza de configuración de Envoy está a un lado u otro de esa línea.
Listeners: por dónde entran las conexiones
Un listener se enlaza a un puerto y acepta conexiones en él. Una sola instancia de Envoy puede definir varios listeners, cada uno con su propio puerto y su propio pipeline de procesamiento, de modo que una instancia puede, por ejemplo, terminar TLS en el 443 mientras gestiona tráfico sin cifrar en el 8080 con reglas completamente distintas. Todo lo que un listener necesite hacer con una conexión antes de poder enrutarla, terminación TLS, detección de protocolo y más, ocurre mediante los filtros adjuntos a él, que la siguiente guía de esta serie cubre en profundidad.
Clusters: a dónde van las conexiones
Un cluster es un grupo lógico con nombre de uno o más endpoints upstream a los que Envoy puede enrutar tráfico. Si vienes de Kubernetes, la comparación que suele aclararlo: un cluster es aproximadamente análogo a un Service, y los endpoints individuales dentro de él son aproximadamente análogos a los Pods que hay detrás. Envoy rastrea la salud de cada endpoint, aplica la política de balanceo de carga con la que esté configurado el cluster y elige un destino entre los sanos para cada petición.
Filtros y cadenas de filtros
Una vez que un listener acepta una conexión, los datos fluyen a través de una secuencia de filtros, unidades pequeñas y enfocadas que hacen cada una un trabajo, encadenadas en una cadena de filtros. Los filtros más básicos operan a nivel de red (TCP o UDP), sobre el flujo de bytes en bruto, antes de que nada se haya interpretado como un protocolo de más alto nivel. Envoy incluye de serie filtros de red para cosas como el manejo de los protocolos de MongoDB, Redis y Kafka.
Para el tráfico HTTP en concreto, un filtro de red en particular hace la mayor parte del trabajo pesado: el HTTP Connection Manager, que convierte los bytes en bruto en peticiones, encabezados y cuerpos HTTP, y expone su propia cadena anidada de filtros a nivel HTTP, registro de acceso, reintentos, manipulación de encabezados y más, que operan una vez que el tráfico es HTTP y no solo bytes. La siguiente guía de esta serie está dedicada por completo a él.
Rutas: elegir un cluster
Una vez que el tráfico llega a la capa HTTP, las rutas deciden a qué cluster va una petición dada, comparando con características de la propia petición: host, ruta, encabezados. Una petición a example.com/api puede coincidir con una ruta que la envía a un cluster example-com, mientras que un host o ruta distintos coinciden con una ruta completamente distinta. La coincidencia de rutas es lo que convierte “llegó una petición HTTP” en “este es el cluster concreto al que pertenece”.
Juntándolo todo: el recorrido de una petición
cliente downstream
│
▼
listener (enlazado a un puerto)
│
▼
cadena de filtros (filtros de red, luego HTTP Connection Manager)
│
▼
coincidencia de rutas (host, ruta, encabezados)
│
▼
cluster (un grupo con nombre de endpoints)
│
▼
balanceo de carga + health checking
│
▼
endpoint upstream
Una petición llega a un listener, fluye por la cadena de filtros de ese listener, las reglas de enrutamiento la asocian a un cluster y el cluster manager de Envoy elige un endpoint sano dentro de ese cluster al que enviarla realmente. Todo lo que hace Envoy, TLS, rate limiting, reintentos, observabilidad, se asocia a una de estas etapas en lugar de existir como una preocupación separada, que es exactamente el diseño de “la red es transparente, los problemas son fáciles de localizar” que el proyecto se propuso lograr: como cada etapa es explícita e inspeccionable, una respuesta lenta o una petición fallida normalmente se puede rastrear hasta un listener, filtro o cluster concreto en lugar de requerir una conjetura.
Para un relato bastante más detallado de exactamente qué ocurre en cada etapa, incluidas las partes de la arquitectura (hilos worker, connection pooling) que esta guía simplifica deliberadamente, la propia documentación “life of a request” de Envoy recorre paso a paso todo el flujo interno.
Guías populares
-
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.