概述
在應用服務網格中可以通過自定義的資源(TrafficLabel)實現對請求流量的打標,進而可以基于流量的標簽進行單服務及全鏈路的路由、策略控制等。本文介紹流量打標原理,流量標簽管理,流量標簽配置示例及詳細說明。
流量打標原理
流量打標就是要給流量打上標簽,進而可以對流量進行路由等策略配置。當前CSM服務網格支持從請求頭部或者工作負載本身的標簽中取值作為流量的標簽;同時還支持在調用鏈中透傳流量標簽信息,用于實現全鏈路的標簽路由策略。
流量標簽配置實例
下面是一個流量標簽的配置示例,定義了一個流量標簽userdefinelabel1,會取當前pod的CSM_TRAFFIC_TAG標簽值作為userdefinelabel1的值添加到請求頭部里面;同時還定義了另外一個userdefinelabel2標簽,該標簽定義優先從請求的x-traffic-tag頭部取值,同時使用Envoy生成的x-request-id作為上下文key,在整個調用鏈路中透傳該標簽;如果打標失敗了,會按照valueFrom數組中下一個定義繼續取值,取到第一個非空值時停止。
apiVersion: istio.daliqc.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.daliqc.cn/library/trace-demo:v1.0.0
imagePullPolicy: IfNotPresent
env:
- name: version
value: base
- name: app
value: app1
- name: upstream_url
value: "//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: app1Ingress gateway流量打標
Ingress網關側對流量打標之后我們看通過查看上游的app1服務收到的請求頭部確認流量打標是否成功,首先定義流量標簽策略:
apiVersion: istio.daliqc.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.daliqc.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的日志,可以看到預期中的流量標簽。
