概述
在应用服务网格中可以通过自定义的资源(TrafficLabel)实现对请求流量的打标,进而可以基于流量的标签进行单服务及全链路的路由、策略控制等。本文介绍流量打标原理,流量标签管理,流量标签配置示例及详细说明。
流量打标原理
流量打标就是要给流量打上标签,进而可以对流量进行路由等策略配置。当前CSM服务网格支持从请求头部或者工作负载本身的标签中取值作为流量的标签;同时还支持在调用链中透传流量标签信息,用于实现全链路的标签路由策略。
流量标签配置实例
下面是一个流量标签的配置示例,定义了一个流量标签userdefinelabel1,会取当前pod的CSM_TRAFFIC_TAG标签值作为userdefinelabel1的值添加到请求头部里面;同时还定义了另外一个userdefinelabel2标签,该标签定义优先从请求的x-traffic-tag头部取值,同时使用Envoy生成的x-request-id作为上下文key,在整个调用链路中透传该标签;如果打标失败了,会按照valueFrom数组中下一个定义继续取值,取到第一个非空值时停止。
apiVersion: istio.ctyun.cn/v1beta1
kind: TrafficLabel
metadata:
name: traffic-label-example
namespace: demo
spec:
rule:
labels:
- name: userdefinelabel1
valueFrom:
- $getLabel(CSM_TRAFFIC_TAG)
- name: userdefinelabel2
valueFrom:
- $getInboundRequestHeaderWithContext (x-traffic-tag, x-request-id)
- $getLabel(CSM_TRAFFIC_TAG)
当前CSM服务网格支持的流量打标方式有以下几种:
函数 | 说明 | 示例 |
---|---|---|
getInboundRequestHeader(headerName) | 从Inbound方向的请求header中取值;只应用于istio ingress网关。 | 请求headerName:v1 打标后: userdefinelabel: v1 |
getInboundRequestHeaderWithContext(headerName, contextKey) | 从Inbound方向的请求header取值,同时从contextKey头部取值作为流量标签在上下文透传的key; 该头部可以是用于实现链路追踪上下文透传的头部,比如x-request-id、x-b3-traceid或者您的业务中使用的自定义头部; 该函数只适用于sidecar。 |
请求: contextID: 1234abcd headerName: v1 打标后: contextID: 1234abcd headerName: v1 userdefinelabel: v1 |
getOutboundRequestHeader(headerName) | 从outbound方向的请求头部取值,只适用于sidecar。 | 请求headerName:v1 打标后: userdefinelabel: v1 |
getLabel(labelName) | 从pod的标签取值;适用于istio ingress网关和sidecar。 | Pod标签: labelName: v1 打标后: userdefinelabel: v1 |
流量标签管理
创建流量标签
- 通过服务网格控制台 流量管理中心 -> 流量标签菜单进入流量标签管理页面。
- 选择命名空间,选择左上角使用YAML创建。
- 基于模板编辑流量标签定义,保存即可。
修改流量标签
- 通过服务网格控制台 流量管理中心 -> 流量标签菜单进入流量标签管理页面。
- 选择命名空间,列表页会展示当前命名空间下定义的TrafficLabel对象。
- 选择操作栏的编辑,修改定义,保存即可。
删除流量标签
- 通过服务网格控制台 流量管理中心 -> 流量标签菜单进入流量标签管理页面。
- 选择命名空间,列表页会展示当前命名空间下定义的TrafficLabel对象。
- 选择操作栏的删除,即可删除已定义的TrafficLabel对象。
TrafficLabel配置说明
字段 | 类型 | 必选 | 说明 |
---|---|---|---|
workload_selector | WorkloadSelector | No | 工作负载选择器,选择当前流量标签生效的工作负载。 |
rule | TrafficLabelRule | No | 流量标签定义。 |
TrafficLabelRule
流量标签的详细定义
字段 | 类型 | 必选 | 说明 |
---|---|---|---|
labels | Label | No | 流量标签定义。 |
Label
字段 | 类型 | 必选 | 说明 |
---|---|---|---|
name | string | No | 流量标签名称,该标签会被添加到请求头部。 |
value_from | string | No | 流量标签取值,value_from为数组,按照顺序取到的第一个非空值作为该标签的取值。 |
流量标签使用示例
准备工作:首先部署测试应用app1和app2,调用关系为ingress -> app1-> app2。
apiVersion: v1
kind: Service
metadata:
name: app1
labels:
app: app1
service: app1
spec:
ports:
- port: 8000
name: http
selector:
app: app1
apiVersion: apps/v1
kind: Deployment
metadata:
name: app1-base
namespace: demo
labels:
app: app1
CSM_TRAFFIC_TAG: base
spec:
replicas: 1
selector:
matchLabels:
app: app1
name: app1
CSM_TRAFFIC_TAG: base
template:
metadata:
labels:
app: app1
name: app1
source: CCSE
CSM_TRAFFIC_TAG: base
spec:
containers:
- name: default
image: registry-vpc-crs-huadong1.cnsp-internal.ctyun.cn/library/trace-demo:v1.0.0
imagePullPolicy: IfNotPresent
env:
- name: version
value: base
- name: app
value: app1
- name: upstream_url
value: "http://app2:8000/"
ports:
- containerPort: 8000
部署Gateway和VirtualService资源
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
name: trace-demo-gateway
spec:
selector:
istio: ingressgateway
servers:
- hosts:
- "*"
port:
name: http
number: 80
protocol: HTTP
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: vs-gateway-app1
spec:
gateways:
- trace-demo-gateway
hosts:
- "*"
http:
- route:
- destination:
host: app1
Ingress gateway流量打标
Ingress网关侧对流量打标之后我们看通过查看上游的app1服务收到的请求头部确认流量打标是否成功,首先定义流量标签策略:
apiVersion: istio.ctyun.cn/v1beta1
kind: TrafficLabel
metadata:
name: traffic-label-example
namespace: istio-system
spec:
workloadSelector:
labels:
istio: ingressgateway
rule:
labels:
- name: label-from-header
valueFrom:
- $getInboundRequestHeader(app-version-tag)
- name: label-from-pod
valueFrom:
- $getLabel(app)
上面的配置在Ingress网关处定义了两个标签,label-from-header会从app-version-tag请求头部取值打标,label-from-pod从pod的app标签取值打标。我们通过Ingress网关访问app1服务,并带上app-version-tag: ccccc,查看app1的日志如下:
sidear流量打标
首先定义sidecar流量打标规则,label1从app-version-tag头部取值,同时使用trace-ctx-id字段做链路传递;label2去outbound方向的trace-ctx-id字段;label3取应用的app标签值:
apiVersion: istio.ctyun.cn/v1beta1
kind: TrafficLabel
metadata:
name: traffic-label-example
namespace: default
spec:
rule:
labels:
- name: label1
valueFrom:
- $getInboundRequestHeaderWithContext(app-version-tag, trace-ctx-id)
- name: label2
valueFrom:
- $getOutboundRequestHeader(trace-ctx-id)
- name: label3
valueFrom:
- $getLabel(app)
请求Ingress网关带上两个头部'app-version-tag:‘ccccc' 和 'trace-ctx-id: 1234',查看app2的日志,可以看到预期中的流量标签。