As liberações canário padrão encaminham o tráfego para diferentes versões de um único serviço com base em proporções de peso. Isso funciona para serviços isolados, mas falha quando uma requisição abrange vários serviços em uma cadeia de chamadas. Por exemplo, se o tráfego canário chega ao Serviço A, mas o sistema o encaminha aleatoriamente para a versão base do Serviço B, os resultados dos testes tornam-se não confiáveis.
As liberações canário de ponta a ponta resolvem esse problema ao adicionar tags ao tráfego de entrada no gateway e propagar essa tag por toda a cadeia de chamadas. Cada serviço lê a tag e encaminha a requisição para a versão correspondente, para que o tráfego canário flua exclusivamente pelas versões canário e o tráfego base permaneça nas versões base.
O Service Mesh (ASM) implementa isso por meio de duas capacidades:
Rotulagem de tráfego: uma CustomResourceDefinition (CRD) TrafficLabel que extrai rótulos dos cabeçalhos de requisição e os associa aos fluxos de tráfego
Roteamento baseado em rótulos: regras do VirtualService que encaminham o tráfego para subconjuntos correspondentes ao valor do rótulo
Como funciona
O diagrama a seguir mostra a cadeia de chamadas usada neste tutorial. O Serviço A (mocka) recebe o tráfego de entrada e chama o Serviço B (mockb):

Ambos os serviços têm duas versões implantadas: base e canary. Sem rótulos de tráfego, o balanceamento de carga round-robin distribui as requisições entre as versões.
Após configurar os rótulos de tráfego, o sistema:
Lê o cabeçalho
my-asm-prefer-tagdas requisições recebidas no gateway para classificar o tráfego comoversion-baseouversion-canary.Encaminha a requisição para a versão correspondente do Serviço A.
Propaga a tag para o Serviço B por meio do cabeçalho
my-trace-id, para que o Serviço B também encaminhe para a versão correspondente.
As suas aplicações devem propagar o cabeçalho HTTP nas chamadas de serviço. Os serviços de exemplo neste tutorial já incluem essa lógica. Para as suas próprias aplicações, implemente a propagação do cabeçalho utilizado na rotulagem de tráfego. Consulte src/mock-abc/go/main.go no código de exemplo para obter uma implementação de referência.
Pré-requisitos
Antes de iniciar, certifique-se de ter:
Uma instância do ASM da Enterprise Edition ou Ultimate Edition, versão 1.17.2.22 ou posterior. Consulte Crie uma instância do ASM ou Atualize uma instância do ASM
Um cluster adicionado à instância do ASM. Consulte Adicione um cluster a uma instância do ASM
Um gateway de entrada. Consulte Crie um gateway de entrada
Arquivos de configuração de exemplo
Baixe os arquivos de configuração de exemplo usados neste tutorial. O pacote contém os seguintes arquivos:
|
Arquivo |
Finalidade |
|
|
Implanta as versões base do Serviço A ( |
|
|
Implanta as versões canário de ambos os serviços |
|
|
Define o Gateway, os DestinationRules e os VirtualServices para o roteamento inicial |
|
|
Configura as CRDs TrafficLabel para a rotulagem de tráfego |
|
|
Aplica o roteamento baseado em rótulos ao Serviço B |
|
|
Aplica o roteamento baseado em rótulos ao Serviço A no gateway |
|
|
Adiciona distribuição baseada em peso (90% base, 10% baseada em rótulos) ao Serviço A |
Etapa 1: Implantar os serviços de exemplo
Ative a injeção automática de proxy sidecar para o namespace de destino (
defaultneste exemplo). Consulte Ative a injeção automática de proxy sidecar.-
Conecte-se ao cluster do Container Service for Kubernetes (ACK) com o kubectl e implante os serviços de exemplo:
kubectl apply -n default -f application-base.yaml kubectl apply -n default -f application-canary.yaml
Etapa 2: Configure as regras de roteamento iniciais
Configure o Gateway, os DestinationRules e os VirtualServices para estabelecer o roteamento básico sem rótulos de tráfego.
-
Crie um arquivo chamado routing.yaml com o seguinte conteúdo:
Esta configuração:
Cria um Gateway (
simple-gateway) que aceita todo o tráfego HTTP na porta 80Define DestinationRules para ambos os serviços com os subconjuntos
version-baseeversion-canaryCria VirtualServices que encaminham o tráfego sem lógica baseada em rótulos
-
Conecte-se à instância do ASM com o kubectl e aplique as regras de roteamento:
kubectl apply -n default -f routing.yaml -
Verifique se ambas as versões do serviço estão acessíveis.
Obtenha o endereço IP público do gateway de entrada no console do ASM. Consulte Obtenha o endereço IP do gateway de entrada do ASM.
-
Defina o IP do gateway como uma variável de ambiente. Substitua
<gateway-ip>pelo endereço IP real:export ASM_GATEWAY_IP=<gateway-ip> -
Envie requisições de teste:
for i in {1..200}; do curl -H'my-asm-prefer-tag: version-base' -H'my-trace-id: x000'$i http://${ASM_GATEWAY_IP}/; echo; sleep 1; done;
Saída esperada -- o sistema distribui o tráfego aleatoriamente entre todas as versões de ambos os serviços:
-> mocka(version: canary, ip: 172.17.0.129)-> mockb(version: base, ip: 172.17.0.70) -> mocka(version: base, ip: 172.17.0.132)-> mockb(version: base, ip: 172.17.0.70) -> mocka(version: base, ip: 172.17.0.132)-> mockb(version: canary, ip: 172.17.0.54) -> mocka(version: canary, ip: 172.17.0.129)-> mockb(version: canary, ip: 172.17.0.54)Neste ponto, o cabeçalho
my-asm-prefer-tagnão surte efeito no roteamento. As requisições seguem o balanceamento de carga round-robin independentemente do valor do cabeçalho.
Etapa 3: Configure os rótulos de tráfego
Crie recursos TrafficLabel para extrair rótulos de roteamento dos cabeçalhos de requisição. O ASM usa esses rótulos para determinar se o tráfego é version-base ou version-canary. Para saber mais sobre a rotulagem de tráfego, consulte Rotule o tráfego.
-
Crie um arquivo chamado trafficlabel.yaml com o seguinte conteúdo:
Esta configuração define dois recursos TrafficLabel:
Recurso
Escopo
Comportamento
trafficlabel-nsTodos os serviços no namespace
default(mocka,mockb)Usa
$getExternalInboundRequestHeaderpara extrair a tag de versão do cabeçalhomy-asm-prefer-tag. O segundo parâmetro,my-trace-id, especifica o cabeçalho de rastreamento que a aplicação deve propagar entre os serviços.ingressgatewayApenas o gateway de entrada (namespace
istio-system)Lê a tag de versão do cabeçalho
my-asm-prefer-tagda requisição de entrada do cliente.NotaEste exemplo usa os nomes de cabeçalho
my-asm-prefer-tagemy-trace-id. Substitua-os por cabeçalhos que correspondam à sua aplicação. -
Conecte-se à instância do ASM com o kubectl e aplique os rótulos de tráfego:
kubectl apply -f trafficlabel.yaml
Etapa 4: Aplique o roteamento baseado em rótulos e verifique
Esta etapa verifica progressivamente a liberação canário de ponta a ponta em três fases:
Roteamento de salto único -- Aplique o roteamento baseado em rótulos ao Serviço B e confirme se a tag de tráfego encaminha corretamente as requisições para a versão correspondente
Roteamento de cadeia completa -- Aplique o roteamento baseado em rótulos ao Serviço A no gateway para que o tráfego canário flua pelas versões canário de todos os serviços de ponta a ponta
Roteamento ponderado -- Combine a distribuição baseada em peso com o roteamento baseado em rótulos para controlar o percentual da liberação canário
Verifique o roteamento baseado em rótulos para o Serviço B
Aplique primeiro o roteamento baseado em rótulos ao Serviço B. Isso verifica se a tag de tráfego do Serviço A encaminha corretamente as requisições para a versão correspondente do Serviço B.

-
Crie um arquivo chamado
vs-tf-mockb.yamlcom o seguinte conteúdo:apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: vs-mockb spec: hosts: - mockb http: - route: - destination: host: mockb subset: $asm-labels-sampleO subconjunto
$asm-labels-sampleresolve dinamicamente para o valor do rótulo de tráfego -- sejaversion-baseouversion-canary. -
Aplique a regra de roteamento:
kubectl apply -n default -f vs-tf-mockb.yaml -
Envie tráfego canário e verifique se o Serviço B o recebe na versão canário:
for i in {1..200}; do curl -H'my-asm-prefer-tag: version-canary' -H'my-trace-id: x000'$i http://${ASM_GATEWAY_IP}/; echo; sleep 1; done;Saída esperada -- o Serviço A ainda recebe tráfego aleatório, mas o Serviço B encaminha consistentemente para a versão canário:
-> mocka(version: canary, ip: 172.17.0.129)-> mockb(version: canary, ip: 172.17.0.54) -> mocka(version: base, ip: 172.17.0.132)-> mockb(version: canary, ip: 172.17.0.54) -> mocka(version: base, ip: 172.17.0.132)-> mockb(version: canary, ip: 172.17.0.54) -
Envie tráfego base e verifique se o Serviço B o recebe na versão base:
for i in {1..200}; do curl -H'my-asm-prefer-tag: version-base' -H'my-trace-id: x000'$i http://${ASM_GATEWAY_IP}/; echo; sleep 1; done;Saída esperada -- o Serviço B encaminha consistentemente para a versão base:
-> mocka(version: canary, ip: 172.17.0.129)-> mockb(version: base, ip: 172.17.0.70) -> mocka(version: base, ip: 172.17.0.132)-> mockb(version: base, ip: 172.17.0.70) -> mocka(version: base, ip: 172.17.0.132)-> mockb(version: base, ip: 172.17.0.70)
O roteamento do Serviço B agora funciona conforme o esperado. O Serviço A ainda recebe tráfego aleatoriamente porque você ainda não aplicou nenhuma regra de roteamento baseada em rótulos ao gateway.
Verifique o roteamento canário de ponta a ponta
Aplique o roteamento baseado em rótulos ao Serviço A no nível do gateway para que toda a cadeia de chamadas respeite o rótulo de tráfego.

-
Crie um arquivo chamado
vs-tf-mocka.yamlcom o seguinte conteúdo:apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: vs-gateway-mocka spec: gateways: - simple-gateway hosts: - "*" http: - route: - destination: host: mocka subset: $asm-labels-sample -
Aplique a regra de roteamento ao gateway de entrada:
kubectl apply -n default -f vs-tf-mocka.yaml -
Envie tráfego canário e verifique se ambos os serviços encaminham para as versões canário:
for i in {1..200}; do curl -H'my-asm-prefer-tag: version-canary' -H'my-trace-id: x000'$i http://${ASM_GATEWAY_IP}/; echo; sleep 1; done;Saída esperada -- todo o tráfego flui pelas versões canário de ponta a ponta:
-> mocka(version: canary, ip: 172.17.0.69)-> mockb(version: canary, ip: 172.17.0.130) -> mocka(version: canary, ip: 172.17.0.69)-> mockb(version: canary, ip: 172.17.0.130) -> mocka(version: canary, ip: 172.17.0.69)-> mockb(version: canary, ip: 172.17.0.130) -
Envie tráfego base e verifique se ambos os serviços encaminham para as versões base:
for i in {1..200}; do curl -H'my-asm-prefer-tag: version-base' -H'my-trace-id: x000'$i http://${ASM_GATEWAY_IP}/; echo; sleep 1; done;Saída esperada -- todo o tráfego flui pelas versões base de ponta a ponta:
-> mocka(version: base, ip: 172.17.0.90)-> mockb(version: base, ip: 172.17.0.93) -> mocka(version: base, ip: 172.17.0.90)-> mockb(version: base, ip: 172.17.0.93) -> mocka(version: base, ip: 172.17.0.90)-> mockb(version: base, ip: 172.17.0.93)
O roteamento canário de ponta a ponta agora está ativo. O tráfego canário atinge consistentemente as versões canário de todos os serviços, e o tráfego base permanece nas versões base.
Verifique a distribuição ponderada de tráfego com rótulos
Em produção, você geralmente começa encaminhando uma pequena porcentagem de tráfego para a versão canário. Combine a distribuição baseada em peso com o roteamento baseado em rótulos para controlar a liberação.

-
Crie um arquivo chamado
vs-tf-mocka-90-10.yamlcom o seguinte conteúdo:apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: vs-gateway-mocka spec: gateways: - simple-gateway hosts: - "*" http: - route: - destination: host: mocka subset: version-base weight: 90 - destination: host: mocka subset: $asm-labels-sample weight: 10Esta configuração envia 90% do tráfego para a versão base do Serviço A. O sistema encaminha os 10% restantes com base no rótulo de tráfego -- se o cabeçalho
my-asm-prefer-tagestiver definido comoversion-canary, esses 10% vão para a versão canário. -
Aplique a regra de roteamento ponderado:
kubectl apply -n default -f vs-tf-mocka-90-10.yaml -
Envie tráfego canário e verifique a distribuição:
for i in {1..200}; do curl -H'my-asm-prefer-tag: version-canary' -H'my-trace-id: x000'$i http://${ASM_GATEWAY_IP}/; echo; sleep 1; done;Saída esperada -- aproximadamente 90% das requisições chegam à versão base do Serviço A, enquanto 10% chegam à versão canário. O Serviço B encaminha consistentemente para a versão canário porque o rótulo se propaga pela cadeia de chamadas:
-> mocka(version: base, ip: 172.17.0.90)-> mockb(version: canary, ip: 172.17.0.130) -> mocka(version: base, ip: 172.17.0.90)-> mockb(version: canary, ip: 172.17.0.130) -> mocka(version: base, ip: 172.17.0.90)-> mockb(version: canary, ip: 172.17.0.130) ... -> mocka(version: canary, ip: 172.17.0.69)-> mockb(version: canary, ip: 172.17.0.130)Cerca de 9 em cada 10 requisições atingem
mocka(version: base), enquanto aproximadamente 1 em 10 atingemocka(version: canary). Em ambos os casos, omockbencaminha para a versão canário. -
Envie tráfego base e verifique se todas as requisições chegam às versões base:
for i in {1..200}; do curl -H'my-asm-prefer-tag: version-base' -H'my-trace-id: x000'$i http://${ASM_GATEWAY_IP}/; echo; sleep 1; done;Saída esperada -- 90% do tráfego vai diretamente para a versão base. O sistema também encaminha os 10% restantes para a versão base porque o rótulo resolve para
version-base:-> mocka(version: base, ip: 172.17.0.90)-> mockb(version: base, ip: 172.17.0.93) -> mocka(version: base, ip: 172.17.0.90)-> mockb(version: base, ip: 172.17.0.93) -> mocka(version: base, ip: 172.17.0.90)-> mockb(version: base, ip: 172.17.0.93) -> mocka(version: base, ip: 172.17.0.90)-> mockb(version: base, ip: 172.17.0.93)Com o cabeçalho
my-asm-prefer-tagdefinido comoversion-base, 90% vão para a versão base por peso fixo e os 10% restantes também resolvem para a base por rótulo. O resultado é 100% de tráfego base.
Próximos passos
Aumente gradualmente o peso canário à medida que ganhar confiança na nova versão.
Para mais detalhes sobre a configuração de rotulagem de tráfego, consulte Rotule o tráfego.
Para liberações canário de um único serviço apenas com roteamento baseado em peso, consulte Implante um aplicativo no modo de implantação blue-green e no modo de liberação por fases.