TL;DR — Resumo Rápido

Guia do Envoy Proxy para service mesh e edge proxy. Cobre xDS API, balanceamento de carga, mTLS, observabilidade, circuit breaking e sidecar no Kubernetes.

O Envoy Proxy é o plano de dados no coração dos service meshes modernos. Criado originalmente no Lyft para resolver observabilidade e confiabilidade de microsserviços em escala, o Envoy é hoje o sidecar de facto para o Istio, o edge proxy de muitos controladores de ingress e um proxy L3/L4/L7 de propósito geral usado pelo Google, AWS e milhares de empresas. Este guia cobre a arquitetura do Envoy, configuração estática e dinâmica, algoritmos de balanceamento de carga, pipeline de observabilidade, gerenciamento de TLS e filtros avançados.

Pré-requisitos

  • Docker (para testes autônomos) ou um cluster Kubernetes.
  • Conhecimento básico de HTTP, TLS e conceitos de proxy reverso.
  • Familiaridade com a sintaxe de configuração YAML.
  • curl e opcionalmente jq para testar endpoints.

Arquitetura do Envoy

O Envoy opera como um proxy de rede fora do processo — ele é executado junto com sua aplicação em vez de como uma biblioteca dentro dela. Isso mantém o proxy independente de linguagem e permite atualizações independentes.

Componentes principais:

  • Listeners — Portas de rede onde o Envoy escuta (conexões downstream chegam aqui).
  • Cadeias de filtros — Lista ordenada de filtros de rede e HTTP aplicados a cada conexão.
  • Clusters — Grupos nomeados de endpoints upstream (seus serviços backend).
  • Endpoints — Pares IP:porta individuais dentro de um cluster, descobertos via EDS ou config estática.
  • Rotas — Regras que mapeiam requisições de entrada para clusters com base em caminho, cabeçalho ou parâmetros de consulta.

Modelo de threads: O Envoy usa uma thread principal para gerenciamento mais uma thread worker por núcleo de CPU. Cada thread worker gerencia conexões de forma independente usando I/O não bloqueante. Não há contenção de bloqueios no caminho quente — cada worker tem seu próprio pool de conexões.

Hot restart: O Envoy suporta atualizações binárias sem tempo de inatividade via handshake em memória compartilhada entre o processo antigo e o novo. O novo processo assume as conexões existentes sem descartar tráfego.


Configuração Estática (envoy.yaml)

A maneira mais rápida de começar é uma configuração YAML estática com todos os recursos definidos inline:

admin:
  address:
    socket_address:
      address: 0.0.0.0
      port_value: 9901

static_resources:
  listeners:
    - name: listener_0
      address:
        socket_address:
          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: service_backend
                            timeout: 15s
                            retry_policy:
                              retry_on: "5xx,reset,connect-failure"
                              num_retries: 3
                http_filters:
                  - name: envoy.filters.http.router
                    typed_config:
                      "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router

  clusters:
    - name: service_backend
      connect_timeout: 0.5s
      type: STRICT_DNS
      lb_policy: ROUND_ROBIN
      load_assignment:
        cluster_name: service_backend
        endpoints:
          - lb_endpoints:
              - endpoint:
                  address:
                    socket_address:
                      address: backend-service
                      port_value: 8080
      health_checks:
        - timeout: 1s
          interval: 10s
          unhealthy_threshold: 2
          healthy_threshold: 2
          http_health_check:
            path: /health

O bloco admin expõe a API de gerenciamento do Envoy na porta 9901. Use-o para consultar /stats, /clusters, /config_dump e /healthcheck/fail para testes de circuit-breaker.


Configuração Dinâmica: A xDS API

Configurações estáticas funcionam para implantações simples, mas se tornam difíceis de gerenciar em escala. O protocolo xDS (x Discovery Service) do Envoy permite que um plano de controle envie alterações de configuração em tempo de execução — sem recarga, sem reinicialização.

Tipos de recursos xDS:

APIGerencia
LDS (Listener Discovery Service)Listeners e cadeias de filtros
RDS (Route Discovery Service)Virtual hosts e tabelas de rotas
CDS (Cluster Discovery Service)Definições de clusters e políticas
EDS (Endpoint Discovery Service)Saúde individual de endpoints IP:porta
SDS (Secret Discovery Service)Certificados TLS e chaves privadas

ADS (Aggregated Discovery Service): Combina todas as xDS APIs em um único stream gRPC bidirecional. É o modo recomendado porque garante ordenação — um novo cluster é sempre entregue antes da rota que o referencia, evitando erros 503 temporários durante atualizações.

Delta xDS: Em vez de enviar o estado completo a cada atualização, o delta xDS envia apenas os recursos adicionados, modificados ou removidos. Essencial para malhas grandes com milhares de clusters.


Algoritmos de Balanceamento de Carga

O Envoy suporta seis políticas de balanceamento de carga selecionáveis por cluster:

PolíticaMelhor Para
ROUND_ROBINCapacidade uniforme do backend, escolha padrão
LEAST_REQUESTDuração variável de requisições, evita backends sobrecarregados
RING_HASHHash consistente — afinidade de cache, serviços com estado
RANDOMSimples, baixo overhead, resistente a endpoints lentos
MAGLEVHash consistente do Google — distribuição mais uniforme
CLUSTER_PROVIDEDDelega a decisão ao tipo de cluster upstream

Observabilidade

O Envoy é opinativo sobre observabilidade — foi construído para tornar os sistemas distribuídos depuráveis. Três pilares integrados:

Estatísticas: O Envoy emite milhares de contadores, medidores e histogramas. Exponha-os ao Prometheus no endpoint admin:

curl http://localhost:9901/stats/prometheus

Rastreamento Distribuído: O Envoy gera e propaga automaticamente cabeçalhos de contexto de rastreamento para Jaeger, Zipkin e OpenTelemetry. Sua aplicação só precisa encaminhar esses cabeçalhos — o Envoy lida com a criação de rastreamentos.

Log de Acesso: Logs de acesso JSON estruturado com todos os metadados da requisição, incluindo cluster upstream, duração, código de resposta e bytes enviados.


TLS e mTLS com SDS

O Secret Discovery Service (SDS) do Envoy resolve a distribuição manual de certificados: os certificados são obtidos de um plano de controle em tempo de execução e rotacionados sem reinicialização do processo.

Para TLS mútuo entre serviços, o campo match_subject_alt_names aplica a identidade SPIFFE — apenas conexões de serviços com o URI SPIFFE esperado são aceitas. É assim que o Istio implementa redes de confiança zero: cada conexão pod a pod é autenticada mutuamente via certificados de curta duração rotacionados pelo SPIRE.


Filtros Avançados

Circuit Breaking: Previne falhas em cascata limitando requisições pendentes, novas tentativas e conexões. Configure max_connections, max_pending_requests, max_requests e max_retries por cluster.

Detecção de Outliers: Ejeta automaticamente hosts não saudáveis do pool de balanceamento. Após cinco respostas 5xx consecutivas, o endpoint é ejetado por 30 segundos. max_ejection_percent evita ejetar todos os hosts quando o upstream degrada globalmente.

Injeção de Falhas: Injeta latência ou erros em uma porcentagem de requisições para testes de caos, configurável por rota sem mudanças no código da aplicação.

Autorização Externa: Delega decisões de autorização a um serviço gRPC externo (OPA, Ory Keto). O filtro ext_authz envia cabeçalhos de requisição ao serviço de autorização antes de encaminhar upstream.

Extensões Wasm: O Envoy suporta plugins de filtro WebAssembly para lógica de negócio personalizada em qualquer linguagem que compile para Wasm (Go, Rust, C++). Os filtros Wasm são recarregados a quente sem atualizações binárias.


Envoy vs Outros Proxies

RecursoEnvoyNginxHAProxyTraefikLinkerdMOSN
Config dinâmicaxDS API (sem recarga)nginx -s reloadAPI em tempo realAuto-descobre K8sxDS (limitado)xDS API
Service meshSim (Istio, Consul)NãoNãoNão (só ingress)Sim (Linkerd2)Sim
Protocolos L7HTTP/1.1, HTTP/2, gRPC, ThriftHTTP/1.1, HTTP/2HTTP/1.1, HTTP/2HTTP/1.1, HTTP/2HTTP/1.1, HTTP/2, gRPCHTTP/1.1, HTTP/2, Dubbo
ObservabilidadeStats + tracing integradosBaseado em módulosSocket de statsPlugin PrometheusSinais dourados integradosStats integrados
mTLSSDS + SPIFFECerts manuaisCerts manuaisCerts manuaisAutomáticoSDS
Filtros WasmSimNãoNãoNãoNãoSim

Exemplo Prático: Envoy como Proxy Frontal

Você tem três microsserviços (users, orders, products) atrás do Envoy como edge proxy, com tráfego dividido entre v1 e v2 do serviço de pedidos para implantação canary:

routes:
  - match:
      prefix: "/orders"
    route:
      weighted_clusters:
        clusters:
          - name: orders_v1
            weight: 90
          - name: orders_v2
            weight: 10
        total_weight: 100

Esta configuração de cluster ponderado envia 10% do tráfego /orders para o canary v2 sem alterações no código da aplicação.


Armadilhas e Casos Extremos

  • Sensibilidade a maiúsculas de cabeçalhos: Cabeçalhos HTTP/2 são minúsculas por padrão. O Envoy os normaliza — garanta que seus serviços lidem com content-type, authorization em minúsculas.
  • Timeouts upstream vs de rota: connect_timeout do cluster (TCP) e timeout da rota (requisição) são independentes. O timeout de rota padrão é 15 segundos — defina-o explicitamente.
  • Orçamento de novas tentativas: Sem limites em retry_on, as novas tentativas sob carga podem amplificar falhas. Combine sempre novas tentativas com um circuit breaker.

Solução de Problemas

SintomaCausa ProvávelSolução
503 upstream_reset_before_response_startedUpstream fechou conexão antes de responderVerifique o caminho de health check; aumente connect_timeout
404 do Envoy (não do upstream)Sem rota correspondenteExecute /config_dump na porta admin; verifique o domínio do virtual host
Circuit breaker aberto nas statsUpstream sobrecarregadoAumente max_pending_requests ou escale o upstream
Falha de handshake mTLSIncompatibilidade de SAN no certificadoVerifique se match_subject_alt_names corresponde ao URI SPIFFE real
Alta latência P99Fome de threadsAumente o número de worker threads com concurrency no bootstrap

Resumo

  • A xDS API permite configuração totalmente dinâmica sem reinicializações — clusters, rotas, listeners e certificados são atualizados ao vivo.
  • O balanceamento de carga oferece seis algoritmos incluindo Ring Hash para afinidade de cache e Least Request para cargas de trabalho heterogêneas.
  • A observabilidade integrada fornece stats Prometheus, cabeçalhos de rastreamento distribuído e logs de acesso JSON estruturado.
  • mTLS via SDS + SPIFFE entrega redes de confiança zero com certificados de curta duração rotacionados automaticamente.
  • Os filtros avançados tornam o Envoy extensível sem tocar no código da aplicação.

Artigos Relacionados