ASM支持通过TrafficLabel CRD设置流量标签,然后根据流量标签将流量路由到不同的工作负载。本文介绍流量标签和标签路由的功能。
背景信息
流量打标又称作流量染色,指对符合一定流量特征的请求打上具体的染色标记。Istio通过透明拦截的方式劫持了应用流量,基于此技术背景,Sidecar可以对应用流量进行染色标记。
ASM商业版(专业版)扩展了一个新的TrafficLabel CRD ,通过该CRD定义具体的流量染色逻辑,实现命名空间、工作负载及接口级别的流量打标。
注意事项
仅ASM商业版(专业版)v1.10.5.40及以上版本支持流量打标和标签路由功能。
如何对工作负载进行流量打标
方式一:按照命名空间进行流量打标
对命名空间下的所有应用进行流量打标。
- 通过控制面kubectl访问Istio资源 。
-
使用以下内容,创建
example1.yaml
。
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 # 表示生效的协议,空为都不生效,*为都生效。 protocols: "*" hosts: # 表示生效的服务。 - "*"参数 描述 apiVersion-
若ASM实例版本为1.16及以上,支持使用
apiVersion: istio.alibabacloud.com/v1。若您在ACK集群进行了相关配置,请将对应的TrafficLabel CRD中的apiVersion: istio.alibabacloud.com/v1beta1修改为apiVersion: istio.alibabacloud.com/v1,再重新进行部署。 -
若ASM实例版本为1.16以下,支持使用
apiVersion: istio.alibabacloud.com/v1beta1。
namespace该CRD生效的命名空间。 labels. name标签名称。 labels. valueFrom标签值。取值: 说明 valueFrom 的参数值采用自然顺序的优先级,例如以上配置表示优先从 getContext(x-request-id) 获取标签值,当通过 getContext 变量获取不到才会从 localLabel 变量获取标签值。- getContext(x-request-id) :从流量的上下文获取标签值。
-
localLabel
:从工作负载的业务Pod标签
ASM_TRAFFIC_TAG获取标签值。
attachTo取值为 opentracing ,对应HTTP或GRPC协议,表示该流量标识将添加到Header下。 getContext(xxx)和localLabel两个变量详细说明如下:-
getContext(x-request-id)getContext(x-request-id)是个函数型变量,标明流量颜色需要从流量的上下文中获取,其中x-request-id为该函数参数,指代Trace ID。不同的Trace系统采用的Trace ID不同。说明getContext仅针对Sidecar生效。Sidecar包含入口和出口两种类型的流量,流量打标其实指的是对出口流量进行打标。
ASM商业版(专业版)的Sidecar默认通过x-asm-prefer-tag header从入口流量中获取流量tag,并以Trace ID为Key记录到上下文map<traceId, tag>中。当业务容器发起出口请求时,Sidecar会通过Trace ID查找上下文map。若找到关联tag,则Sidecar会附带x-asm-prefer-tag header(默认)以及TrafficLabel CRD定义的标签名userdefinelabel1。说明- 业务应用采用不同的Trace系统则会有不同Trace ID。更多信息,请参见 Tracing 。
-
map<traceId, tag>存储在Envoy内存中,默认30秒过期。
若不定义getContext函数下的参数,Sidecar默认采用x-request-id为Trace ID。Trace ID需要业务应用进行Header propagation或Context propagation。若Header Propagation逻辑缺失,则出口流量会因为找不到关联的Trace ID Key,Sidecar将无法从
map<traceId,tag>找到对应的流量tag。若业务应用有对接Trace系统,则Trace SDK会帮助业务代码进行Header propagation或Context propagation,例如采用 接入ARMS进行trace 。若业务有对接ARMS Trace,则只需要在TrafficLabel CRD中修改 valueFrom 为 getContext(x-b3-traceid) ,其中参数 x-b3-traceid 为Zipkin系统的Trace header。
-
localLabellocalLabel是从Sidecar对应的业务Pod标签 ASM_TRAFFIC_TAG 获取流量标识,并对出口流量打标。以下工作负载定义了 ASM_TRAFFIC_TAG 为 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: {}
-
若ASM实例版本为1.16及以上,支持使用
-
执行以下命令,使CRD生效。
kubectl apply -f example1.yaml
方式二:按照工作负载进行流量打标
对某个命名空间下某个应用进行流量打标。
- 通过控制面kubectl访问Istio资源 。
-
使用以下内容,创建
example2.yaml
。
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: - "*"参数 描述 apiVersion-
若ASM实例版本为1.16及以上,支持使用
apiVersion: istio.alibabacloud.com/v1。若您在ACK集群进行了相关配置,请将对应的TrafficLabel CRD中的apiVersion: istio.alibabacloud.com/v1beta1修改为apiVersion: istio.alibabacloud.com/v1,再重新进行部署。 -
若ASM实例版本为1.16以下,支持使用
apiVersion: istio.alibabacloud.com/v1beta1。
namespace该CRD生效的命名空间。 labels. name标签名称。 labels. valueFrom标签值,取值: 说明 valueFrom具有优先级,以上配置表示优先从 getContext(x-request-id) 获取标签值,当通过 getContext 变量获取不到才会从localLabel变量获取标签值。- getContext(x-request-id) :从流量的上下文获取标签值。
-
localLabel
:从工作负载的业务Pod标签
ASM_TRAFFIC_TAG获取标签值。
workloadSelector. app匹配工作负载的标签,例如本文的CRD只作用于带有test标签的工作负载。 attachTo取值为 opentracing ,对应HTTP或GRPC协议,意味着会将该流量标识添加到header下。 -
若ASM实例版本为1.16及以上,支持使用
-
执行以下命令,使CRD生效。
kubectl apply -f example2.yaml
方式三:按照接口进行流量打标
对某个命名空间下某个应用接口进行流量打标。
- 通过控制面kubectl访问Istio资源 。
-
使用以下内容,创建
example3.yaml
。
apiVersion: istio.alibabacloud.com/v1beta1 kind: TrafficLabel metadata: name: example3 namespace: workshop spec: workloadSelector: labels: app: test rules: - http: - match: - headers: end-user: exact: "jason" prefix: "/test" labels: - name: userdefinelabel1 valueFrom: - $getContext(x-b3-traceid) attachTo: - opentracing protocols: "*" hosts: - "*"参数 描述 apiVersion-
若ASM实例版本为1.15.3.105及以上,支持使用
apiVersion: istio.alibabacloud.com/v1。若您在ACK集群进行了相关配置,请将对应的TrafficLabel CRD中的apiVersion: istio.alibabacloud.com/v1beta1修改为apiVersion: istio.alibabacloud.com/v1,再重新进行部署。 -
若ASM实例版本为1.15.3.105以下,支持使用
apiVersion: istio.alibabacloud.com/v1beta1。
namespace该CRD生效的命名空间。 workloadSelector. app匹配工作负载的标签,例如本文的CRD只作用于带有 app: test标签的工作负载。match. headers请求头,本文设置请求头为 jason用户。match. prefix请求URL,描述特定接口请求,本文设置为带有 /test的请求URL。labels. name标签名称。 labels. valueFrom标签值,取值: 说明 valueFrom具有优先级,以上配置表示优先从 getContext(x-request-id) 获取标签值,当通过 getContext 变量获取不到才会从localLabel变量获取标签值。- getContext(x-request-id) :从流量的上下文获取标签值。
-
localLabel
:从工作负载的业务Pod标签
ASM_TRAFFIC_TAG获取标签值。
attachTo取值为 opentracing,对应HTTP或GRPC协议,表示会将该流量标识添加到header下。 -
若ASM实例版本为1.15.3.105及以上,支持使用
-
执行以下命令,使CRD生效。
kubectl apply -f example3.yaml
基于流量标签进行标签路由
通过TrafficLabel定义了流量标签userdefinelabel1,其取值为test1、test2、test3等,您还需要创建DestinationRule和VirtualService,将流量根据标签路由到对应工作负载。
-
使用以下内容,创建
example4.yaml
。
使用以下内容将productpage分为test1 、test2 、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 -
执行以下命令,创建DestinationRule。
kubectl apply -f example4.yaml -
使用以下内容,创建
example5.yaml
。
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: baseheaders和subset决定了将流量根据标签路由到对应工作负载,例如本文将带有值为test1,名称为userdefinelabel1的标签的流量路由到test1组别的工作负载。参数解释如下:
参数 描述 headers. userdefinelabel1流量标签名称。 headers. exact流量标签值。 subset 路由到的目标工作负载的组别。 -
执行以下命令,创建VirtualService。
kubectl apply -f example5.yaml
其他操作:简化VirtualService变量配置方式
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
其中
fallback
配置
spec
说明如下:
| 参数 | 描述 |
|---|---|
case
|
以竖线(|)分隔的字符串,取值:
|
target
|
路由的目标服务。本文定义了当缺少实例或者实例不可用时,将流量路由到v1组别的工作负载。 |