All Products
Search
Document Center

Alibaba Cloud Service Mesh:Traffic labeling and label-based routing

Last Updated:Jun 05, 2023

Service Mesh (ASM) allows you to configure traffic labels by using TrafficLabel Custom Resource Definitions (CRDs) and route traffic to different workloads based on the traffic labels. This topic describes the traffic labeling and label-based routing features.

Background information

Traffic labeling is also called traffic coloring. Traffic labeling is to label the requests that have specific traffic characteristics. Istio transparently hijacks application traffic. You can use a sidecar to label application traffic based on Istio.

ASM commercial editions provide a new TrafficLabel CRD. You can use this CRD to define traffic labeling logic and label traffic for a specific namespace, workload, or API operation.

Usage notes

Only ASM instances of commercial editions and 1.10.5.40 or later versions support the traffic labeling and label-based routing features.

Label traffic

Method 1: Label traffic for namespace

You can use this method to label traffic of all applications in a specific namespace.

  1. Use kubectl on the control plane to access Istio resources.

  2. Create a file named example1.yaml that contains the following content:

    apiVersion: istio.alibabacloud.com/v1beta1
    kind: TrafficLabel
    metadata:
      name: example1
      namespace: default
    spec:
      rules:
      - labels:
          - name: userdefinelabel1
            valueFrom:
            - $getContext(x-request-id)
            - $localLabel
        attachTo:
        - opentracing
        # The protocols that take effect. If you leave the protocols parameter empty, no protocol takes effect. If you set the protocols parameter to an asterisk (*), all protocols take effect. 
        protocols: "*"
      hosts: # The services to which the TrafficLabel CRD is applied. 
      - "*"

    Parameter

    Description

    apiVersion

    • If the version of your ASM instance is 1.16 or later, you can set the apiVersion parameter to istio.alibabacloud.com/v1. If you have set the apiVersion parameter to istio.alibabacloud.com/v1beta1 when you configured the TrafficLabel CRD in the Container Service for Kubernetes (ACK) cluster, change the value to istio.alibabacloud.com/v1, and deploy the YAML file again.

    • If the version of your ASM instance is earlier than 1.16, you can set the apiVersion parameter to istio.alibabacloud.com/v1beta1.

    namespace

    The namespace in which the TrafficLabel CRD takes effect.

    labels. name

    The name of the traffic label.

    labels. valueFrom

    The value of the traffic label. Valid values:

    Note

    The values of the valueFrom parameter are sequenced by priority. For example, the sequence in the preceding code indicates that the getContext(x-request-id) variable is preferentially used to obtain traffic label values. The localLabel variable is used only if the getContext(x-request-id) variable fails to obtain traffic label values.

    • getContext(x-request-id): obtains traffic label values based on the traffic context.

    • localLabel: obtains traffic label values based on the ASM_TRAFFIC_TAG label added to the pod.

    attachTo

    Set the value to opentracing. In this case, if the traffic label applies to the HTTP or gRPC protocol, the traffic label is added to the request header.

    The following content describes the getContext(xxx) and localLabel variables:

    • getContext(x-request-id)

      getContext(x-request-id) is a function that serves as a variable. The variable is used to obtain the traffic label based on the traffic context. The x-request-id parameter specifies the trace ID. Different tracing systems use different trace IDs.

      Note

      The getContext variable takes effect only for a sidecar.

      A sidecar involves inbound traffic and outbound traffic. Traffic labeling is to label the outbound traffic. Traffic labeling

      By default, a sidecar of an ASM instance of commercial editions attempts to obtain a traffic label from the inbound traffic by using the x-asm-prefer-tag header and records the traffic label to the context in the format of map<traceId, tag>. The trace ID is used as the key. If a container initiates an outbound request, the sidecar searches for the traffic label in the map based on the trace ID. If the traffic label is found, the sidecar transfers the traffic label together with x-asm-prefer-tag header that is automatically transferred and the traffic label name userdefinelabel1 that is defined by the TrafficLabel CRD.

      Note
      • Different tracing systems use different trace IDs. For more information, see Tracing.

      • The traffic label in the map<traceId, tag> format is stored in the memory of an Envoy proxy for only 30 minutes by default.

      If you do not set the parameter of the getContext function, the sidecar uses the x-request-id as the trace ID by default. In this case, your application must propagate the trace ID by using a header. If no header propagation logic exists, the trace ID of an outbound request cannot be obtained. Then, the sidecar may fail to obtain the corresponding traffic label from map<traceId,tag>.

      If your application is connected to a tracing system, you can use the SDKs provided by the tracing system to propagate the context in the code by using headers. For example, you can connect your application to Application Real-Time Monitoring Service (ARMS) for tracing. For more information, see Monitor application performance. If your application is connected to an ARMS tracing system, you need only to change the getContext(x-request-id) variable under valueFrom in the TrafficLabel CRD to getContext(x-b3-traceid). The x-b3-traceid parameter specifies a trace header in the Zipkin system.

    • localLabel

      The localLabel variable is used to obtain traffic label values based on the ASM_TRAFFIC_TAG label that is added to the pod along which the sidecar runs and label the outbound traffic. In the following YAML file of a Deployment, the value of the ASM_TRAFFIC_TAG label is 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
          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: {}
  3. Run the following command to make the TrafficLabel CRD take effect:

    kubectl apply -f example1.yaml

Method 2: Label traffic for workload

You can use this method to label traffic for a specific application in a namespace.

  1. Use kubectl on the control plane to access Istio resources.

  2. Create a file named example2.yaml that contains the following content:

    apiVersion: istio.alibabacloud.com/v1beta1
    kind: TrafficLabel
    metadata:
      name: example2
      namespace: workshop
    spec:
      workloadSelector:
        labels:
          app: test
      rules:
      - labels:
          - name: userdefinelabel1
            valueFrom:
            - $getContext(x-request-id)
            - $localLabel
        attachTo:
        - opentracing
        protocols: "*"
      hosts:
      - "*"

    Parameter

    Description

    apiVersion

    • If the version of your ASM instance is 1.16 or later, you can set the apiVersion parameter to istio.alibabacloud.com/v1. If you have set the apiVersion parameter to istio.alibabacloud.com/v1beta1 when you configured the TrafficLabel CRD in the ACK cluster, change the value to istio.alibabacloud.com/v1, and deploy the YAML file again.

    • If the version of your ASM instance is earlier than 1.16, you can set the apiVersion parameter to istio.alibabacloud.com/v1beta1.

    namespace

    The namespace in which the TrafficLabel CRD takes effect.

    labels. name

    The name of the traffic label.

    labels. valueFrom

    The value of the traffic label. Valid values:

    Note

    The values of the valueFrom parameter are sequenced by priority. For example, the sequence in the preceding code indicates that the getContext(x-request-id) variable is preferentially used to obtain traffic label values. The localLabel variable is used only if the getContext(x-request-id) variable fails to obtain traffic label values.

    • getContext(x-request-id): obtains traffic label values based on the traffic context.

    • localLabel: obtains traffic label values based on the ASM_TRAFFIC_TAG label added to the pod.

    workloadSelector. app

    The label used to match a workload. For example, the parameter value in the preceding code indicates that the TrafficLabel CRD applies only to a workload with the test label.

    attachTo

    Set the value to opentracing. In this case, if the traffic label applies to the HTTP or gRPC protocol, the traffic label is added to the request header.

  3. Run the following command to make the TrafficLabel CRD take effect:

    kubectl apply -f example2.yaml

Route traffic based on traffic labels

After you define the traffic labels whose names are userdefinelabel1 and whose values are test1, test2, and test3 by using the TrafficLabel CRD, you need to create a destination rule and a virtual service to route traffic to corresponding workloads based on the traffic labels.

  1. Create a file named example4.yaml that contains the following content.

    The following code divides productpage into multiple subsets such as test1, test2, and test3.

    apiVersion: networking.istio.io/v1alpha3
    kind: DestinationRule
    metadata:
      name: 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. Run the following command to create a destination rule:

    kubectl apply -f example4.yaml
  3. Create a file named example5.yaml that contains the following content:

    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: example-app
      namespace: default
    spec:
      hosts:
        - example
      http:
      - match:
        - headers:
            userdefinelabel1:
             exact: test1
        route:
        - destination:
            host: example
            subset: test1
      - match:
        - headers:
            userdefinelabel1:
             exact: test2
        route:
        - destination:
            host: example
            subset: test2
      - match:
        - headers:
            userdefinelabel1:
             exact: test3
        route:
        - destination:
            host: example
            subset: test3
      - route:
        - destination:
            host: example
            subset: base

    The headers and subset parameters determine the corresponding workloads to which traffic is routed based on the traffic labels. For example, in the preceding code, a request with the userdefinelabel1:test1 label is routed to the workload that belongs to the subset test1. The following table describes the parameters.

    Parameter

    Description

    headers. userdefinelabel1

    The name of the traffic label.

    headers. exact

    The value of the traffic label.

    subset

    The subset to which the destination workload belongs.

  4. Run the following command to create a virtual service:

    kubectl apply -f example5.yaml

Simplify the variable configuration of a virtual service

If a great many workload versions exist, the virtual service configuration is complicated. You can use the following code to simplify the variable configuration of the virtual service and degrade the traffic:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: example-app
  namespace: default
spec:
  hosts:
    - example
  http:
  - route:
    - destination:
        host: example
        subset: $userdefinelabel1
      fallback:
        case: noinstances|noavailabled
        target:
          host: example
          subset: v1
                

The following table describes the parameters under fallback.

Parameter

Description

case

The scenario for traffic routing. Multiple scenarios are separated by using vertical bars (|). Valid values:

  • noinstances: No instance is specified.

  • noavailabled: The backend instance is unavailable.

  • noisolationunit: The backend subset does not exist.

target

The service to which traffic is routed. The preceding code shows how to route traffic to the workload that belongs to the subset v1 if no instance is specified or the backend instance is unavailable.