All Products
Search
Document Center

Alibaba Cloud Service Mesh:Scenario 3: Propagate baggage headers

Last Updated:Jun 20, 2026

You can use traffic lanes in permissive mode to isolate application versions. This process propagates a routing request header in baggage headers to route traffic to different lanes. When services within a traffic lane call each other, if the target service does not exist in the current lane, the request is forwarded to the baseline lane. This ensures call chain integrity and simplifies traffic management.

Important

Before you begin, read and understand Use traffic lanes in permissive mode to manage end-to-end traffic and its related content.

Scenario overview

This example simulates a call chain with three services (mocka, mockb, and mockc) and three traffic lanes (s1, s2, and s3). First, you will use OpenTelemetry auto-instrumentation to enable baggage header propagation for the services. Then, you will create three traffic lanes in permissive mode and guide traffic by using a weight-based routing policy.

Step 1: Deploy the sample services

  1. Enable automatic sidecar proxy injection for the default namespace. For more information, see Manage global namespaces.

    Note

    For more information about automatic injection, see Configure sidecar injection policies.

  2. Create a file named mock.yaml with the following content.

    mock.yaml content

    apiVersion: v1
    kind: Service
    metadata:
      name: mocka
      labels:
        app: mocka
        service: mocka
    spec:
      ports:
      - port: 8000
        name: http
      selector:
        app: mocka
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: mocka-v1
      labels:
        app: mocka
        version: v1
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: mocka
          version: v1
          ASM_TRAFFIC_TAG: v1
      template:
        metadata:
          labels:
            app: mocka
            version: v1
            ASM_TRAFFIC_TAG: v1
          annotations:
            instrumentation.opentelemetry.io/inject-java: "true"
            instrumentation.opentelemetry.io/container-names: "default"
        spec:
          containers:
          - name: default
            image: registry-cn-hangzhou.ack.aliyuncs.com/acs/asm-mock:v0.1-java
            imagePullPolicy: IfNotPresent
            env:
            - name: version
              value: v1
            - name: app
              value: mocka
            - name: upstream_url
              value: "http://mockb:8000/"
            ports:
            - containerPort: 8000
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: mockb
      labels:
        app: mockb
        service: mockb
    spec:
      ports:
      - port: 8000
        name: http
      selector:
        app: mockb
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: mockb-v1
      labels:
        app: mockb
        version: v1
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: mockb
          version: v1
          ASM_TRAFFIC_TAG: v1
      template:
        metadata:
          labels:
            app: mockb
            version: v1
            ASM_TRAFFIC_TAG: v1
          annotations:
            instrumentation.opentelemetry.io/inject-java: "true"
            instrumentation.opentelemetry.io/container-names: "default"
        spec:
          containers:
          - name: default
            image: registry-cn-hangzhou.ack.aliyuncs.com/acs/asm-mock:v0.1-java
            imagePullPolicy: IfNotPresent
            env:
            - name: version
              value: v1
            - name: app
              value: mockb
            - name: upstream_url
              value: "http://mockc:8000/"
            ports:
            - containerPort: 8000
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: mockc
      labels:
        app: mockc
        service: mockc
    spec:
      ports:
      - port: 8000
        name: http
      selector:
        app: mockc
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: mockc-v1
      labels:
        app: mockc
        version: v1
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: mockc
          version: v1
          ASM_TRAFFIC_TAG: v1
      template:
        metadata:
          labels:
            app: mockc
            version: v1
            ASM_TRAFFIC_TAG: v1
          annotations:
            instrumentation.opentelemetry.io/inject-java: "true"
            instrumentation.opentelemetry.io/container-names: "default"
        spec:
          containers:
          - name: default
            image: registry-cn-hangzhou.ack.aliyuncs.com/acs/asm-mock:v0.1-java
            imagePullPolicy: IfNotPresent
            env:
            - name: version
              value: v1
            - name: app
              value: mockc
            ports:
            - containerPort: 8000
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: mocka-v2
      labels:
        app: mocka
        version: v2
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: mocka
          version: v2
          ASM_TRAFFIC_TAG: v2
      template:
        metadata:
          labels:
            app: mocka
            version: v2
            ASM_TRAFFIC_TAG: v2
          annotations:
            instrumentation.opentelemetry.io/inject-java: "true"
            instrumentation.opentelemetry.io/container-names: "default"
        spec:
          containers:
          - name: default
            image: registry-cn-hangzhou.ack.aliyuncs.com/acs/asm-mock:v0.1-java
            imagePullPolicy: IfNotPresent
            env:
            - name: version
              value: v2
            - name: app
              value: mocka
            - name: upstream_url
              value: "http://mockb:8000/"
            ports:
            - containerPort: 8000
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: mockb-v2
      labels:
        app: mockb
        version: v2
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: mockb
          version: v2
          ASM_TRAFFIC_TAG: v2
      template:
        metadata:
          labels:
            app: mockb
            version: v2
            ASM_TRAFFIC_TAG: v2
          annotations:
            instrumentation.opentelemetry.io/inject-java: "true"
            instrumentation.opentelemetry.io/container-names: "default"
        spec:
          containers:
          - name: default
            image: registry-cn-hangzhou.ack.aliyuncs.com/acs/asm-mock:v0.1-java
            imagePullPolicy: IfNotPresent
            env:
            - name: version
              value: v2
            - name: app
              value: mockb
            - name: upstream_url
              value: "http://mockc:8000/"
            ports:
            - containerPort: 8000
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: mockc-v2
      labels:
        app: mockc
        version: v2
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: mockc
          version: v2
          ASM_TRAFFIC_TAG: v2
      template:
        metadata:
          labels:
            app: mockc
            version: v2
            ASM_TRAFFIC_TAG: v2
          annotations:
            instrumentation.opentelemetry.io/inject-java: "true"
            instrumentation.opentelemetry.io/container-names: "default"
        spec:
          containers:
          - name: default
            image: registry-cn-hangzhou.ack.aliyuncs.com/acs/asm-mock:v0.1-java
            imagePullPolicy: IfNotPresent
            env:
            - name: version
              value: v2
            - name: app
              value: mockc
            ports:
            - containerPort: 8000
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: mocka-v3
      labels:
        app: mocka
        version: v3
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: mocka
          version: v3
          ASM_TRAFFIC_TAG: v3
      template:
        metadata:
          labels:
            app: mocka
            version: v3
            ASM_TRAFFIC_TAG: v3
          annotations:
            instrumentation.opentelemetry.io/inject-java: "true"
            instrumentation.opentelemetry.io/container-names: "default"
        spec:
          containers:
          - name: default
            image: registry-cn-hangzhou.ack.aliyuncs.com/acs/asm-mock:v0.1-java
            imagePullPolicy: IfNotPresent
            env:
            - name: version
              value: v3
            - name: app
              value: mocka
            - name: upstream_url
              value: "http://mockb:8000/"
            ports:
            - containerPort: 8000
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: mockb-v3
      labels:
        app: mockb
        version: v3
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: mockb
          version: v3
          ASM_TRAFFIC_TAG: v3
      template:
        metadata:
          labels:
            app: mockb
            version: v3
            ASM_TRAFFIC_TAG: v3
          annotations:
            instrumentation.opentelemetry.io/inject-java: "true"
            instrumentation.opentelemetry.io/container-names: "default"
        spec:
          containers:
          - name: default
            image: registry-cn-hangzhou.ack.aliyuncs.com/acs/asm-mock:v0.1-java
            imagePullPolicy: IfNotPresent
            env:
            - name: version
              value: v3
            - name: app
              value: mockb
            - name: upstream_url
              value: "http://mockc:8000/"
            ports:
            - containerPort: 8000
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: mockc-v3
      labels:
        app: mockc
        version: v3
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: mockc
          version: v3
          ASM_TRAFFIC_TAG: v3
      template:
        metadata:
          labels:
            app: mockc
            version: v3
            ASM_TRAFFIC_TAG: v3
          annotations:
            instrumentation.opentelemetry.io/inject-java: "true"
            instrumentation.opentelemetry.io/container-names: "default"
        spec:
          containers:
          - name: default
            image: registry-cn-hangzhou.ack.aliyuncs.com/acs/asm-mock:v0.1-java
            imagePullPolicy: IfNotPresent
            env:
            - name: version
              value: v3
            - name: app
              value: mockc
            ports:
            - containerPort: 8000

    These annotations declare that the service is a Java application and instruct the OpenTelemetry Operator to perform auto-instrumentation on the container named default.

  3. Run the following command to deploy the sample services.

    kubectl apply -f mock.yaml

    OpenTelemetry auto-instrumentation enables the deployed service pods to automatically propagate baggage headers across the call chain.

Step 2: Create a lane group and its traffic lanes

  1. Create a lane group.

    1. Log on to the ASM console. In the left-side navigation pane, choose Service Mesh > Mesh Management.

    2. On the Mesh Management page, click the name of the ASM instance. In the left-side navigation pane, choose Traffic Management Center > Traffic Lane.

    3. On the Traffic Lane page, click Create Swimlane Group. In the Create Swimlane Group panel, configure the parameters and click OK.

      Parameter

      Description

      Name of swim lane group

      Enter test.

      Entrance gateway

      Select ingressgateway.

      Lane Mode

      Select Permissive Mode.

      Pass-through Mode of Trace Context

      Select Pass Through Baggage Header.

      Routing Request Header

      Enter x-asm-prefer-tag.

      Swimlane Services

      Select the target Kubernetes cluster and the default namespace. In the list of services, select mocka, mockb, and mockc, and then click the image.png icon to add the services to the selected area.

  2. Create the s1, s2, and s3 traffic lanes, and bind them to the v1, v2, and v3 versions, respectively.

    1. On the Traffic Lane page, go to the Traffic Rule Definition section and click Create swimlanes.

    2. In the Create swimlanes dialog box, configure the parameters and then click OK.

    Parameter

    Description

    Swimlane Name

    Enter s1, s2, and s3 for the three traffic lanes respectively.

    Configure Service Tag

    Label Key: Enter ASM_TRAFFIC_TAG.

    Label Value: Enter v1, v2, and v3 for the three traffic lanes respectively.

    Add Service

    • s1 lane: Select mocka(default), mockb(default), and mockc(default).

    • s2 lane: Select mocka(default) and mockc(default).

    • s3 lane: Select mockb(default).

    By default, ASM sets the first traffic lane that you create in a lane group as the baseline lane. You can also change the baseline lane. When traffic is sent to a service that does not exist in another traffic lane, a fallback mechanism forwards the request to the baseline lane. For more information about how to change the baseline lane, see Change the baseline lane in permissive mode.

    In the left-side navigation pane of the console, you can choose Traffic Management Center > DestinationRule or VirtualService to view the DestinationRule and VirtualService resources that ASM automatically generates for each service in the lane group. For example, the following DestinationRule and VirtualService are automatically created for the mocka service.

    DestinationRule and VirtualService

    apiVersion: networking.istio.io/v1beta1
    kind: DestinationRule
    metadata:
      labels:
        asm-system: 'true'
        provider: asm
        swimlane-group: test
      name: trafficlabel-dr-test-default-mocka
      namespace: istio-system
    spec:
      host: mocka.default.svc.cluster.local
      subsets:
        - labels:
            ASM_TRAFFIC_TAG: v1
          name: s1
        - labels:
            ASM_TRAFFIC_TAG: v2
          name: s2
    apiVersion: networking.istio.io/v1beta1
    kind: VirtualService
    metadata:
      labels:
        asm-system: 'true'
        provider: asm
        swimlane-group: test
      name: trafficlabel-vs-test-default-mocka
      namespace: istio-system
    spec:
      hosts:
        - mocka.default.svc.cluster.local
      http:
        - match:
            - headers:
                x-asm-prefer-tag:
                  exact: s1
          route:
            - destination:
                host: mocka.default.svc.cluster.local
                subset: s1
              fallback:
                target:
                  host: mocka.default.svc.cluster.local
                  subset: s1
        - match:
            - headers:
                x-asm-prefer-tag:
                  exact: s2
          route:
            - destination:
                host: mocka.default.svc.cluster.local
                subset: s2
              fallback:
                target:
                  host: mocka.default.svc.cluster.local
                  subset: s1
        - match:
            - headers:
                x-asm-prefer-tag:
                  exact: s3
          route:
            - destination:
                host: mocka.default.svc.cluster.local
                subset: s3
              fallback:
                target:
                  host: mocka.default.svc.cluster.local
                  subset: s1
  3. Create a unified weight-based routing rule.

    1. On the Traffic Lane page, in the Traffic Rule Definition section, click Weight-based Routing in the Routing Policy section.

    2. In the Set Unified Routing Rules dialog box, configure the parameters and then click OK. The following example shows how to configure a unified routing rule for the three traffic lanes, assuming the entry API for the lane service is /mock.

      Parameter

      Description

      realm name

      Set this to *.

      Matching request URI

      Set Method to Prefix and Content to /.

  4. Set the routing weights for the three traffic lanes. The weights determine the proportion of traffic sent to each lane.

    1. On the Traffic Lane page, in the Traffic Rule Definition section, click the image.png icon next to the number in the Traffic Routing Weight column for each lane. In the Edit Traffic Routing Weight dialog box, configure the parameters and click OK.

      Parameter

      Description

      Ingress service

      Set this to mocka.default.svc.cluster.local for all three traffic lanes.

      Weight Value

      • For the s1 lane, enter 60.

      • For the s2 lane, enter 20.

      • For the s3 lane, enter 20.

Step 3: Verify the end-to-end canary release

  1. Obtain the public IP address of the ASM ingress gateway. For more information, see Obtain the IP address of the ASM ingress gateway.

  2. Run the following command to set an environment variable. Replace xxx.xxx.xxx.xxx with the IP address from the previous step.

    export ASM_GATEWAY_IP=xxx.xxx.xxx.xxx
  3. Verify the end-to-end canary release.

    1. Run the following command to observe the access behavior across the three traffic lanes.

      for i in {1..100};  do curl http://${ASM_GATEWAY_IP}/ ;  echo ''; sleep 1; done;

      Expected output:

      # Traffic to lane s1 (baseline): all services are v1.
      -> mocka(version: v1, ip: 192.168.0.193)-> mockb(version: v1, ip: 192.168.0.1)-> mockc(version: v1, ip: 192.168.0.190)
      
      # Traffic to lane s2: mocka and mockc are v2, mockb falls back to v1 in the baseline lane.
      -> mocka(version: v2, ip: 192.168.0.184)-> mockb(version: v1, ip: 192.168.0.1)-> mockc(version: v2, ip: 192.168.0.189)
      
      # Traffic to lane s3: mockb is v3, mocka and mockc fall back to v1 in the baseline lane.
      -> mocka(version: v1, ip: 192.168.0.193)-> mockb(version: v3, ip: 192.168.0.2)-> mockc(version: v1, ip: 192.168.0.190)
      
      # The output will show a mix of the above patterns, with distribution approximating 6:2:2 for s1:s2:s3.

      The output shows that traffic is distributed to the s1, s2, and s3 traffic lanes at an approximate ratio of 6:2:2. s1 acts as the baseline lane. When a service in the call chain does not exist in the target lane, the request falls back to the corresponding service in the baseline lane (s1).