No roteamento estático de subconjuntos, cada DestinationRule precisa listar explicitamente todos os subconjuntos. Sempre que uma nova versão é lançada ou uma antiga descontinuada, a regra exige atualização manual. O roteamento dinâmico de subconjuntos elimina essa sobrecarga: o Service Mesh (ASM) monitora os rótulos das cargas de trabalho e agrupa os endpoints em subconjuntos automaticamente, mantendo as regras de roteamento atualizadas sem alterações manuais.
O exemplo de ponta a ponta abaixo implanta uma aplicação com múltiplas versões, direciona requisições para versões e ambientes específicos com base em cabeçalhos HTTP e configura um comportamento de fallback quando o subconjunto de destino não existe.
Como funcionam os subconjuntos dinâmicos
No roteamento padrão do Istio, uma DestinationRule enumera cada subconjunto com um conjunto fixo de rótulos. Quando as versões mudam, a regra deve ser atualizada para corresponder à nova realidade.
Os subconjuntos dinâmicos adotam uma abordagem diferente. Em vez de listar cada subconjunto, especifique uma ou mais chaves de agrupamento (por exemplo, version e stage). O ASM inspeciona os rótulos de cada endpoint associado a um serviço e agrupa automaticamente os endpoints que compartilham a mesma combinação de chave-valor no mesmo subconjunto.
Em seguida, uma VirtualService mapeia os cabeçalhos das requisições recebidas para essas chaves de agrupamento. Por exemplo, uma requisição contendo x-version: v2 e x-stage: prod é roteada para o subconjunto onde version=v2 e stage=prod.
Pré-requisitos
Antes de começar, certifique-se de ter:
Uma instância do ASM na versão 1,18 ou posterior
Um cluster do Container Service for Kubernetes (ACK) adicionado à instância do ASM
kubectl configurado com o arquivo kubeconfig do cluster ACK
Etapa 1: Implantar a aplicação de exemplo
Este exemplo utiliza hashicorp/http-echo para simular uma implantação com múltiplos ambientes e versões:
Ambiente dev: versões v1, v2, v3
Ambiente prod: versões v2, v3
Cada pod responde com seu ambiente, versão e endereço IP. Um Service helloworld na porta 8000 atua como frontend para todos os pods, e um Deployment sleep fornece um cliente para testes.

Implante todos os recursos com kubectl. Para mais informações, consulte Implantar uma aplicação em um cluster ACK adicionado a uma instância do ASM.
Etapa 2: Roteamento de requisições para uma versão e ambiente específicos
Após a implantação, o Kubernetes balanceia a carga das requisições entre todos os pods do helloworld, independentemente da versão ou do ambiente. Para direcionar o tráfego a uma combinação específica, crie uma DestinationRule que defina as chaves de agrupamento e uma VirtualService que mapeie os cabeçalhos das requisições para essas chaves.
Criar a DestinationRule
Aplique a seguinte DestinationRule para agrupar endpoints por stage e version. Para mais informações, consulte Gerenciar regras de destino.
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: helloworld
namespace: default
spec:
host: helloworld.default.svc.cluster.local
trafficPolicy:
loadBalancer:
dynamicSubset:
subsetSelectors:
- keys:
- stage
- version
O ASM lê os rótulos stage e version de cada endpoint e gera os seguintes subconjuntos:
|
Subconjunto |
Pod |
Endereço IP |
|
stage=dev, version=v1 |
helloworld-dev-v1-67b6876778-nf7pz |
192.168.0.5 |
|
stage=dev, version=v2 |
helloworld-dev-v2-68f65bbc99-v957l |
192.168.0.1 |
|
stage=dev, version=v3 |
helloworld-dev-v3-7f6978bc56-hqzgg |
192.168.0.252 |
|
stage=prod, version=v2 |
helloworld-prod-v2-b5745b949-p8rc4 |
192.168.0.103 |
|
stage=prod, version=v3 |
helloworld-prod-v3-6768bf56f8-6bd6h |
192.168.0.104, 192.168.0.6 |
Criar a VirtualService
Aplique a seguinte VirtualService para mapear cabeçalhos HTTP nas chaves de subconjunto dinâmico. Para mais informações, consulte Gerenciar serviços virtuais.
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: helloworld
namespace: default
spec:
hosts:
- helloworld.default.svc.cluster.local
http:
- headerToDynamicSubsetKey:
- header: x-version # Map the x-version header to the "version" grouping key
key: version
defaultValue: v3 # Fall back to v3 if the header is absent
- header: x-stage # Map the x-stage header to the "stage" grouping key
key: stage
defaultValue: prod # Fall back to prod if the header is absent
name: default
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 8000
Esta VirtualService estabelece dois mapeamentos:
Do cabeçalho
x-versionpara a chave de agrupamentoversion. Padrão:v3quando o cabeçalho estiver ausente.Do cabeçalho
x-stagepara a chave de agrupamentostage. Padrão:prodquando o cabeçalho estiver ausente.
Verificar o roteamento
Envie uma requisição direcionada ao ambiente dev, versão v1:
kubectl exec -it deploy/sleep -c sleep -- curl -H 'x-stage: dev' -H 'x-version: v1' helloworld:8000
Saída esperada:
Welcome to helloworld stage: dev, version: v1, ip: 192.168.0.5
A requisição atinge o pod onde stage=dev e version=v1, confirmando que o roteamento dinâmico de subconjuntos funciona corretamente.
Etapa 3: Configurar políticas de fallback
A versão v1 não existe no ambiente prod. Uma requisição direcionada a stage=prod, version=v1 não corresponde a nenhum subconjunto:
kubectl exec -it deploy/sleep -c sleep -- curl -H 'x-stage: prod' -H 'x-version: v1' helloworld:8000
# Output: no healthy upstream
Para lidar com subconjuntos não correspondidos, defina uma fallbackPolicy na DestinationRule. O ASM suporta três políticas:
|
Política |
Comportamento |
Recomendada para |
|
|
Retorna um erro |
Roteamento estrito, onde requisições mal direcionadas devem falhar rapidamente |
|
|
Roteia para qualquer endpoint disponível em todos os subconjuntos |
Desenvolvimento ou testes, onde a disponibilidade é mais importante que a precisão |
|
|
Roteia para um subconjunto padrão pré-configurado |
Cargas de trabalho em produção, onde requisições sem correspondência devem ser direcionadas a uma versão estável conhecida |
NO_FALLBACK
NO_FALLBACK é o comportamento padrão. Requisições que não correspondem a nenhum subconjunto retornam um erro. Defina-a explicitamente para deixar clara a intenção de falha rápida.
Aplique a seguinte DestinationRule. Para mais informações, consulte Gerenciar regras de destino.
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: helloworld
namespace: default
spec:
host: helloworld.default.svc.cluster.local
trafficPolicy:
loadBalancer:
dynamicSubset:
subsetSelectors:
- fallbackPolicy: NO_FALLBACK
keys:
- stage
- version
Verifique:
kubectl exec -it deploy/sleep -c sleep -- curl -H 'x-stage: prod' -H 'x-version: v1' helloworld:8000
Saída esperada:
no healthy upstream
ANY_ENDPOINT
Quando nenhum subconjunto corresponde, as requisições são roteadas para qualquer endpoint disponível, independentemente dos rótulos.
Aplique a seguinte DestinationRule. Para mais informações, consulte Gerenciar regras de destino.
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: helloworld
namespace: default
spec:
host: helloworld.default.svc.cluster.local
trafficPolicy:
loadBalancer:
dynamicSubset:
subsetSelectors:
- fallbackPolicy: ANY_ENDPOINT
keys:
- stage
- version
Verifique enviando duas requisições. Cada uma pode atingir um pod diferente:
# First request
kubectl exec -it deploy/sleep -c sleep -- curl -H 'x-stage: prod' helloworld:8000
Exemplo de saída:
Welcome to helloworld stage: prod, version: v2, ip: 192.168.0.103
# Second request -- targets a non-existent subset
kubectl exec -it deploy/sleep -c sleep -- curl -H 'x-stage: prod' -H 'x-version: v1' helloworld:8000
Exemplo de saída:
Welcome to helloworld stage: dev, version: v2, ip: 192.168.0.1
Como não existe nenhum subconjunto prod/v1, a requisição recorre a um endpoint aleatório.
DEFAULT_SUBSET
Quando nenhum subconjunto corresponde, as requisições são roteadas para o subconjunto definido em defaultSubset. Esta é a política recomendada para cargas de trabalho em produção, pois requisições sem correspondência são direcionadas a uma versão estável conhecida, em vez de falhar ou ser distribuídas aleatoriamente.
Aplique a seguinte DestinationRule. Neste exemplo, defaultSubset aponta para stage=prod, version=v3. Para mais informações, consulte Gerenciar regras de destino.
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: helloworld
namespace: default
spec:
host: helloworld.default.svc.cluster.local
trafficPolicy:
loadBalancer:
dynamicSubset:
defaultSubset:
stage: prod
version: v3
subsetSelectors:
- fallbackPolicy: DEFAULT_SUBSET
keys:
- stage
- version
Verifique enviando duas requisições para o subconjunto inexistente prod/v1:
kubectl exec -it deploy/sleep -c sleep -- curl -H 'x-stage: prod' -H 'x-version: v1' helloworld:8000
Saída esperada:
Welcome to helloworld stage: prod, version: v3, ip: 192.168.0.6
kubectl exec -it deploy/sleep -c sleep -- curl -H 'x-stage: prod' -H 'x-version: v1' helloworld:8000
Saída esperada:
Welcome to helloworld stage: prod, version: v3, ip: 192.168.0.104
Ambas as requisições atingem o subconjunto padrão prod/v3. Os dois IPs diferentes (192.168.0.6 e 192.168.0.104) refletem o balanceamento de carga entre as duas réplicas prod-v3.
Etapa 4: Roteamento para um pod específico por endereço IP
Para fixar requisições em um pod individual, use o atributo integrado %ip% como chave de agrupamento. Cada pod se torna seu próprio subconjunto de membro único.
Criar a DestinationRule
Aplique a seguinte DestinationRule para agrupar pods por endereço IP. Para mais informações, consulte Gerenciar regras de destino.
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: helloworld
namespace: default
spec:
host: helloworld.default.svc.cluster.local
trafficPolicy:
loadBalancer:
dynamicSubset:
defaultSubset:
stage: prod
version: v3
subsetSelectors:
- keys:
- '%ip%'
Criar a VirtualService
Mapeie o cabeçalho x-ip para a chave %ip% para que o valor do cabeçalho especifique o IP do pod de destino. Para mais informações, consulte Gerenciar serviços virtuais.
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: helloworld
namespace: default
spec:
hosts:
- helloworld.default.svc.cluster.local
http:
- headerToDynamicSubsetKey:
- header: x-ip
key: '%ip%'
name: default
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 8000
Verificar o roteamento
Envie múltiplas requisições direcionadas ao IP do pod 192.168.0.6:
kubectl exec -it deploy/sleep -c sleep -- curl -H 'x-ip: 192.168.0.6' helloworld:8000
Saída esperada (consistente em chamadas repetidas):
Welcome to helloworld stage: prod, version: v3, ip: 192.168.0.6
Todas as requisições atingem o mesmo pod, confirmando a fixação baseada em IP.
Referência de campos CRD
VirtualService
HTTPRoute
O ASM estende o recurso HTTPRoute com o campo headerToDynamicSubsetKey.
|
Campo |
Tipo |
Descrição |
|
|
HeaderToMetadataSubsetKey[] |
Mapeia cabeçalhos de requisição para chaves de agrupamento de subconjuntos dinâmicos. Cada elemento define um mapeamento de cabeçalho para chave. |
HeaderToMetadataSubsetKey
|
Campo |
Tipo |
Descrição |
|
|
string |
Nome do cabeçalho da requisição. |
|
|
string |
Nome da chave de agrupamento do subconjunto dinâmico. Um valor entre sinais de porcentagem (por exemplo, |
|
|
string |
Valor usado quando a requisição não contém o cabeçalho especificado. Se omitido e o cabeçalho estiver ausente, a chave fica indefinida e é excluída da correspondência de subconjuntos. |
DestinationRule
O ASM estende a estrutura trafficPolicy com o campo dynamicSubset.
TrafficPolicy
|
Campo |
Tipo |
Descrição |
|
|
DynamicSubsetLB |
Configura regras de agrupamento de subconjuntos dinâmicos. |
DynamicSubsetLB
|
Campo |
Tipo |
Descrição |
|
|
map[string]string |
Subconjunto padrão usado quando |
|
|
SubsetSelector[] |
Lista de regras de agrupamento. Cada elemento define uma dimensão de agrupamento separada. |
|
|
DynamicSubsetLB_FallbackPolicy |
Política de fallback global quando nenhum subconjunto corresponde. O padrão é |
SubsetSelector
|
Campo |
Tipo |
Descrição |
|
|
string[] |
Dimensões de agrupamento mapeadas para rótulos de carga de trabalho. Por exemplo, |
|
|
DynamicSubsetLB_FallbackPolicy |
Política de fallback para esta regra de agrupamento específica. Substitui a política definida em DynamicSubsetLB. |
DynamicSubsetLB_FallbackPolicy
|
Valor |
Descrição |
|
|
Retorna um erro quando nenhum subconjunto corresponde. Este é o padrão. |
|
|
Roteia para qualquer endpoint do serviço quando nenhum subconjunto corresponde. |
|
|
Roteia para o subconjunto definido em |
Atributos integrados da carga de trabalho
|
Atributo |
Tipo |
Descrição |
|
|
string |
Endereço IP do pod onde a carga de trabalho está em execução. |
Veja também
Ativar coleta de logs do plano de controle e alertas baseados em logs
Configurar alertas de auditoria para operações em recursos do ASM
Usar regras de tráfego para configurar faixas de tráfego e deslocamento de tráfego
Verificar o recurso de roteamento consciente de zona na topologia de uma instância do ASM