Na comunicação entre microsserviços em uma malha, frequentemente é necessário direcionar requisições específicas para versões determinadas de um serviço — seja para canary releases, testes A/B ou isolamento de ambientes. A rotulagem de tráfego no Alibaba Cloud Service Mesh (ASM) anexa tags personalizadas às requisições conforme elas trafegam pela malha. Isso permite que regras de roteamento downstream, políticas de limitação e circuit breakers atuem com base nessas tags.
O ASM fornece a CustomResourceDefinition (CRD) TrafficLabel para definir regras de rotulagem. Ao aplicar um recurso TrafficLabel a um namespace ou a uma carga de trabalho específica, o ASM injeta automaticamente a lógica de rotulagem nos filtros do proxy Envoy.
Casos de uso
Canary releases -- Encaminhe uma porcentagem do tráfego para uma nova versão com base na correspondência de um valor de cabeçalho.
Testes A/B -- Divida o tráfego entre variantes usando regras de roteamento baseadas em rótulos.
Isolamento de ambientes -- Marque o tráfego como
stagingouproductione direcione-o aos backends correspondentes.
Pré-requisitos
Antes de começar, verifique se você tem:
Uma instância do ASM executando a versão 1.17 ou posterior
Um cluster Kubernetes associado à sua instância do ASM
O
kubectlconfigurado para conexão com o cluster
O ASM 1.17 introduziu a apiVersion: istio.alibabacloud.com/v1 para a CRD TrafficLabel. Se você configurou anteriormente o TrafficLabel em um cluster Container Service for Kubernetes (ACK) usando apiVersion: istio.alibabacloud.com/v1beta1, altere a apiVersion para istio.alibabacloud.com/v1 e reaplique o recurso. Para atualizar sua instância do ASM, consulte Atualizar uma instância do ASM. Para versões anteriores do ASM, abra um ticket para obter assistência.
Como funciona a rotulagem de tráfego
Um recurso TrafficLabel define dois elementos:
Escopo -- As cargas de trabalho a serem rotuladas (todas as cargas de um namespace ou um subconjunto selecionado por rótulos de pod).
Regras -- A origem da extração do valor do rótulo (cabeçalhos de requisição, rótulos de pod ou contexto de rastreamento).
Quando uma requisição entra em um gateway ou proxy sidecar, o proxy avalia as regras do TrafficLabel, resolve um valor de rótulo e o anexa como um novo cabeçalho nas requisições de saída. Os serviços downstream podem então usar esse cabeçalho para tomar decisões de roteamento.
Visão geral da estrutura da CRD
O esqueleto abaixo mostra o aninhamento dos campos do TrafficLabel:
apiVersion: istio.alibabacloud.com/v1
kind: TrafficLabel
metadata:
name: <label-name> # Name of this TrafficLabel resource
namespace: <namespace> # Namespace where this resource applies
spec:
workloadSelector: # (Optional) Omit to apply to all workloads in the namespace
labels:
<key>: <value> # Match workloads by label, e.g., app: productpage
rules:
- labels:
- name: <traffic-label-name> # Header name for the label (must follow HTTP header naming rules)
valueFrom:
- <variable-1> # Primary source for the label value
- <variable-2> # Fallback if variable-1 returns empty
Referência de campos
Spec
|
Campo |
Tipo |
Obrigatório |
Descrição |
|
|
Não |
Seleciona as cargas de trabalho a serem rotuladas. Se omitido, a rotulagem aplica-se a todas as cargas de trabalho no namespace. |
|
|
|
Sim |
Uma ou mais regras de rotulagem. |
WorkloadSelector
|
Campo |
Tipo |
Obrigatório |
Descrição |
|
|
map |
Não |
Pares chave-valor que correspondem aos rótulos da carga de trabalho. |
TrafficLabelRule
|
Campo |
Tipo |
Obrigatório |
Descrição |
|
|
Label[] |
Sim |
Os rótulos de tráfego a serem anexados. |
Label
|
Campo |
Tipo |
Obrigatório |
Descrição |
|
|
string |
Sim |
Nome do rótulo de tráfego. Deve seguir as convenções de nomenclatura de cabeçalhos de requisição HTTP. |
|
|
string[] |
Sim |
Lista ordenada de variáveis. O proxy as avalia em sequência e utiliza o primeiro resultado não vazio. Consulte Variáveis valueFrom. |
Variáveis valueFrom
O campo valueFrom aceita uma lista ordenada de variáveis. O proxy as avalia sequencialmente e usa o primeiro resultado não vazio como valor do rótulo.
As quatro variáveis dividem-se em dois grupos conforme o local de aplicação:
|
Variável |
Aplica-se a |
Origem do valor do rótulo |
|
|
Apenas gateways |
Cabeçalho da requisição de entrada no gateway |
|
|
Apenas proxies sidecar |
Cabeçalho da requisição de entrada, correlacionado ao longo da cadeia de chamadas por meio de um mapa de contexto |
|
|
Apenas proxies sidecar |
Cabeçalho da requisição de saída definido pela aplicação |
|
|
Gateways e proxies sidecar |
Rótulo de pod no gateway ou no pod da carga de trabalho |
Variável de gateway
$getInboundRequestHeader(headerName)
Lê o cabeçalho headerName da requisição de entrada no gateway. O gateway adiciona um novo cabeçalho de saída usando o nome do rótulo definido na CRD TrafficLabel como chave e o valor extraído como valor.
Se headerName estiver em branco, o gateway lê x-asm-prefer-tag por padrão.
Fluxo de dados:
Client request Gateway Upstream service
| | |
|-- headerName: tagValue ----->| |
| |-- userDefinedLabel: tagValue ---->|
| | |

Variáveis de proxy sidecar
$getExternalInboundRequestHeader(headerName, contextId)
Lê o cabeçalho headerName da requisição de entrada no proxy sidecar e armazena o valor em um mapa de contexto interno indexado por contextId. Esse mapa persiste por 30 segundos na memória do Envoy.
Parâmetros (ambos obrigatórios):
|
Parâmetro |
Descrição |
Exemplo |
|
|
Chave do cabeçalho de requisição a ser lida. |
|
|
|
Campo de cabeçalho que persiste ao longo da cadeia de chamadas, usado para correlacionar tráfego de entrada e saída. Geralmente é um ID de rastreamento. |
|
Funcionamento do mapa de contexto:
Uma requisição de entrada chega ao sidecar. O proxy lê
headerNamepara obtertagValuee armazenamap<contextId, tagValue>.Quando a aplicação inicia uma requisição de saída, o proxy consulta
contextIdno mapa de contexto.-
Se houver correspondência, o proxy adiciona dois cabeçalhos à requisição de saída:
headerName: tagValueuserDefinedLabel: tagValue(usando o nome do rótulo da CRD TrafficLabel)
Fluxo de dados:
Inbound request Sidecar proxy (context map) Outbound request
| | |
|-- headerName: tagValue | |
|-- contextId: ctx123 --->| store: ctx123 -> tagValue |
| | |
| App initiates outbound request |
| |-- contextId: ctx123 ----------->|
| | (lookup: ctx123 -> tagValue) |
| |-- headerName: tagValue -------->|
| |-- userDefinedLabel: tagValue -->|

O mapa de contexto (
map<contextId, tagValue>) permanece armazenado na memória do proxy Envoy por 30 segundos, por padrão.Se sua aplicação estiver conectada a um sistema de rastreamento, use o ID de rastreamento como
contextId. Sistemas diferentes utilizam IDs distintos. Para mais detalhes, consulte Tracing.As aplicações devem propagar os cabeçalhos HTTP relevantes para que os proxies Istio correlacionem spans em um rastreamento completo. Consulte Ativar rastreamento distribuído no ASM.
Caso a aplicação não propague o
contextId, o proxy sidecar não consegue recuperar o valor do rótulo no mapa de contexto e a requisição de saída não será rotulada.
$getLocalOutboundRequestHeader(headerName)
Lê o cabeçalho headerName da requisição de saída enviada pela aplicação ao proxy sidecar. O proxy adiciona um novo cabeçalho de saída usando o nome do rótulo da CRD TrafficLabel como chave e o valor extraído como valor.
Use esta variável quando a própria aplicação definir um cabeçalho em suas requisições de saída.
Fluxo de dados:
Application container Sidecar proxy Upstream service
| | |
|-- headerName: tagValue ----->| |
| |-- userDefinedLabel: tagValue -->|
| | |

Variável de rótulo de pod
$getLabel(labelName)
Lê o rótulo labelName do pod do gateway ou do pod da carga de trabalho sidecar e adiciona o valor ao tráfego de saída. Se labelName estiver em branco, o proxy lê o rótulo ASM_TRAFFIC_TAG por padrão.
Exemplo: Se um pod de Deployment tiver o rótulo ASM_TRAFFIC_TAG: test, a variável $getLabel(ASM_TRAFFIC_TAG) retorna test.
apiVersion: apps/v1
kind: Deployment
metadata:
name: productpage-v1
labels:
app: productpage
version: v1
spec:
replicas: 1
selector:
matchLabels:
app: productpage
version: v1
template:
metadata:
annotations:
sidecar.istio.io/logLevel: debug
labels:
app: productpage
version: v1
ASM_TRAFFIC_TAG: test # This value is read by $getLabel(ASM_TRAFFIC_TAG)
spec:
serviceAccountName: bookinfo-productpage
containers:
- name: productpage
image: docker.io/istio/examples-bookinfo-productpage-v1:1.16.2
imagePullPolicy: IfNotPresent
ports:
- containerPort: 9080
volumeMounts:
- name: tmp
mountPath: /tmp
volumes:
- name: tmp
emptyDir: {}
Rotular tráfego para uma carga de trabalho específica
Este exemplo rotula o tráfego da carga de trabalho productpage. O valor do rótulo é obtido do cabeçalho de requisição de entrada header1 (correlacionado por x-request-id), com fallback para o rótulo de pod header2.
Ambos os exemplos nesta página exigem ASM 1.17 ou posterior e utilizam a aplicação de exemplo Bookinfo.
Implante a aplicação Bookinfo. Consulte Implantar uma aplicação em uma instância do ASM.
-
Salve o YAML a seguir em
productpage-trafficlabel.yaml:apiVersion: istio.alibabacloud.com/v1 kind: TrafficLabel metadata: name: productpage namespace: default spec: workloadSelector: labels: app: productpage # Only applies to the productpage workload rules: - labels: - name: asm-labels-test-a # Outbound header name for the label valueFrom: - $getExternalInboundRequestHeader(header1, x-request-id) # Primary: read from inbound header - $getLabel(header2) # Fallback: read from pod label -
Aplique o recurso:
kubectl apply -n default -f productpage-trafficlabel.yaml -
Verifique se o filtro Envoy foi injetado no proxy
productpage: Procure pelo filtrocom.aliyun.traffic_labelemdynamic_listenersouhttp_filters:kubectl exec -it -n default deploy/productpage-v1 -c istio-proxy -- \ curl localhost:15000/config_dump{ "name": "com.aliyun.traffic_label", "typed_config": { "@type": "type.googleapis.com/envoy.config.filter.traffic_label.v3alpha.TrafficLabel", ... } } -
Confirme que as cargas de trabalho não selecionadas não foram afetadas. Execute a mesma verificação no pod
details: Um resultado vazio confirma que nenhum filtro de rotulagem foi injetado, conforme esperado.kubectl exec -it -n default deploy/details-v1 -c istio-proxy -- \ curl localhost:15000/config_dump | grep traffic_label
Rotular tráfego no nível de namespace
Omita workloadSelector para rotular o tráfego de todas as cargas de trabalho em um namespace. Este exemplo rotula todas as cargas de trabalho no namespace default.
-
Salve o YAML a seguir em
all-workload-for-ns-trafficlabel.yaml:apiVersion: istio.alibabacloud.com/v1 kind: TrafficLabel metadata: name: all-workload-for-ns namespace: default spec: rules: # No workloadSelector -- applies to every workload in "default" - labels: - name: asm-labels-test-b valueFrom: - $getExternalInboundRequestHeader(header1, x-request-id) - $getLabel(header2) -
Aplique o recurso:
kubectl apply -n default -f all-workload-for-ns-trafficlabel.yaml -
Verifique se o filtro de rotulagem está presente em todas as cargas de trabalho. Verifique o pod
details: Saída esperada: O filtro agora está injetado em todas as cargas de trabalho do namespace.kubectl exec -it -n default deploy/details-v1 -c istio-proxy -- \ curl localhost:15000/config_dump | grep traffic_label"@type": "type.googleapis.com/envoy.config.filter.traffic_label.v3alpha.TrafficLabel",
Tópicos relacionados
Implantar uma aplicação em uma instância do ASM -- Configure as cargas de trabalho na malha antes de definir rótulos de tráfego.
Ativar rastreamento distribuído no ASM -- Propague os cabeçalhos de rastreamento necessários para
$getExternalInboundRequestHeader.Atualizar uma instância do ASM -- Atualize para o ASM 1.17+ caso esteja em uma versão anterior.