All Products
Search
Document Center

Alibaba Cloud Service Mesh:Label traffic

Last Updated:Jul 06, 2023

Service Mesh (ASM) allows you to configure traffic labels so that you can manage traffic based on the labels. You can route application traffic with specific labels to different services or versions. You can perform traffic control, such as circuit breaking and throttling, based on labels. ASM adds the TrafficLabel CustomResourceDefinition (CRD). You can use this CRD to define traffic label logics and configure traffic labels for namespaces and workloads. This topic describes how to configure traffic labels and provides descriptions of the fields in the CRD and configuration examples.

Usage notes

  • An ASM instance of version 1.17 or later supports apiVersion: istio.alibabacloud.com/v1 in the TrafficLabel CRD. If you have configured TrafficLabel in the Container Service for Kubernetes (ACK) cluster, change apiVersion: istio.alibabacloud.com/v1beta1 in the TrafficLabel CRD to apiVersion: istio.alibabacloud.com/v1 and then configure TrafficLabel again.

    Show the sample YAML code for TrafficLabel configuration in an ASM instance of version 1.17

    apiVersion: istio.alibabacloud.com/v1
    kind: TrafficLabel
    metadata:
      name: example
      namespace: default
    spec:
      workloadSelector:
        labels:
          app: httpbin
      rules:
      - labels:
          - name: asm-labels-test-a
            valueFrom:
            - $getInboundRequestHeader(headerName)
            - $getExternalInboundRequestHeader(contextId, headerName) 
            - $getLocalOutboundRequestHeader(headerName)
            - $getLabel(labelName)  
  • If the version of your ASM instance is earlier than 1.17, we recommend that you update the ASM instance to version 1.17 or later, or submit a ticket to obtain technical support.

Field description

This section describes the CRD fields in an ASM instance of version 1.17 or later.

Spec

Field

Type

Required

Description

workloadSelector

WorkloadSelector

No

Indicates the workload range in which the selector applies the traffic label.

If this field is left empty, the selector applies the traffic label to all workloads in the current namespace.

rules

TrafficLabelRule[]

Yes

Defines rules for traffic labels.

WorkloadSelector

Field

Type

Required

Description

labels

map<string, string>

No

Traffic labels that are applied to workloads. You can configure one or more labels.

TrafficLabelRule

Field

Type

Required

Description

labels

Label[]

Yes

The names and values of the labels that you want to configure.

Label

Field

Type

Required

Description

name

string

Yes

The name of the traffic label. The name must comply with the naming conventions of HTTP request headers.

valueFrom

string[]

Yes

The value of the traffic label. The value is obtained based on the variable order you set. The label value is preferentially obtained from the first variable. If it is unavailable, the second variable is checked. If the value is not found in the first and second variables, the third variable is checked. Finally, if the value is not found in the first, second, and third variables, it is obtained from the fourth variable.

For more information, see valueFrom.

valueFrom

The valueFrom field supports the following four variables. You can click the corresponding expand icons below the table to view the descriptions of the variables.

Variable

Supported workloads

$getInboundRequestHeader(headerName)

Gateways

$getExternalInboundRequestHeader(headerName, contextId)

Sidecar proxies

$getLocalOutboundRequestHeader(headerName)

Sidecar proxies

$getLabel(labelName)

Gateways or sidecar proxies

Show the description of $getInboundRequestHeader(headerName)

This variable indicates that the value of the header named headerName is obtained from the request that enters the gateway. According to this function variable, the value of the traffic label is obtained from an inbound request header. The headerName parameter is the key of a request header. If the parameter is left empty, x-asm-prefer-tag is used by default.

As shown in the following figure, the ingress gateway adds a new request header to the outbound request. The name of the request header is the label name (for example, userDefinedLabel) that is defined in the TrafficLabel CRD and the value is tagValue.$getInboundRequestHeader(headerName)..png

Note

This variable takes effect only for gateways. It does not take effect for sidecar proxies.

Show the description of $getExternalInboundRequestHeader(headerName, contextId)

This variable indicates that the value of the header named headerName is obtained from the request that enters the sidecar proxy. According to this function variable, the value of the traffic label is obtained from the context of a traffic request. The variable contains the following parameters:

  • headerName: the key of a request header. This parameter value is mandatory, such as x-asm-prefer-tag.

  • contextId: a request header field that runs through the entire call chain. The value can be a specified inbound request header or a trace ID in the tracing system. This parameter is mandatory and cannot be left empty.

A sidecar proxy involves inbound traffic and outbound traffic. Traffic labeling is to label the outbound traffic. By default, a sidecar proxy obtains the value from the inbound request header whose name is headerName and uses this value as the label value tagValue for the traffic.$getExternalInboundRequestHeader(headerName, contextId)..png

To add tagValue to an outbound request, the sidecar proxy keeps map<contextId, tagValue> in its internal logic. contextId is a request header field that runs through the entire call chain. The value can be a specified inbound request header or x-request-id.

When an application container initiates an outbound request, the sidecar proxy searches for the context map by using contextId. If the associated tagValue is found, the sidecar proxy adds the following two request headers to the outbound request:

  • The name of one request header is headerName and the value is tagValue.

  • The name of the other request header is the label name (for example, userDefinedLabel) that is defined in the TrafficLabel CRD, and the value is tagValue.

Note
  • This variable takes effect only for sidecar proxies. It does not take effect for gateways.

  • By default, map<contextId, tagValue> is stored in the memory of an Envoy proxy for 30 seconds.

  • When an application is connected to a tracing system, a trace ID is used in the request throughout the entire call chain. Therefore, you can use the trace ID as the contextId. Different tracing systems use different trace IDs. For more information, see Tracing.

  • Although Istio proxies can automatically send tracing spans, they need some hints to tie together the entire trace. Applications need to propagate relevant HTTP headers so that the spans sent by Istio proxies can be correctly correlated into a single trace. For more information, see Enable distributed tracing in ASM.

  • If the corresponding HTTP header is not propagated, the outbound traffic cannot be associated with contextId. Then, the sidecar proxy cannot obtain the corresponding traffic label value from map<contextId,tagValue>.

Show the description of $getLocalOutboundRequestHeader(headerName)

This variable indicates that the value of the header named headerName is obtained from the request that the application sends to the sidecar proxy. According to this function variable, the value of the traffic label is obtained from an inbound request header. The headerName parameter is the key of a request header. You can specify the parameter based on the actual request header of the application container.

As shown in the following figure, when the application container to which the sidecar proxy is injected initiates an outbound request, the sidecar proxy adds a request header to the outbound request. The name of the request header is the label name (for example, userDefinedLabel) that is defined in the TrafficLabel CRD and the value is tagValue.$getLocalOutboundRequestHeader(headerName)..png

Note

This variable takes effect only for sidecar proxies. It does not take effect for gateways.

Show the description of $getLabel(labelName)

This variable indicates that the value of the label named labelName is obtained from the gateway pod or the pod of the sidecar container, and the value is added to the outbound traffic. If labelName is left empty, this variable obtains the value of the ASM_TRAFFIC_TAG label from the workload pod by default.

In the following example, the value of ASM_TRAFFIC_TAG of the workload is test. You can use the $getLabel(ASM_TRAFFIC_TAG) variable to obtain value test.

Show the sample YAML code

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: {}

Configuration examples

In the following examples, the ASM instances are of version 1.17 or later. For more information about how to update an ASM instance, see Update an ASM instance.

Example 1: Label traffic for a workload

You can define workloadSelector to select the workload based on the label and then label the traffic of the workloads in a namespace.

  1. Deploy the Bookinfo application. For more information, see Deploy an application in an ASM instance.

  2. Create a file named productpage-trafficlabel.yaml and copy the following content to the file:

    apiVersion: istio.alibabacloud.com/v1
    kind: TrafficLabel
    metadata:
      name: productpage
      namespace: default
    spec:
      workloadSelector:
        labels:
          app: productpage
      rules:
      - labels:
          - name: asm-labels-test-a
            valueFrom:
            - $getExternalInboundRequestHeader(header1, x-request-id)
            - $getLabel(header2)
  3. Run the following command to label the traffic of the productpage workload:

     kubectl apply -n default  -f productpage-trafficlabel.yaml
  4. Run the following command to view the proxy configuration of the productpage workload:

    kubectl exec -it -n default deploy/productpage-v1 -c istio-proxy -- curl localhost:15000/config_dump

    Expected output:

    {
                  "name": "com.aliyun.traffic_label",
                  "typed_config": {
                   "@type": "type.googleapis.com/envoy.config.filter.traffic_label.v3alpha.TrafficLabel",
                   
                  }
                 },

    You can see the preceding filter configuration in type.googleapis.com/envoy.config.listener.v3.Listener/envoy.filters.network.http_connection_manager/http_filters under Listener Config (type.googleapis.com/envoy.admin.v3.ListenersConfigDump) or dynamic_listeners. This indicates that the traffic label is configured.

  5. Run the following command to view the proxy configurations of other workloads, such as the details pod:

    kubectl exec -it -n default deploy/details-v1 -c istio-proxy -- curl localhost:15000/config_dump |grep type.googleapis.com/envoy.config.filter.traffic_label.v3alpha.TrafficLabel

    The returned result is empty, indicating that no relevant filter is available. The result meets expectations.

Example 2: Label traffic at the namespace level

If you leave the workloadSelector field empty, the label is added to the traffic of all workloads in the namespace. The following example labels the traffic of all workloads in the default namespace.

  1. Create a file named all-workload-for-ns-trafficlabel.yaml and copy the following content to the file:

    apiVersion: istio.alibabacloud.com/v1
    kind: TrafficLabel
    metadata:
      name: all-workload-for-ns
      namespace: default
    spec:
      rules:
      - labels:
          - name: asm-labels-test-b
            valueFrom:
            - $getExternalInboundRequestHeader(header1, x-request-id)
            - $getLabel(header2)
  2. Run the following command to label the traffic of all workloads in the default namespace:

     kubectl apply -n default -f all-workload-for-ns-trafficlabel.yaml

  3. Run the following command to view the proxy configurations of a workload, such as the details pod:

    kubectl exec -it -n default deploy/details-v1 -c istio-proxy -- curl localhost:15000/config_dump |grep type.googleapis.com/envoy.config.filter.traffic_label.v3alpha.TrafficLabel

    Expected output:

     "@type": "type.googleapis.com/envoy.config.filter.traffic_label.v3alpha.TrafficLabel",

    The preceding output indicates that the traffic label is configured.