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 |
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 |
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 |
Field | Type | Required | Description |
labels | Label[] | Yes | The names and values of the labels that you want to configure. |
Label
Field | Type | Required | Description |
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 |
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.
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.
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.
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.
Deploy the Bookinfo application. For more information, see Deploy an application in an ASM instance.
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)
Run the following command to label the traffic of the productpage
workload:
kubectl apply -n default -f productpage-trafficlabel.yaml
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.
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.
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)
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
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.