Instalación y Configuración del Proxy Envoy

Envoy es un proxy Layer 7 y bus de comunicación diseñado para arquitecturas grandes y modernas orientadas a servicios. Originalmente desarrollado en Lyft y ahora un proyecto CNCF, Envoy proporciona características avanzadas de gestión de tráfico, políticas de seguridad y observabilidad. Esta guía cubre instalación, conceptos principales de oyentes y clústeres, configuración de enrutamiento, verificación de salud y aspectos operacionales.

Tabla de Contenidos

  1. Introducción a Envoy
  2. Requisitos del Sistema
  3. Métodos de Instalación
  4. Instalación Binaria
  5. Instalación Docker
  6. Estructura de Configuración
  7. Oyentes y Puntos de Entrada
  8. Clústeres y Servicios Upstream
  9. Rutas y Hosts Virtuales
  10. Filtros y Extensiones
  11. Verificación de Salud
  12. Interfaz de Administración
  13. Solución de Problemas

Introducción a Envoy

Envoy es un proceso autónomo diseñado para ejecutarse junto a cada servicio. A diferencia de proxies inversos tradicionales que manejan tráfico en límites de infraestructura, Envoy opera a nivel de servicio, proporcionando visibilidad y control sobre la comunicación servicio a servicio. Características clave incluyen:

  • Algoritmos de balanceo de carga avanzados
  • Reintentos automáticos y ruptura de circuito
  • Verificaciones de salud y detección de valores atípicos
  • Observabilidad exhaustiva y métricas
  • Configuración dinámica vía API
  • Soporte de protocolo: HTTP/1.1, HTTP/2, HTTP/3, gRPC, TCP

Requisitos del Sistema

Asegúrate de que tu sistema cumpla con estos requisitos:

  • Kernel de Linux 3.10 o más nuevo
  • 256 MB de RAM mínimo (512 MB recomendado)
  • 50 MB de espacio en disco para binario
  • Conectividad de red a servicios upstream
  • Acceso root o sudo para puertos privilegiados

Envoy admite x86_64, ARM64 y otras arquitecturas.

Métodos de Instalación

Envoy se puede instalar vía administradores de paquetes, Docker o compilado desde fuente.

Instalación Binaria

Descarga la última versión de Envoy:

cd /tmp
wget https://github.com/envoyproxy/envoy/releases/download/v1.27.0/envoy-1.27.0-linux-x86_64
chmod +x envoy-1.27.0-linux-x86_64
sudo mv envoy-1.27.0-linux-x86_64 /usr/local/bin/envoy

Verifica instalación:

envoy --version

Crea usuario dedicado y directorios:

sudo useradd -r -s /bin/false -d /var/lib/envoy envoy
sudo mkdir -p /etc/envoy
sudo mkdir -p /var/lib/envoy
sudo mkdir -p /var/log/envoy
sudo chown -R envoy:envoy /var/lib/envoy /var/log/envoy /etc/envoy

Crea archivo de servicio systemd:

sudo tee /etc/systemd/system/envoy.service > /dev/null <<'EOF'
[Unit]
Description=Envoy Proxy
Documentation=https://www.envoyproxy.io/
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=envoy
Group=envoy
ExecStart=/usr/local/bin/envoy -c /etc/envoy/envoy.yaml --log-level info
Restart=on-failure
RestartSec=5s
StandardOutput=journal
StandardError=journal
SyslogIdentifier=envoy

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable envoy

Instalación Docker

Implementa Envoy usando Docker:

docker run -d \
  --name envoy \
  -p 80:10000 \
  -p 443:10001 \
  -p 8001:8001 \
  -v /etc/envoy/envoy.yaml:/etc/envoy/envoy.yaml:ro \
  -v /var/log/envoy:/var/log/envoy \
  envoyproxy/envoy:v1.27-latest \
  /usr/local/bin/envoy -c /etc/envoy/envoy.yaml

Usa Docker Compose para implementaciones multi-contenedor:

version: '3.8'

services:
  envoy:
    image: envoyproxy/envoy:v1.27-latest
    restart: always
    ports:
      - "80:10000"
      - "443:10001"
      - "8001:8001"
    volumes:
      - /etc/envoy/envoy.yaml:/etc/envoy/envoy.yaml:ro
      - /var/log/envoy:/var/log/envoy
    networks:
      - service_mesh
    command: /usr/local/bin/envoy -c /etc/envoy/envoy.yaml --log-level info

networks:
  service_mesh:
    driver: bridge

Estructura de Configuración

La configuración de Envoy está en YAML con cuatro secciones principales:

Crea /etc/envoy/envoy.yaml:

static_resources:
  listeners:
    - name: listener_0
      address:
        socket_address:
          protocol: TCP
          address: 0.0.0.0
          port_value: 10000
      filter_chains:
        - filters:
            - name: envoy.filters.network.http_connection_manager
              typed_config:
                "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
                stat_prefix: ingress_http
                route_config:
                  name: local_route
                  virtual_hosts:
                    - name: backend
                      domains: ["*"]
                      routes:
                        - match:
                            prefix: "/"
                          route:
                            cluster: backend_service
                http_filters:
                  - name: envoy.filters.http.router
                    typed_config:
                      "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router

  clusters:
    - name: backend_service
      connect_timeout: 1s
      type: STRICT_DNS
      lb_policy: ROUND_ROBIN
      load_assignment:
        cluster_name: backend_service
        endpoints:
          - lb_endpoints:
              - endpoint:
                  address:
                    socket_address:
                      address: 192.168.1.100
                      port_value: 8080

admin:
  address:
    socket_address:
      protocol: TCP
      address: 127.0.0.1
      port_value: 9001

Inicia Envoy:

sudo systemctl start envoy

Oyentes y Puntos de Entrada

Los oyentes definen dónde Envoy acepta conexiones entrantes:

static_resources:
  listeners:
    - name: http_listener
      address:
        socket_address:
          protocol: TCP
          address: 0.0.0.0
          port_value: 80
      filter_chains:
        - filters:
            - name: envoy.filters.network.http_connection_manager
              typed_config:
                "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
                stat_prefix: ingress_http
                
    - name: https_listener
      address:
        socket_address:
          protocol: TCP
          address: 0.0.0.0
          port_value: 443
      filter_chains:
        - transport_socket:
            name: envoy.transport_sockets.tls
            typed_config:
              "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
              common_tls_context:
                tls_certificates:
                  - certificate_chain:
                      filename: /etc/envoy/certs/example.crt
                    private_key:
                      filename: /etc/envoy/certs/example.key
          filters:
            - name: envoy.filters.network.http_connection_manager
              typed_config:
                "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
                stat_prefix: ingress_https

Clústeres y Servicios Upstream

Los clústeres definen grupos de servicios upstream:

clusters:
  - name: backend_service
    connect_timeout: 1s
    type: STRICT_DNS
    lb_policy: ROUND_ROBIN
    load_assignment:
      cluster_name: backend_service
      endpoints:
        - lb_endpoints:
            - endpoint:
                address:
                  socket_address:
                    address: 192.168.1.100
                    port_value: 8080
                weight: 3
            - endpoint:
                address:
                  socket_address:
                    address: 192.168.1.101
                    port_value: 8080
                weight: 1

  - name: api_service
    connect_timeout: 2s
    type: STRICT_DNS
    lb_policy: LEAST_REQUEST
    load_assignment:
      cluster_name: api_service
      endpoints:
        - lb_endpoints:
            - endpoint:
                address:
                  socket_address:
                    address: 192.168.1.110
                    port_value: 8000
            - endpoint:
                address:
                  socket_address:
                    address: 192.168.1.111
                    port_value: 8000
    circuit_breakers:
      thresholds:
        - max_connections: 1000
          max_pending_requests: 100
          max_requests: 1000
          max_retries: 3

Rutas y Hosts Virtuales

Define reglas de enrutamiento para diferentes dominios y rutas:

route_config:
  name: local_route
  virtual_hosts:
    - name: example_com
      domains: ["example.com", "www.example.com"]
      routes:
        - name: api_route
          match:
            prefix: "/api/v1"
          route:
            cluster: api_service
            timeout: 5s
            retry_policy:
              retry_on: "5xx"
              num_retries: 3
              per_try_timeout: 2s
        
        - name: static_route
          match:
            prefix: "/static"
          route:
            cluster: static_service
            timeout: 10s
        
        - name: default_route
          match:
            prefix: "/"
          route:
            cluster: backend_service
            timeout: 30s

    - name: api_example_com
      domains: ["api.example.com"]
      routes:
        - match:
            prefix: "/"
          route:
            cluster: api_service
            prefix_rewrite: "/"

Filtros y Extensiones

Los filtros proporcionan capacidades de procesamiento de tráfico:

http_filters:
  - name: envoy.filters.http.authentication
    typed_config:
      "@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthz
      transport_api_version: V3
      grpc_service:
        envoy_grpc:
          cluster_name: auth_service
        timeout: 2s
  
  - name: envoy.filters.http.rate_limit
    typed_config:
      "@type": type.googleapis.com/envoy.extensions.filters.http.local_ratelimit.v3.LocalRateLimit
      stat_prefix: http_local_rate_limiter
      token_bucket:
        max_tokens: 100
        tokens_per_fill: 10
        fill_interval: 1s
      filter_enabled:
        runtime_key: local_rate_limit_enabled
        default_value:
          numerator: 100
          denominator: HUNDRED
      filter_enforced:
        runtime_key: local_rate_limit_enforced
        default_value:
          numerator: 100
          denominator: HUNDRED
  
  - name: envoy.filters.http.router
    typed_config:
      "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router

Verificación de Salud

Configura verificación de salud activa:

clusters:
  - name: backend_service
    connect_timeout: 1s
    type: STRICT_DNS
    lb_policy: ROUND_ROBIN
    load_assignment:
      cluster_name: backend_service
      endpoints:
        - lb_endpoints:
            - endpoint:
                address:
                  socket_address:
                    address: 192.168.1.100
                    port_value: 8080
            - endpoint:
                address:
                  socket_address:
                    address: 192.168.1.101
                    port_value: 8080
    
    health_checks:
      - timeout: 1s
        interval: 10s
        unhealthy_threshold: 3
        healthy_threshold: 2
        http_health_check:
          path: "/health"
          expected_statuses:
            - start: 200
              end: 299
    
    outlier_detection:
      consecutive_5xx: 5
      interval: 30s
      base_ejection_time: 30s
      max_ejection_percent: 50
      split_external_local_origin_errors: true

Interfaz de Administración

Accede a la interfaz de administración de Envoy para monitoreo:

admin:
  address:
    socket_address:
      protocol: TCP
      address: 127.0.0.1
      port_value: 9001

Accede a puntos finales de administración:

# Obtén ayuda de administración
curl http://localhost:9001/

# Ver configuración
curl http://localhost:9001/config_dump

# Ver estadísticas
curl http://localhost:9001/stats

# Ver configuración en tiempo de ejecución
curl http://localhost:9001/runtime

# Ver clústeres
curl http://localhost:9001/clusters

# Obtén información de oyentes
curl http://localhost:9001/listeners

Solución de Problemas

Comprueba estado del servicio Envoy:

sudo systemctl status envoy
sudo journalctl -u envoy -f

Valida configuración:

envoy -c /etc/envoy/envoy.yaml --mode validate

Prueba configuración con ejecución en seco:

envoy -c /etc/envoy/envoy.yaml --mode init_only

Comprueba puertos de escucha:

sudo netstat -tlnp | grep envoy

Consulta interfaz de administración:

curl -s http://localhost:9001/stats | grep -i error
curl -s http://localhost:9001/clusters | grep -i status

Prueba conectividad backend:

curl -v http://localhost:10000/

Habilita registro de depuración:

sudo systemctl stop envoy
sudo /usr/local/bin/envoy -c /etc/envoy/envoy.yaml --log-level debug

Conclusión

Envoy proporciona una plataforma de proxy sofisticada para arquitecturas modernas de microservicios. Su modelo de configuración flexible, capacidades avanzadas de balanceo de carga, verificación de salud, ruptura de circuito y observabilidad exhaustiva la hacen ideal para patrones complejos de comunicación servicio a servicio. Ya sea operando como proxy de borde, puerta de API o proxy de malla de servicios, Envoy entrega el control y visibilidad requeridos para sistemas distribuidos confiables.