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.
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 toistio.alibabacloud.com/v1beta1
when you configured the TrafficLabel CRD in the Container Service for Kubernetes (ACK) cluster, change the value toistio.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:
NoteThe 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)
andlocalLabel
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. Thex-request-id
parameter specifies the trace ID. Different tracing systems use different trace IDs.NoteThe
getContext
variable takes effect only for a sidecar.A sidecar involves inbound traffic and outbound traffic. Traffic labeling is to label the outbound traffic.
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.NoteDifferent 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: {}
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.
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 toistio.alibabacloud.com/v1beta1
when you configured the TrafficLabel CRD in the ACK cluster, change the value toistio.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:
NoteThe 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.
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.
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
Run the following command to create a destination rule:
kubectl apply -f example4.yaml
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.
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 |
| The scenario for traffic routing. Multiple scenarios are separated by using vertical bars (|). Valid values:
|
| 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. |