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。
localLabel
localLabel
是从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
基于流量标签进行标签路由
通过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: base
headers和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组别的工作负载。 |