O espelhamento de tráfego, também conhecido como traffic shadowing, copia o tráfego de produção em tempo real para um serviço de teste sem afetar o ambiente produtivo. As requisições espelhadas operam no modelo fire-and-forget: a malha as envia fora do caminho crítico da requisição e descarta todas as respostas. O Service Mesh (ASM) oferece suporte ao espelhamento de tráfego entre clusters, permitindo validar novas versões de serviços, depurar problemas ou executar testes de simulação com base no tráfego real de produção.
Na configuração a seguir, o Cluster A representa o ambiente de produção e o Cluster B, o ambiente de teste. O gateway de entrada no Cluster A espelha o tráfego recebido para o Cluster B, onde um serviço de teste processa as requisições espelhadas.

Quando usar o espelhamento de tráfego
|
Caso de uso |
Descrição |
|
Validação pré-lançamento |
Espelhe o tráfego de produção para uma nova versão do serviço e compare os resultados antes da implantação. Diferentemente de testes manuais com dados de amostra, o tráfego espelhado abrange casos extremos do mundo real, como entradas malformadas e payloads maliciosos. |
|
Migração de sistema |
Direcione o tráfego do sistema antigo para o novo em uma execução experimental. Verifique se o novo sistema lida com todos os cenários de produção antes do corte definitivo. |
|
Depuração em tempo real |
Replique o tráfego de um serviço em execução para uma instância temporária de depuração. Reproduza problemas com tráfego real sem impactar os usuários. |
|
Isolamento de dados de teste |
Encaminhe o tráfego de produção espelhado para um banco de dados de teste separado, mantendo os dados de produção intactos. |
|
Registro de comportamento do usuário |
Capture dados reais de comportamento para algoritmos de recomendação e análise de perfil de usuário armazenando o tráfego espelhado em logs. |
Como funciona o espelhamento de tráfego
Antes de configurar o espelhamento, compreenda dois comportamentos importantes:
Modificação do cabeçalho Host: As requisições espelhadas recebem o sufixo
-shadowno cabeçalho Host/Authority. Por exemplo, se o Host original forhttpbin, o Host da requisição espelhada torna-sehttpbin-shadow. O campohostna seçãomirrordo VirtualService determina apenas o endereço de destino — ele não sobrescreve o cabeçalho Host original.Porcentagem de espelhamento: O campo
mirrorPercentage.valuecontrola a fração do tráfego a ser espelhada. Se omitido, 100% do tráfego será espelhado.
Exemplo de configuração do VirtualService
O VirtualService abaixo roteia todo o tráfego para o subconjunto v1 e o espelha para o subconjunto v1-mirroring:
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: myapp-traffic-mirroring
spec:
hosts:
- myapp
http:
- route:
- destination:
host: myapp.default.svc.cluster.local
port:
number: 8000
subset: v1
weight: 100
mirror:
host: myapp.default.svc.cluster.local
port:
number: 8000
subset: v1-mirroring
Após aplicar essa configuração, cada requisição para myapp é atendida pelo subconjunto v1, enquanto uma cópia de cada requisição é enviada ao subconjunto v1-mirroring.
Pré-requisitos
Antes de começar, certifique-se de ter:
Dois clusters Kubernetes (Cluster A e Cluster B) com o ASM configurado
kubectl configurado para acessar ambos os clusters
Injeção automática de sidecar ativada nos namespaces de destino
Etapa 1: Implantar o serviço httpbin no Cluster B
-
Crie um arquivo chamado
httpbin.yamlcom o seguinte conteúdo: -
Implante a aplicação httpbin v1:
kubectl apply -f httpbin.yaml -
Verifique se o Pod está em execução:
kubectl get pods -l app=httpbinA saída esperada é semelhante a:
NAME READY STATUS RESTARTS AGE httpbin-v1-xxxxxxxxx-xxxxx 2/2 Running 0 30sO valor
2/2na coluna READY confirma que o proxy sidecar foi injetado junto ao contêiner da aplicação.
Etapa 2: Configurar uma regra de roteamento para o gateway de entrada no Cluster B
Esta etapa expõe o serviço httpbin por meio do gateway de entrada do Cluster B, permitindo que o tráfego espelhado do Cluster A o alcance.
-
Crie um arquivo chamado
httpbin-gateway.yamlcom o seguinte conteúdo: -
Aplique o Gateway e o VirtualService:
kubectl apply -f httpbin-gateway.yaml -
Envie uma requisição de teste para verificar se o serviço está acessível pelo gateway de entrada:
curl http://<cluster-b-ingress-gateway-ip>/headersSubstitua
<cluster-b-ingress-gateway-ip>pelo IP externo do gateway de entrada no Cluster B.A saída esperada é semelhante a:
{ "headers": { "Accept": "*/*", "Host": "47.99.XX.XX", "User-Agent": "curl/7.79.1", "X-Envoy-Attempt-Count": "1", "X-Envoy-External-Address": "120.244.XXX.XXX", "X-Forwarded-Client-Cert": "By=spiffe://cluster.local/ns/default/sa/httpbin;Hash=158e4ef69876550c34d10e3bfbd8d43f5ab481b16ba0e90b4e38a2d53ac****;Subject=\"\";URI=spiffe://cluster.local/ns/istio-system/sa/istio-ingressgateway-service-account" } }
Etapa 3: Configurar o espelhamento de tráfego no Cluster A
Implante a mesma aplicação httpbin no Cluster A, caso ainda não tenha feito isso. Utilize o mesmo arquivo httpbin.yaml da Etapa 1:
kubectl apply -f httpbin.yaml
Em seguida, crie quatro recursos no Cluster A:
Um ServiceEntry que registra o gateway de entrada do Cluster B como um serviço externo
Uma DestinationRule que define o subconjunto
v1para o serviço httpbin localUm Gateway e um VirtualService que roteiam o tráfego para o serviço httpbin local e o espelham para o Cluster B
Criar o ServiceEntry
O tráfego espelhado tem como alvo um endereço externo (o gateway de entrada do Cluster B). Um ServiceEntry informa à malha como resolver esse endereço.
-
Crie um arquivo chamado
httpbin-cluster-b.yamlcom o seguinte conteúdo:apiVersion: networking.istio.io/v1alpha3 kind: ServiceEntry metadata: name: httpbin-cluster-b spec: hosts: - httpbin.mirror.cluster-b location: MESH_EXTERNAL ports: - number: 80 # Port of the ingress gateway in Cluster B name: http protocol: HTTP resolution: STATIC endpoints: - address: 47.95.XX.XX # External IP of the ingress gateway in Cluster BSubstitua
47.95.XX.XXpelo IP externo real do gateway de entrada no Cluster B. -
Aplique o ServiceEntry:
kubectl apply -f httpbin-cluster-b.yaml
Criar a DestinationRule
O VirtualService roteia o tráfego para o subconjunto v1 do httpbin. Uma DestinationRule define esse subconjunto.
-
Crie um arquivo chamado
httpbin-destinationrule.yamlcom o seguinte conteúdo:apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: httpbin spec: host: httpbin subsets: - name: v1 labels: version: v1 -
Aplique a DestinationRule:
kubectl apply -f httpbin-destinationrule.yaml
Criar o Gateway e o VirtualService com espelhamento
O VirtualService roteia todo o tráfego para o subconjunto v1 do serviço httpbin local e, simultaneamente, espelha uma porcentagem desse tráfego para o Cluster B por meio do ServiceEntry.
-
Crie um arquivo chamado
httpbin-gateway.yamlcom o seguinte conteúdo:NotaO campo
mirror.hostserve apenas para a resolução de destino. O cabeçalho Host real das requisições espelhadas corresponde ao Host original com o sufixo-shadow, e não ahttpbin.mirror.cluster-b. -
Aplique a configuração:
kubectl apply -f httpbin-gateway.yaml
Etapa 4: Verificar o funcionamento do espelhamento de tráfego
Verificar a configuração do Envoy
Visualize o dump de configuração do Envoy no Pod do gateway de entrada do Cluster A para confirmar a aplicação da política de espelhamento:
"routes": [
{
"match": {
"prefix": "/headers",
"case_sensitive": true
},
"route": {
"cluster": "outbound|8000|v1|httpbin.default.svc.cluster.local",
"timeout": "0s",
"retry_policy": {
"retry_on": "connect-failure,refused-stream,unavailable,cancelled,retriable-status-codes",
"num_retries": 2,
"retry_host_predicate": [
{
"name": "envoy.retry_host_predicates.previous_hosts",
"typed_config": {
"@type": "type.googleapis.com/envoy.extensions.retry.host.previous_hosts.v3.PreviousHostsPredicate"
}
}
],
"host_selection_retry_max_attempts": "5",
"retriable_status_codes": [503]
},
"request_mirror_policies": [
{
"cluster": "outbound|80||httpbin.mirror.cluster-b",
"runtime_fraction": {
"default_value": {
"numerator": 500000,
"denominator": "MILLION"
}
},
"trace_sampled": false
}
]
}
}
]
Verifique os seguintes campos principais:
|
Campo |
Valor esperado |
Significado |
|||
|
|
|
80 |
httpbin.mirror.cluster-b` |
O tráfego espelhado é enviado ao gateway de entrada do Cluster B |
|
|
|
|
50% do tráfego é espelhado (500.000 / 1.000.000) |
Enviar tráfego de teste e verificar logs
Embora o dump de configuração do Envoy confirme os parâmetros definidos, valide se o tráfego espelhado realmente chega ao Cluster B. Envie requisições de teste e analise os logs do Pod httpbin em ambos os clusters.
-
Envie uma requisição para o gateway de entrada no Cluster A:
curl http://<cluster-a-ingress-gateway-ip>/headers -
Consulte os logs do Pod httpbin no Cluster A para confirmar o atendimento da requisição:
kubectl logs -l app=httpbin -c httpbinA saída esperada indica que o Cluster A recebeu e processou a requisição:
127.0.0.6 - - [11/Mar/2026 06:00:00] "GET /headers HTTP/1.1" 200 - -
Examine os logs do Pod httpbin no Cluster B para confirmar a chegada da requisição espelhada:
kubectl logs -l app=httpbin -c httpbinSe o espelhamento estiver funcionando corretamente, os logs do Cluster B exibirão uma entrada correspondente à requisição
GET /headers:127.0.0.6 - - [11/Mar/2026 06:00:00] "GET /headers HTTP/1.1" 200 -A requisição espelhada carrega um cabeçalho Host com o sufixo
-shadow(por exemplo,httpbin-shadow), mas o formato padrão de log de acesso do httpbin não exibe cabeçalhos Host. Para inspecionar o cabeçalho-shadow, consulte os logs de acesso do Envoy no proxy sidecar ou ative o log detalhado.NotaCaso o Cluster B não apresente a requisição espelhada, verifique se o endereço IP no ServiceEntry corresponde ao IP externo real do gateway de entrada do Cluster B e se o gateway aceita tráfego na porta 80.
Limpeza
Para remover os recursos criados neste tutorial:
No Cluster B:
kubectl delete -f httpbin-gateway.yaml
kubectl delete -f httpbin.yaml
No Cluster A:
kubectl delete -f httpbin-gateway.yaml
kubectl delete -f httpbin-destinationrule.yaml
kubectl delete -f httpbin-cluster-b.yaml
kubectl delete -f httpbin.yaml