¡Hola, Habr! Les presento la traducción de la publicación: .
Envoy es un proxy distribuido de alto rendimiento (escrito en C++) diseñado para servicios y aplicaciones individuales; también es un bus de comunicación y un "data plane universal" desarrollado para grandes arquitecturas de microservicios "service mesh". En su creación se tuvieron en cuenta las soluciones a los problemas que surgieron al desarrollar servidores como NGINX, HAProxy, balanceadores de carga hardware y balanceadores de carga en la nube. Envoy trabaja junto a cada aplicación y abstrae la red, proporcionando funciones comunes sin importar la plataforma. Cuando todo el tráfico de servicio en la infraestructura pasa a través de la malla Envoy, se vuelve fácil visualizar las áreas problemáticas mediante una observabilidad coherente, configurar el rendimiento general y agregar funciones clave en un lugar específico.
Funcionalidades
- Arquitectura fuera del proceso: envoy es un servidor autónomo de alto rendimiento que ocupa poca memoria. Funciona junto con cualquier lenguaje de aplicación o marco de trabajo.
- Soporte para http/2 y grpc: envoy tiene soporte de primera clase para http/2 y grpc para conexiones entrantes y salientes. Es un proxy transparente de http/1.1 a http/2.
- Balanceo de carga avanzado: envoy admite características avanzadas de balanceo de carga, incluidas reintentos automáticos, ruptura de cadena, limitación de velocidad global, sombreado de solicitudes, balanceo de carga local por zona, etc.
- API para gestionar la configuración: envoy proporciona una API robusta para gestionar dinámicamente su configuración.
- Observabilidad: observabilidad profunda del tráfico L7, soporte incorporado para trazado distribuido y observabilidad en mongodb, dynamodb y muchas otras aplicaciones.
Paso 1 - Ejemplo de configuración de NGINX
En este escenario se utiliza un archivo creado especialmente nginx.conf, basado en un ejemplo completo de . Puedes revisar la configuración en el editor abriendo nginx.conf
La configuración original de nginx
usuario www www;
pid /var/run/nginx.pid;
worker_processes 2;
events {
worker_connections 2000;
}
http {
gzip on;
gzip_min_length 1100;
gzip_buffers 4 8k;
gzip_types text/plain;
log_format main '$remote_addr - $remote_user [$time_local] '
'"$request" $status $bytes_sent '
'"$http_referer" "$http_user_agent" '
'"$gzip_ratio"';
log_format download '$remote_addr - $remote_user [$time_local] '
'"$request" $status $bytes_sent '
'"$http_referer" "$http_user_agent" '
'"$http_range" "$sent_http_content_range"';
upstream targetCluster {
172.18.0.3:80;
172.18.0.4:80;
}
server {
listen 8080;
server_name one.example.com www.one.example.com;
access_log /var/log/nginx.access_log main;
error_log /var/log/nginx.error_log info;
location / {
proxy_pass http://targetCluster/;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
}Las configuraciones de NGINX generalmente tienen tres elementos clave:
- La configuración del servidor NGINX, la estructura de registro y la funcionalidad de Gzip. Esto se define globalmente en todos los casos.
- Configuración de NGINX para aceptar solicitudes en el host one.example.com en el puerto 8080.
- Configuración de la ubicación objetivo, cómo manejar el tráfico para diferentes partes de la URL.
No toda la configuración se aplicará a Envoy Proxy, y no necesitas configurar algunos parámetros. Envoy Proxy tiene cuatro tipos clave, que respaldan la infraestructura básica ofrecida por NGINX. El núcleo es:
- Escuchadores: Definen cómo Envoy Proxy acepta solicitudes entrantes. Actualmente, Envoy Proxy solo admite escuchadores basados en TCP. Una vez que se establece la conexión, se pasa a un conjunto de filtros para su procesamiento.
- Filtros: Son parte de una arquitectura de canalización, que puede manejar datos entrantes y salientes. Esta funcionalidad incluye filtros como Gzip, que comprime datos antes de enviarlos al cliente.
- Enrutadores: Redirigen el tráfico al destino requerido, definido como un clúster.
- Clústeres: Definen el punto final para el tráfico y los parámetros de configuración.
Usaremos estos cuatro componentes para crear una configuración de Envoy Proxy que se ajuste a una configuración específica de NGINX. El objetivo de Envoy es trabajar con API y configuración dinámica. En este caso, la configuración básica utilizará parámetros estáticos predeterminados de NGINX.
Paso 2 — Configuración de NGINX
Primera parte nginx.conf define algunos componentes internos de NGINX que deben configurarse.
Worker Connections (Conexiones de trabajo)
La configuración a continuación define la cantidad de procesos de trabajo y conexiones. Esto indica cómo NGINX se escalará para satisfacer la demanda.
worker_processes 2;
events {
worker_connections 2000;
}Envoy Proxy gestiona de manera diferente los procesos de trabajo y las conexiones.
Envoy crea un hilo de trabajo para cada hilo de hardware en el sistema. Cada hilo de trabajo ejecuta un ciclo de eventos no bloqueante, el cual es responsable de
- Escuchar cada listener
- Aceptar nuevas conexiones
- Crear un conjunto de filtros para la conexión
- Manejar todas las operaciones de entrada y salida durante la existencia de la conexión.
Todo el procesamiento posterior de la conexión se maneja completamente en el hilo de trabajo, incluyendo cualquier comportamiento de redirección.
Para cada hilo de trabajo en Envoy, hay una conexión en la piscina. Así, las conexiones HTTP/2 solo establecen una conexión para cada host externo a la vez; con cuatro hilos de trabajo habrá cuatro conexiones HTTP/2 por cada host externo en estado estable. Manteniendo todo en un solo hilo de trabajo, casi todo el código puede ser escrito sin bloqueos, como si fuera de un solo hilo. Si se asignan más hilos de trabajo de los necesarios, esto puede resultar en un uso ineficiente de la memoria, creando un gran número de conexiones inactivas y reduciendo el número de retornos de conexión a la piscina.
Para más información, visite .
Configuración HTTP
El siguiente bloque de configuración de NGINX define los ajustes HTTP, tales como:
- Qué tipos de mime son admitidos
- Timeouts por defecto
- Configuración de Gzip
Puedes ajustar estos aspectos usando filtros en Envoy Proxy, de lo que hablaremos más adelante.
Paso 3 — Configuración del servidor
En el bloque de configuración HTTP, la configuración de NGINX indica escuchar en el puerto 8080 y responder a las solicitudes entrantes para los dominios one.example.com y www.one.example.com.
server {
listen 8080;
server_name one.example.com www.one.example.com;Dentro de Envoy, esto es gestionado por los listeners.
Listeners de Envoy
El aspecto más importante para empezar a trabajar con Envoy Proxy es la definición de los listeners. Necesitas crear un archivo de configuración que describa cómo quieres ejecutar una instancia de Envoy.
El fragmento a continuación creará un nuevo listener y lo vinculará al puerto 8080. La configuración indica a Envoy Proxy a qué puertos debe estar vinculado para las solicitudes entrantes.
Envoy Proxy utiliza la notación YAML para su configuración. Para familiarizarse con esta notación, consulte aquí. .
Copy to Editorstatic_resources:
listeners:
- name: listener_0
address:
socket_address: { address: 0.0.0.0, port_value: 8080 }No es necesario definir server_name, ya que los filtros de Envoy Proxy se encargarán de eso.
Paso 4 — Configuración del location
Cuando llega una solicitud a NGINX, el bloque location define cómo manejar y hacia dónde dirigir el tráfico. En el siguiente fragmento, todo el tráfico hacia el sitio se envía al clúster upstream (nota del traductor: el upstream suele ser servidores de aplicaciones) llamado targetCluster. El clúster upstream determina qué nodos deben manejar la solicitud. Lo discutiremos en el siguiente paso.
location / {
proxy_pass http://targetCluster/;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}En Envoy, esto es gestionado por Filters.
Envoy Filters
Para una configuración estática, los filtros definen cómo manejar las solicitudes entrantes. En este caso, establecemos filtros que coinciden con server_names del paso anterior. Cuando llegan solicitudes entrantes que coinciden con ciertos dominios y rutas, el tráfico se dirige al clúster. Esto es equivalente a la configuración upstream en NGINX.
Copy to Editor filter_chains:
- filters:
- name: envoy.http_connection_manager
config:
codec_type: auto
stat_prefix: ingress_http
route_config:
name: local_route
virtual_hosts:
- name: backend
domains:
- "one.example.com"
- "www.one.example.com"
routes:
- match:
prefix: "/"
route:
cluster: targetCluster
http_filters:
- name: envoy.routerNombre envoy.http_connection_manager es un filtro integrado en Envoy Proxy. Otros filtros incluyen Redis, Mongo, TCP. Puede encontrar la lista completa en .
Para obtener más información sobre otras políticas de balanceo de carga, visite .
Paso 5 — Configuración de Proxy y Upstream
En NGINX, la configuración upstream define un conjunto de servidores objetivo que manejarán el tráfico. En este caso, se han asignado dos clústeres.
upstream targetCluster {
172.18.0.3:80;
172.18.0.4:80;
}En Envoy, esto es gestionado por clústeres.
Envoy Clusters
El equivalente upstream se define como clústeres. En este caso, se han definido hosts que atenderán el tráfico. El método de acceso a los hosts, como el tiempo de espera, se define como configuración del clúster. Esto permite un control más preciso de aspectos como el tiempo de espera y el balanceo de carga.
Copiar al editor clústeres:
- name: targetCluster
connect_timeout: 0.25s
type: STRICT_DNS
dns_lookup_family: V4_ONLY
lb_policy: ROUND_ROBIN
hosts: [
{ socket_address: { address: 172.18.0.3, port_value: 80 }},
{ socket_address: { address: 172.18.0.4, port_value: 80 }}
]Al usar la detección de servicios STRICT_DNS Envoy resolverá de manera continua y asíncrona los objetivos DNS especificados. Cada dirección IP devuelta como resultado de DNS se considerará un host explícito en el clúster ascendente. Esto significa que si la consulta devuelve dos direcciones IP, Envoy asumirá que hay dos hosts en el clúster y ambos deben ser balanceados. Si un host se elimina del resultado, Envoy supone que ya no existe y comenzará a desviar el tráfico de cualquier grupo de conexiones existente.
Para más información, consulte .
Paso 6: Acceso a los registros y errores
La configuración final es la registro. En lugar de enviar los registros de errores al disco, Envoy Proxy usa un enfoque en la nube. Todos los registros de aplicaciones se envían a stdout y stderr.
Cuando los usuarios realizan una solicitud, los registros de acceso son opcionales y están desactivados por defecto. Para habilitar los registros de acceso para solicitudes HTTP, active la configuración access_log para el administrador de conexiones HTTP. La ruta puede ser un dispositivo, como stdout, o un archivo en disco, según sus requisitos.
La siguiente configuración redirigirá todos los registros de acceso a stdout (Nota del traductor: stdout es necesario para usar envoy dentro de Docker. Si se usa sin Docker, sustituya /dev/stdout por la ruta a un archivo de registro normal). Copie el fragmento en la sección de configuración para el gestor de conexiones:
Copiar al portapapeles access_log:
- name: envoy.file_access_log
config:
path: "\/dev\/stdout"Los resultados deben lucir así:
- name: envoy.http_connection_manager
config:
codec_type: auto
stat_prefix: ingress_http
access_log:
- name: envoy.file_access_log
config:
path: "\/dev\/stdout"
route_config:Por defecto, Envoy tiene una cadena de formato que incluye los detalles de la solicitud HTTP:
[%START_TIME%] "%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%"nEl resultado de esta línea de formato:
[2018-11-23T04:51:00.281Z] "GET / HTTP/1.1" 200 - 0 58 4 1 "-" "curl/7.47.0" "f21ebd42-6770-4aa5-88d4-e56118165a7d" "one.example.com" "172.18.0.4:80"El contenido de la salida se puede personalizar configurando el campo de formato. Por ejemplo:
access_log:
- name: envoy.file_access_log
config:
path: "/dev/stdout"
format: "[%START_TIME%] "%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%" %RESPONSE_CODE% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%"n"La línea de registro también se puede generar en formato JSON configurando el campo json_formatPor ejemplo:
access_log:
- name: envoy.file_access_log
config:
path: "/dev/stdout"
json_format: {"protocol": "%PROTOCOL%", "duration": "%DURATION%", "request_method": "%REQ(:METHOD)%"}Para obtener más información sobre la técnica de registro del proxy, visite
El registro no es la única forma de obtener una visión del funcionamiento de Envoy Proxy. Incorpora capacidades avanzadas de trazado y métricas. Puede aprender más en o a través de .
Paso 7 — Ejecución
Ahora ha trasladado la configuración de NGINX a Envoy Proxy. El último paso es ejecutar una instancia de Envoy Proxy para probarlo.
Ejecución como usuario
En la parte superior de la configuración de NGINX, la línea user www www; indica ejecutar NGINX como un usuario con bajo privilegio para mejorar la seguridad.
Envoy Proxy utiliza un enfoque basado en la nube para gestionar quién posee el proceso. Cuando ejecutamos Envoy Proxy a través de un contenedor, podemos especificar un usuario con bajo privilegio.
Ejecución de Envoy Proxy
El siguiente comando ejecutará Envoy Proxy a través de un contenedor Docker en el host. Este comando permite que Envoy escuche las solicitudes entrantes a través del puerto 80. Sin embargo, como se indica en la configuración del oyente, Envoy Proxy escucha el tráfico entrante a través del puerto 8080. Esto permite que el proceso se ejecute como un usuario con bajo privilegio.
docker run --name proxy1 -p 80:8080 --user 1000:1000 -v /root/envoy.yaml:/etc/envoy/envoy.yaml envoyproxy/envoyPruebas
Con el proxy en funcionamiento, ahora se pueden realizar y procesar pruebas. El siguiente comando cURL emite una solicitud con el encabezado de host definido en la configuración del proxy.
curl -H "Host: one.example.com" localhost -iLa solicitud HTTP resultará en un error 503Esto se debe a que las conexiones ascendentes no funcionan y no están disponibles. Por lo tanto, Envoy Proxy no tiene destinatarios disponibles para la solicitud. El siguiente comando iniciará una serie de servicios HTTP que corresponden a la configuración definida para Envoy.
docker run -d katacoda/docker-http-server; docker run -d katacoda/docker-http-server;Con los servicios disponibles, Envoy puede enrutear el tráfico con éxito al destino.
curl -H "Host: one.example.com" localhost -iDeberías ver una respuesta que indique qué contenedor Docker manejó la solicitud. En los registros de Envoy Proxy también deberías ver la línea de acceso mostrada.
Encabezados de respuesta HTTP adicionales (HTTP Response)
En los encabezados de la respuesta de la solicitud válida verás encabezados HTTP adicionales. En el encabezado se muestra el tiempo que el host ascendente tardó en procesar la solicitud. Se expresa en milisegundos. Esto es útil si el cliente desea determinar el tiempo de servicio en comparación con la latencia de la red.
x-envoy-upstream-service-time: 0
server: envoyConfiguración final
static_resources:
listeners:
- name: listener_0
address:
socket_address: { address: 0.0.0.0, port_value: 8080 }
filter_chains:
- filters:
- name: envoy.http_connection_manager
config:
codec_type: auto
stat_prefix: ingress_http
route_config:
name: local_route
virtual_hosts:
- name: backend
domains:
- "one.example.com"
- "www.one.example.com"
routes:
- match:
prefix: "\/"
route:
cluster: targetCluster
http_filters:
- name: envoy.router
clusters:
- name: targetCluster
connect_timeout: 0.25s
type: STRICT_DNS
dns_lookup_family: V4_ONLY
lb_policy: ROUND_ROBIN
hosts: [
{ socket_address: { address: 172.18.0.3, port_value: 80 }},
{ socket_address: { address: 172.18.0.4, port_value: 80 }}
]
admin:
access_log_path: \/tmp\/admin_access.log
address:
socket_address: { address: 0.0.0.0, port_value: 9090 }Información adicional del traductor
Puedes encontrar las instrucciones para instalar Envoy Proxy en el sitio web
Por defecto, el rpm no incluye la configuración del servicio systemd.
Agrega la configuración del servicio systemd \/etc\/systemd\/system\/envoy.service:
[Unit]
Description=Envoy Proxy
Documentation=https://www.envoyproxy.io/
After=network-online.target
Requires=envoy-auth-server.service
Wants=nginx.service
[Service]
User=root
Restart=on-failure
ExecStart=\/usr\/bin\/envoy --config-path \/etc\/envoy\/config.yaml
[Install]
WantedBy=multi-user.targetNecesitas crear el directorio \/etc\/envoy\/ y poner allí el archivo de configuración config.yaml.
Hay un chat de Telegram sobre Envoy Proxy:
Envoy Proxy no soporta la entrega de contenido estático. Por lo tanto, quien pueda, vote por esta función:
Solo los usuarios registrados pueden participar en la encuesta. , por favor.
¿Te ha motivado esta publicación a instalar y probar Envoy Proxy?
sí
no
75 usuarios votaron. 18 usuarios se abstuvieron.
Fuente: habr.com
