全部產品
Search
文件中心

Alibaba Cloud Service Mesh:流量標籤TrafficLabel說明

更新時間:Jun 30, 2024

在服務網格ASM中,流量標籤(TrafficLabel)支援標記流量,以便您更細緻地進行流量控制和管理。應用服務之間的流量請求被打上特定的標籤後,可以被劃分到不同的服務或者版本中。您可以根據標籤來進行流量控制、熔斷降級、限流等操作。ASM新增並擴充了流量標籤TrafficLabel自訂資源CRD,並通過該CRD定義具體的流量標籤邏輯,為命名空間和工作負載設定流量標籤。本文介紹流量標籤的配置說明、欄位說明和配置樣本。

配置說明

  • 若ASM執行個體版本為1.17及以上,TrafficLabel CRD支援使用apiVersion: istio.alibabacloud.com/v1。若您在ACK叢集進行了TrafficLabel的相關配置,請將對應的TrafficLabel CRD中的apiVersion: istio.alibabacloud.com/v1beta1修改為apiVersion: istio.alibabacloud.com/v1,再重新進行部署。

    展開查看1.17版本TrafficLabel YAML樣本

    apiVersion: istio.alibabacloud.com/v1
    kind: TrafficLabel
    metadata:
      name: example
      namespace: default
    spec:
      workloadSelector:
        labels:
          app: httpbin
      rules:
      - labels:
          - name: asm-labels-test-a
            valueFrom:
            - $getInboundRequestHeader(headerName)
            - $getExternalInboundRequestHeader(contextId, headerName) 
            - $getLocalOutboundRequestHeader(headerName)
            - $getLabel(labelName)  
  • 若ASM執行個體版本為1.17以下,建議您將版本升級到1.17及以上,或提交工單擷取支援人員。

欄位說明

ASM執行個體版本為1.17及以上的欄位說明如下。

Spec

欄位

類型

是否必選

說明

workloadSelector

WorkloadSelector

作用的工作負載範圍。選取器決定在哪裡應用該流量標籤。

如果未設定,選取器將匹配當前命名空間下的所有工作負載。

rules

TrafficLabelRule[]

設定標籤的規則定義。

WorkloadSelector

欄位

類型

是否必選

說明

labels

map<string, string>

在工作負載上應用的流量標籤。支援配置一個或多個標籤。

TrafficLabelRule

欄位

類型

是否必選

說明

labels

Label[]

需要設定的標籤名稱與值。

Label

欄位

類型

是否必選

說明

name

string

標籤名稱。該名稱需要符合HTTP要求標頭的命名規範。

valueFrom

string[]

標籤值。取值採用自然順序的優先順序,優先從第一行擷取標籤值,當擷取不到時才會從第二行擷取標籤值,以此類推。

更多資訊,請參見valueFrom

valueFrom

valueFrom支援以下四種變數。您可以展開表格下方的摺疊面板,查看變數的詳細說明。

變數

支援的工作負載類型

$getInboundRequestHeader(headerName)

網關

$getExternalInboundRequestHeader(headerName, contextId)

Sidecar代理

$getLocalOutboundRequestHeader(headerName)

Sidecar代理

$getLabel(labelName)

網關或者Sidecar代理

展開查看$getInboundRequestHeader(headerName)詳細說明

表示從進入網關的要求標頭中擷取名稱為headerName的標題值。該變數是一個函數型變數,需要從入口要求標頭中擷取。參數headerName是指要求標頭的關鍵字Key。如果參數值為空白,預設為x-asm-prefer-tag

如下圖所示,入口網關會為出口請求中附加一個新要求標頭。該要求標頭的名稱為流量標籤TrafficLabel CRD中定義的標籤名(例如userDefinedLabel),值為tagValue$getInboundRequestHeader(headerName)..png

說明

該變數僅對網關生效,對Sidecar代理不生效。

展開查看$getExternalInboundRequestHeader(headerName, contextId)詳細說明

表示從進入Sidecar代理的請求中擷取名稱為headerName的標題值。該變數是一個函數型變數,需要從流量請求的上下文中擷取。參數說明如下:

  • headerName:要求標頭的關鍵字Key。該參數為必填項,且值不可為空,例如x-asm-prefer-tag

  • contextId:一個貫穿整個調用鏈路的要求標頭欄位,其值可配置為一個指定的入口要求標頭或Tracing系統中的Trace ID。該參數為必填項,且值不可為空。

Sidecar包含入口和出口兩種類型的流量。流量打標的本質是對出口流量設定標籤。預設情況下,Sidecar代理從入口要求標頭(名稱為headerName)中擷取對應的值,並以此作為流量打標的標籤值tagValue$getExternalInboundRequestHeader(headerName, contextId)..png

為了將標籤值tagValue附加到出口流量請求中,在Sidecar代理的內部邏輯中維持一個map<contextId, tagValue>contextId是一個貫穿整個調用鏈路的要求標頭欄位,其值可配置為一個指定的入口要求標頭或使用x-request-id作為contextId

當業務容器發起出口請求時,Sidecar代理會通過contextId尋找上下文Map。若找到關聯tagValue,則Sidecar代理會為出口請求中附加兩個新要求標頭:

  • 要求標頭名稱為headerName,值為tagValue

  • 要求標頭名稱為流量標籤TrafficLabel CRD中定義的標籤名(例如userDefinedLabel),值為tagValue

說明
  • 該變數僅對Sidecar代理生效,對網關不生效。

  • map<contextId, tagValue>儲存在Envoy記憶體中,預設30秒到期。

  • 業務應用接入Trace系統時,TraceID會貫穿整個調用鏈路的請求,因此可以使用TraceID作為上述contextId。採用不同的Trace系統會有不同TraceID。更多資訊,請參見Tracing

  • 雖然Istio代理能夠自動發送Tracing Span資訊,但是應用程式仍然需要傳播相關的HTTP標題,以便在代理髮送Span時,可以將Span正確地關聯到單個跟蹤中。具體操作,請參見在ASM中實現分布式跟蹤

  • 若沒有傳播對應的HTTP標題,則出口流量無法關聯的contextId。Sidecar代理將無法從map<contextId,tagValue>找到對應的流量標籤值。

展開查看$getLocalOutboundRequestHeader(headerName)詳細說明

表示從由應用服務發出至Sidecar代理的請求中擷取名稱為headerName的標題值。該變數是一個函數型變數,需要從入口要求標頭中擷取。參數headerName表示要求標頭的關鍵字Key。您可以根據業務容器實際的要求標頭進行指定。

如下圖所示,當注入Sidecar代理的業務容器發起出口請求時,Sidecar代理會為出口請求中附加一個新要求標頭。該要求標頭的名稱為流量標籤TrafficLabel CRD中定義的標籤名(例如userDefinedLabel),值為tagValue$getLocalOutboundRequestHeader(headerName)..png

說明

該變數僅對Sidecar代理生效,對網關不生效。

展開查看$getLabel(labelName)詳細說明

表示從網關Pod或Sidecar容器所屬Pod的標籤中擷取名稱為labelName的標籤值,並將該值附加到出口流量上。如果labelName為空白,預設從工作負載Pod上的標籤ASM_TRAFFIC_TAG取值。

例如,以下工作負載定義ASM_TRAFFIC_TAG值為test,通過$getLabel(ASM_TRAFFIC_TAG)可以擷取標籤值為test

展開查看YAML樣本

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.17及以上。關於升級執行個體的具體操作,請參見升級ASM執行個體

樣本一:按照工作負載進行流量打標籤

通過定義workloadSelector根據標籤選擇對應的工作負載,可以實現對某個命名空間下的工作負載進行流量打標籤。

  1. 部署bookinfo應用。具體操作,請參見在ASM執行個體關聯的叢集中部署應用

  2. 使用以下內容,建立productpage-trafficlabel.yaml檔案。

    apiVersion: istio.alibabacloud.com/v1
    kind: TrafficLabel
    metadata:
      name: productpage
      namespace: default
    spec:
      workloadSelector:
        labels:
          app: productpage
      rules:
      - labels:
          - name: asm-labels-test-a
            valueFrom:
            - $getExternalInboundRequestHeader(header1, x-request-id)
            - $getLabel(header2)
  3. 執行以下命令,對productpage工作負載進行流量打標籤。

     kubectl apply -n default  -f productpage-trafficlabel.yaml
  4. 執行以下命令,查看productpage工作負載對應的代理配置。

    kubectl exec -it -n default deploy/productpage-v1 -c istio-proxy -- curl localhost:15000/config_dump

    預期輸出:

    {
                  "name": "com.aliyun.traffic_label",
                  "typed_config": {
                   "@type": "type.googleapis.com/envoy.config.filter.traffic_label.v3alpha.TrafficLabel",
                   
                  }
                 },

    在對應的Listener Config(type.googleapis.com/envoy.admin.v3.ListenersConfigDump)/dynamic_listeners下的type.googleapis.com/envoy.config.listener.v3.Listener/envoy.filters.network.http_connection_manager/http_filters,可以看到上述的filter配置內容,表明流量標籤配置成功。

  5. 執行以下命令,查看其他工作負載(例如details Pod)對應的代理配置。

    kubectl exec -it -n default deploy/details-v1 -c istio-proxy -- curl localhost:15000/config_dump |grep type.googleapis.com/envoy.config.filter.traffic_label.v3alpha.TrafficLabel

    返回結果為空白,表明沒有相關的filter,符合預期。

樣本二:按照命名空間進行流量打標籤

如果不定義workloadSelector欄位,將對命名空間下所有的工作負載進行流量打標籤。以下樣本將對命名空間default下的所有工作負載進行流量打標籤。

  1. 使用以下內容,建立all-workload-for-ns-trafficlabel.yaml檔案。

    apiVersion: istio.alibabacloud.com/v1
    kind: TrafficLabel
    metadata:
      name: all-workload-for-ns
      namespace: default
    spec:
      rules:
      - labels:
          - name: asm-labels-test-b
            valueFrom:
            - $getExternalInboundRequestHeader(header1, x-request-id)
            - $getLabel(header2)
  2. 執行以下命令,對命名空間default下的所有工作負載進行流量打標籤。

     kubectl apply -n default -f all-workload-for-ns-trafficlabel.yaml

  3. 執行以下命令,查看工作負載(例如details Pod)對應的代理的配置。

    kubectl exec -it -n default deploy/details-v1 -c istio-proxy -- curl localhost:15000/config_dump |grep type.googleapis.com/envoy.config.filter.traffic_label.v3alpha.TrafficLabel

    預期輸出:

     "@type": "type.googleapis.com/envoy.config.filter.traffic_label.v3alpha.TrafficLabel",

    輸出如上內容,表明流量標籤配置成功。