Na comunicação entre microsserviços em uma malha, muitas vezes é necessário direcionar requisições específicas para versões específicas de um service — seja em lançamentos canário, testes A/B ou isolamento de ambientes. A rotulagem de tráfego no Alibaba Cloud Service Mesh (ASM) anexa tags personalizadas às requisições enquanto elas transitam pela malha, permitindo que regras de roteamento downstream, políticas de throttling e circuit breakers atuem com base nessas tags.
O ASM disponibiliza o CustomResourceDefinition (CRD) TrafficLabel para definir regras de rotulagem. Aplique um recurso TrafficLabel a um namespace ou a um workload específico, e o ASM injeta automaticamente a lógica de rotulagem nos filtros do proxy Envoy.
Casos de uso
Lançamentos canário — Direcione 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 utilizando regras de roteamento baseadas em rótulos.
Isolamento de ambientes — Identifique o tráfego como
stagingouproductione encaminhe-o para os backends correspondentes.
Pré-requisitos
Antes de começar, certifique-se de ter:
Uma instância do ASM na versão 1,17 ou posterior
Um cluster Kubernetes associado à sua instância do ASM
kubectlconfigurado para conectar-se ao cluster
O ASM 1.17 introduziu apiVersion: istio.alibabacloud.com/v1 para o CRD TrafficLabel. Se você configurou anteriormente o TrafficLabel em um cluster Container Service for Kubernetes (ACK) usando apiVersion: istio.alibabacloud.com/v1beta1, altere o apiVersion para istio.alibabacloud.com/v1 e reaplique o recurso. Para atualizar sua instância do ASM, consulte Update an ASM instance. Para versões anteriores do ASM, envie um ticket para obter assistência.
Como funciona a rotulagem de tráfego
Um recurso TrafficLabel define duas coisas:
Escopo — Quais workloads rotular (todos os workloads de um namespace ou um subconjunto selecionado por rótulos de pod).
Regras — De onde extrair o 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 do CRD
O esqueleto a seguir mostra como os campos do TrafficLabel se organizam:
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 os workloads a rotular. Se omitido, a rotulagem se aplica a todos os workloads do namespace. |
|
|
|
Sim |
Uma ou mais regras de rotulagem. |
WorkloadSelector
|
Campo |
Tipo |
Obrigatório |
Descrição |
|
|
map |
Não |
Pares de chave-valor correspondentes aos rótulos dos workloads. |
TrafficLabelRule
|
Campo |
Tipo |
Obrigatório |
Descrição |
|
|
Label[] |
Sim |
Os rótulos de tráfego a anexar. |
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 usa o primeiro resultado não vazio. Consulte valueFrom variables. |
Variáveis de valueFrom
O campo valueFrom aceita uma lista ordenada de variáveis. O proxy as avalia em sequência e usa o primeiro resultado não vazio como valor do rótulo.
As quatro variáveis se dividem em dois grupos, de acordo com o local onde se aplicam:
|
Variável |
Aplica-se a |
Origem do valor do rótulo |
|
|
Somente gateways |
Cabeçalho da requisição de entrada no gateway |
|
|
Somente proxies sidecar |
Cabeçalho da requisição de entrada, correlacionado ao longo da cadeia de chamadas por meio de um mapa de contexto |
|
|
Somente 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 do workload |
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 no CRD TrafficLabel como chave e o valor extraído como valor.
Se headerName ficar 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 permanece na memória do Envoy por 30 segundos.
Parâmetros (ambos obrigatórios):
|
Parâmetro |
Descrição |
Exemplo |
|
|
Chave do cabeçalho de requisição a ser lido. |
|
|
|
Campo de cabeçalho persistente ao longo da cadeia de chamadas, usado para correlacionar tráfego de entrada e saída. Normalmente, um ID de rastreamento. |
|
Como o mapa de contexto funciona:
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 do 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>) fica armazenado na memória do proxy Envoy por 30 segundos, por padrão.Quando a aplicação está conectada a um sistema de rastreamento, use o ID de rastreamento como
contextId. Cada sistema de rastreamento utiliza um ID de rastreamento diferente. Para mais detalhes, consulte Tracing.As aplicações devem propagar os cabeçalhos HTTP relevantes para que os proxies do Istio correlacionem spans em um rastreamento completo. Consulte Enable distributed tracing in ASM.
Se a aplicação não propagar
contextId, o proxy sidecar não conseguirá consultar o valor do rótulo no mapa de contexto, e a requisição de saída não receberá o rótulo.
$getLocalOutboundRequestHeader(headerName)
Lê o cabeçalho headerName da requisição de saída que a aplicação envia ao proxy sidecar. O proxy adiciona um novo cabeçalho de saída usando o nome do rótulo do CRD TrafficLabel como chave e o valor extraído como valor.
Use essa variável quando a própria aplicação defina 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 do workload 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 possui 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 um workload específico
Este exemplo rotula o tráfego do workload productpage. O valor do rótulo é resolvido a partir do cabeçalho da requisição de entrada header1 (correlacionado por x-request-id), com fallback para o rótulo de pod header2.
Ambos os exemplos desta página exigem ASM 1.17 ou posterior e utilizam o aplicativo de exemplo Bookinfo.
Implante o aplicativo Bookinfo. Consulte Deploy an application in an ASM instance.
-
Salve o YAML a seguir no arquivo
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 do
productpage: procure o 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 os workloads não selecionados não foram afetados. Execute a mesma verificação no pod
details: um resultado vazio confirme que nenhum filtro de rotulagem foi injetado, como 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 do namespace
Omita workloadSelector para rotular o tráfego de todos os workloads em um namespace. Este exemplo rotula todos os workloads no namespace default.
-
Salve o YAML a seguir no arquivo
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 agora está presente em todos os workloads. Confira o pod
details: a saída esperada indica que o filtro foi injetado em todos os workloads 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
Deploy an application in an ASM instance — Configure workloads na sua malha antes de definir rótulos de tráfego.
Enable distributed tracing in ASM — Propague os cabeçalhos de rastreamento exigidos por
$getExternalInboundRequestHeader.Update an ASM instance — Atualize para o ASM 1.17+ caso esteja em uma versão anterior.