O filtro External Processing (ext_proc) do Envoy encaminha o processamento de requisições e respostas HTTP para um serviço gRPC externo. Em vez de escrever um plug-in Wasm ou incorporar lógica ao Envoy, execute um servidor gRPC independente que inspeciona e modifica cabeçalhos, corpos e trailers conforme o tráfego flui pela malha.
O ext_proc é ideal quando você precisa:
Adicionar, remover ou reescrever cabeçalhos HTTP com base em lógica de negócios
Implementar verificações personalizadas de autenticação ou autorização fora do sidecar
Enriquecer requisições com dados de sistemas externos antes de chegarem ao serviço upstream
Usar uma linguagem ou framework incompatível com Wasm
Como funciona
O filtro ext_proc intercepta o tráfego no sidecar e o encaminha ao serviço gRPC externo para processamento. Esse filtro oferece suporte a seis etapas independentes, cada uma controlada por um modo de processamento:
|
Etapa |
Direção |
Descrição |
|
Cabeçalhos da requisição |
Entrada |
Inspeciona ou modifica cabeçalhos antes de a requisição chegar ao upstream |
|
Corpo da requisição |
Entrada |
Inspeciona ou modifica o corpo da requisição |
|
Trailers da requisição |
Entrada |
Inspeciona ou modifica trailers de requisição HTTP/2 |
|
Cabeçalhos da resposta |
Saída |
Inspeciona ou modifica cabeçalhos antes de a resposta chegar ao downstream |
|
Corpo da resposta |
Saída |
Inspeciona ou modifica o corpo da resposta |
|
Trailers da resposta |
Saída |
Inspeciona ou modifica trailers de resposta HTTP/2 |
Por padrão, nenhuma dessas etapas é enviada ao processador externo. Ative explicitamente cada etapa definindo seu modo de processamento como SEND na configuração do EnvoyFilter.
O diagrama a seguir ilustra o fluxo completo de requisição e resposta:
Um serviço downstream envia uma requisição. O Envoy a intercepta e a encaminha ao serviço de processamento externo.
O serviço de processamento externo inspeciona ou modifica a requisição e retorna o resultado ao Envoy.
O Envoy aplica as modificações e encaminha a requisição ao serviço upstream.
O serviço upstream retorna uma resposta. O Envoy a intercepta e a encaminha ao serviço de processamento externo.
O serviço de processamento externo inspeciona ou modifica a resposta e retorna o resultado ao Envoy.
O Envoy aplica as modificações e encaminha a resposta ao serviço downstream.
Pré-requisitos
Antes de começar, verifique se você tem:
A aplicação HTTPBin implantada e acessível, com uma aplicação sleep implantada conforme descrito em Operações relacionadas
Etapa 1: Escreva o serviço de processamento externo
Crie um servidor gRPC que implemente a interface de serviço ExternalProcessor do Envoy. O servidor recebe um fluxo de mensagens ProcessingRequest do Envoy e deve retornar uma ProcessingResponse correspondente para cada uma.
O trecho Go a seguir mostra a lógica principal. Para obter o projeto executável completo, consulte ext-proc-demo no GitHub. Para a especificação completa da API, consulte a referência proto do ext_proc do Envoy.
Este exemplo trata duas etapas de processamento:
Cabeçalhos da requisição: Adiciona
x-ext-proc-header: hello-to-asma todas as requisições de entrada.Cabeçalhos da resposta: Adiciona
x-ext-proc-header: hello-from-asma todas as respostas de saída.
Empacote seu servidor gRPC como uma imagem de contêiner usando um Dockerfile e envie-a para um registro de contêineres antes da implantação.
Etapa 2: Implante o serviço de processamento externo
Esta etapa usa a imagem de exemplo ext_proc fornecida pelo ASM. O serviço de exemplo adiciona o cabeçalho x-ext-proc-header: hello-to-asm às requisições e x-ext-proc-header: hello-from-asm às respostas.
-
Crie um arquivo chamado
ext.yamlcom o seguinte conteúdo:apiVersion: v1 kind: Service metadata: name: ext-proc labels: app: ext-proc service: ext-proc spec: ports: # gRPC listener port for the external processing service - name: grpc port: 9002 targetPort: 9002 selector: app: ext-proc --- apiVersion: apps/v1 kind: Deployment metadata: name: ext-proc spec: replicas: 1 selector: matchLabels: app: ext-proc version: v1 template: metadata: labels: app: ext-proc version: v1 spec: containers: - image: registry-cn-hangzhou.ack.aliyuncs.com/ack-demo/ext-proc:v0.2 imagePullPolicy: IfNotPresent name: ext-proc ports: - containerPort: 9002 -
Aplique o manifesto e verifique se o serviço está em execução:
kubectl apply -f ext.yaml -
Verifique os logs do pod para confirmar a inicialização do servidor gRPC. Saída esperada: Este log confirma que o serviço de processamento externo está em execução e ouvindo na porta 9002.
kubectl logs deploy/ext-procI1126 06:41:25.467033 1 main.go:52] Starting gRPC server on port :9002
Etapa 3: Configure o EnvoyFilter
Crie um EnvoyFilter para inserir o filtro ext_proc na cadeia de filtros HTTP do sidecar. Essa configuração roteia os cabeçalhos de requisição e resposta do sidecar do HTTPBin para o seu serviço de processamento externo.
Faça login no console do ASM. No painel de navegação à esquerda, escolha .
Na página Mesh Management, clique em nome da instância do ASM. No painel de navegação à esquerda, escolha .
-
Crie um EnvoyFilter chamado
httpbin-ext-proccom o seguinte conteúdo:Campos principais:
Campo
Descrição
context: SIDECAR_INBOUNDAplica o filtro ao tráfego de entrada no proxy sidecar
portNumber: 80Direciona o listener HTTP na porta 80
operation: INSERT_BEFOREInsere o filtro ext_proc antes do filtro de roteador na cadeia
cluster_nameO endpoint do cluster Envoy para o serviço ext-proc, no formato `outbound
`
request_header_mode: SENDEnvia cabeçalhos de requisição ao processador externo. O padrão é
SKIP, ou seja, os cabeçalhos não são enviadosresponse_header_mode: SENDEnvia cabeçalhos de resposta ao processador externo. O padrão é
SKIP, ou seja, os cabeçalhos não são enviadosapiVersion: networking.istio.io/v1alpha3 kind: EnvoyFilter spec: configPatches: - applyTo: HTTP_FILTER match: context: SIDECAR_INBOUND listener: portNumber: 80 filterChain: filter: name: envoy.filters.network.http_connection_manager proxy: proxyVersion: ^MIN_VERSION-MAX_VERSION.* patch: operation: INSERT_BEFORE value: name: envoy.filters.http.ext_proc typed_config: '@type': >- type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor grpc_service: envoy_grpc: cluster_name: outbound|9002||ext-proc.default.svc.cluster.local authority: ext-proc.default.svc.cluster.local processing_mode: request_header_mode: SEND response_header_mode: SEND
Verifique a configuração
Envie uma requisição pela malha e confirme se o processador externo adicionou os cabeçalhos esperados.
No pod sleep, execute:
kubectl exec -it deploy/sleep -- curl httpbin:8000/headers -i
Procure estes dois cabeçalhos na saída:
Cabeçalho de resposta
x-ext-proc-header: hello-from-asm-- adicionado pelo processador externo antes de a resposta chegar ao downstreamCabeçalho de requisição
X-Ext-Proc-Header: hello-to-asm(visível no corpo JSON) -- adicionado pelo processador externo antes de a requisição chegar ao upstream
Saída esperada:
HTTP/1.1 200 OK
server: envoy
date: Wed, 11 Dec 2024 06:47:59 GMT
content-type: application/json
content-length: 564
access-control-allow-origin: *
access-control-allow-credentials: true
x-envoy-upstream-service-time: 3
x-ext-proc-header: hello-from-asm
{
"headers": {
"Accept": "*/*",
"Host": "httpbin:8000",
"User-Agent": "curl/8.1.2",
"X-B3-Parentspanid": "5c6dd2cc9312d6bb",
"X-B3-Sampled": "1",
"X-B3-Spanid": "1153a2737cee4434",
"X-B3-Traceid": "baba86b696edc75a5c6dd2cc9312d6bb",
"X-Envoy-Attempt-Count": "1",
"X-Ext-Proc-Header": "hello-to-asm",
"X-Forwarded-Client-Cert": "By=spiffe://cluster.local/ns/default/sa/httpbin;Hash=69d8f267c3c00b4396a83e12d14520acc9dadb1492d660e10f77e94dcad7cb06;Subject=\"\";URI=spiffe://cluster.local/ns/default/sa/sleep"
}
}
A presença de ambos os cabeçalhos confirma que o serviço de processamento externo intercepta e modifica corretamente o tráfego pelo sidecar do Envoy.