All Products
Search
Document Center

Alibaba Cloud Service Mesh:Route traffic by labels

Last Updated:Mar 11, 2026

When multiple versions of a service run side by side -- for example, a stable baseline and one or more canary deployments -- you need a way to send each request to the correct version. Service Mesh (ASM) solves this with traffic labels: custom HTTP headers that the TrafficLabel CustomResourceDefinition (CRD) attaches to requests. You define routing rules that match these headers and direct traffic to the corresponding workload version.

Label-based routing relies on two Istio resources that work together:

  • DestinationRule -- Groups workload instances into named subsets. Each subset selects Pods by Kubernetes labels (typically a version label). This resource defines *where* traffic can go.

  • VirtualService -- Evaluates routing rules top to bottom and sends each request to the first matching subset. A catch-all route at the end handles unmatched traffic. This resource defines *which* traffic goes *where*.

Routing rules are evaluated sequentially from top to bottom. The first rule that matches a request wins, and subsequent rules are skipped. Always place a default route at the end to catch unmatched traffic.

Core example

The following minimal configuration routes requests with the header asm-labels-test: test1 to the test1 subset, and sends all other requests to the base subset:

# DestinationRule: define the subsets
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: dr-productpage
spec:
  host: productpage
  subsets:
  - name: test1
    labels:
      version: test1
  - name: base
    labels:
      version: base
---
# VirtualService: route by header value
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: vs-productpage
spec:
  hosts:
    - productpage
  http:
  - match:
    - headers:
        asm-labels-test:
         exact: test1
    route:
    - destination:
        host: productpage
        subset: test1
  - route:
    - destination:
        host: productpage
        subset: base

Apply both resources:

kubectl apply -f dr-productpage.yaml
kubectl apply -f vs-productpage.yaml

Verify the routing:

# Request with label header goes to test1 subset
curl -H "asm-labels-test: test1" http://<productpage-url>

# Request without the header goes to base subset
curl http://<productpage-url>

For more subsets and advanced configurations, see the sections below.

Prerequisites

Before you begin, make sure that you have:

  • Traffic labels configured through the TrafficLabel CRD. For details, see Label traffic

Create a destination rule

A destination rule defines the available subsets for a service. Each subset maps to a group of Pods identified by a Kubernetes label.

  1. Create a file named dr-productpage.yaml with the following content.

    This example defines subsets test1, test2, test3, and base for the productpage service. Each subset selects Pods whose version label matches the subset name:

    apiVersion: networking.istio.io/v1alpha3
    kind: DestinationRule
    metadata:
      name: dr-productpage
    spec:
      host: productpage
      subsets:
      - name: test1
        labels:
          version: test1
      - name: test2
        labels:
          version: test2
      - name: test3
        labels:
          version: test3
      ...
      - name: testn
        labels:
          version: testn
      - name: base
        labels:
          version: base
  2. Apply the destination rule:

    kubectl apply -f dr-productpage.yaml

Create a virtual service

A virtual service defines the routing logic. Each rule matches requests by header value and routes them to the corresponding subset. Rules are evaluated top to bottom -- the first match wins.

  1. Create a file named vs-productpage.yaml with the following content.

    In this example, a request with asm-labels-test: test1 goes to the test1 subset, one with test2 goes to test2, and so on. The final route without a match block catches all remaining requests and sends them to the base subset:

    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: vs-productpage
    spec:
      hosts:
        - productpage
      http:
      - match:
        - headers:
            asm-labels-test:
             exact: test1
        route:
        - destination:
            host: productpage
            subset: test1
      - match:
        - headers:
            asm-labels-test:
             exact: test2
        route:
        - destination:
            host: productpage
            subset: test2
      - match:
        - headers:
            asm-labels-test:
             exact: test3
        route:
        - destination:
            host: productpage
            subset: test3
      - route:
        - destination:
            host: productpage
            subset: base

    The following table describes the key fields:

    Field

    Description

    match.headers.asm-labels-test

    The traffic label name to match against

    match.headers.exact

    The exact traffic label value required for a match

    route.destination.subset

    The destination subset that receives matching traffic

  2. Apply the virtual service:

    kubectl apply -f vs-productpage.yaml

Verify the routing rules

After you apply both resources, confirm that traffic routes correctly:

# Confirm the resources exist
kubectl get destinationrule dr-productpage
kubectl get virtualservice vs-productpage

# Send a test request with a traffic label header
# Replace <productpage-url> with your service URL
curl -H "asm-labels-test: test1" http://<productpage-url>

The request with asm-labels-test: test1 should reach a Pod in the test1 subset. Test with other header values (test2, test3) to confirm each subset receives the expected traffic. A request without the asm-labels-test header should fall through to the base subset.

Header-based routing depends on each service in the call chain forwarding the traffic label header. If an intermediate service drops the header, downstream routing rules silently fail. Make sure that your application or the ASM sidecar propagates the asm-labels-test header end to end.

Simplify the virtual service with variable syntax

When many workload versions exist, listing a match block for each one makes the virtual service verbose. Replace the explicit matches with the $asm-labels-test variable syntax. ASM resolves the variable at runtime and routes traffic to the subset whose name matches the header value. If the target subset is unavailable, traffic shifts to other available versions:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: vs-productpage
spec:
  hosts:
    - productpage
  http:
  - route:
    - destination:
        host: productpage
        subset: $asm-labels-test

Configure fallback routing

With ASM Enterprise Edition, traffic automatically falls back to a backup service when the target subset is unavailable -- for example, when the subset is not defined or no matching Pod exists.

Specify the backup target with the fallback field under route:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: vs-productpage
spec:
  hosts:
    - productpage
  http:
  - route:
    - destination:
        host: productpage
        subset: $asm-labels-test
      fallback:
        target:
          host: productpage
          subset: base

The following table describes the fallback fields:

Field

Description

target.host

The service to receive fallback traffic

target.subset

The subset to receive fallback traffic

Related information

  • Label traffic -- Configure traffic labels with the TrafficLabel CRD