全部產品
Search
文件中心

Alibaba Cloud Service Mesh:使用strict 模式流量泳道實現全鏈路流量管理

更新時間:Jul 17, 2024

當您需要對整條調用鏈路進行灰階發布或版本隔離時,可以使用strict 模式的流量泳道,將應用的相關版本(或其他特徵)隔離成獨立的運行環境,確保只有符合特定條件的流量被路由到新的服務版本,提高發布過程的穩定性和可控性。

前提條件

  • 已建立ASM企業版或旗艦版執行個體,且版本為1.18.2.111及以上。具體操作,請參見建立ASM執行個體升級ASM執行個體

    說明

    若您的執行個體版本為1.17.2.22及以上,1.18.2.111以下,請參見使用泳道模式下的流量管理功能

  • 已添加叢集到ASM執行個體。具體操作,請參見添加叢集到ASM執行個體

  • 已建立名稱為ingressgateway的ASM入口網關。具體操作,請參見建立入口網關服務

  • 已建立名稱為ingressgateway且命名空間為istio-system的網關規則。具體操作,請參見管理網關規則

    展開查看Gateway YAML樣本

    apiVersion: networking.istio.io/v1beta1
    kind: Gateway
    metadata:
      name: ingressgateway
      namespace: istio-system
    spec:
      selector:
        istio: ingressgateway
      servers:
        - port:
            number: 80
            name: http
            protocol: HTTP
          hosts:
            - '*'

樣本說明

本樣本使用mocka、mockb、mockc三個服務建立代表格服務調用鏈三個版本的三條泳道:s1、s2、s3。image.png

步驟一:部署樣本服務

  1. 為default命名空間啟用Sidecar網格代理自動注入。具體操作,請參見啟用自動注入

    關於自動注入的更多資訊,請參見配置Sidecar注入策略

  2. 在ACK叢集中執行以下命令,部署樣本服務。

    kubectl apply -f https://alibabacloudservicemesh.oss-cn-beijing.aliyuncs.com/asm-labs/swimlane/v1/mock-v1.yaml
    kubectl apply -f https://alibabacloudservicemesh.oss-cn-beijing.aliyuncs.com/asm-labs/swimlane/v2/mock-v2.yaml
    kubectl apply -f https://alibabacloudservicemesh.oss-cn-beijing.aliyuncs.com/asm-labs/swimlane/v3/mock-v3.yaml

步驟二:建立泳道組和對應泳道

  1. 建立泳道組。

    1. 登入ASM控制台,在左側導覽列,選擇服務網格 > 網格管理

    2. 網格管理頁面,單擊目標執行個體名稱,然後在左側導覽列,選擇流量管理中心 > 流量泳道

    3. 流量泳道頁面,單擊建立泳道組,在建立泳道組面板,配置相關資訊,然後單擊確定

      配置項

      說明

      泳道組名稱

      本樣本配置為test

      入口網關

      選擇ingressgateway

      泳道模式

      選擇strict 模式

      泳道服務

      選擇目標Kubernetes叢集和default命名空間,在下方列表中選中mockamockbmockc服務,單擊移動表徵圖,添加目標服務到已選擇地區。

  2. 建立s1、s2、s3泳道,並分別綁定v1、v2、v3版本。

    1. 流量泳道頁面的流量規則定義地區,單擊建立泳道

    2. 建立泳道對話方塊,配置相關資訊,然後單擊確定

      配置項

      說明

      泳道名稱

      三條泳道分別配置為s1s2s3

      佈建服務標籤

      標籤名稱:選擇ASM_TRAFFIC_TAG

      標籤值:三條泳道分別選擇v1v2v3

      建立s1泳道的樣本圖如下:

      建立泳道

      三條泳道建立完成後,樣本效果如下:建立泳道

      三條泳道建立完成後,針對泳道組中的每個服務都將產生泳道規則對應的目標規則和虛擬服務。您可以在控制台左側導覽列,選擇流量管理中心 > 目標規則虛擬服務進行查看。例如,針對mocka服務會自動建立如下目標規則和虛擬服務。

      展開查看目標規則YAML樣本

      apiVersion: networking.istio.io/v1beta1
      kind: DestinationRule
      metadata:
        labels:
          asm-system: 'true'
          provider: asm
          swimlane-group: test
        name: trafficlabel-dr-test-default-mocka
        namespace: istio-system
      spec:
        host: mocka.default.svc.cluster.local
        subsets:
          - labels:
              ASM_TRAFFIC_TAG: v1
            name: s1
          - labels:
              ASM_TRAFFIC_TAG: v2
            name: s2
          - labels:
              ASM_TRAFFIC_TAG: v3
            name: s3
      

      展開查看虛擬服務YAML樣本

      apiVersion: networking.istio.io/v1beta1
      kind: VirtualService
      metadata:
        labels:
          asm-system: 'true'
          provider: asm
          swimlane-group: test
        name: trafficlabel-vs-test-default-mocka
        namespace: istio-system
      spec:
        hosts:
          - mocka.default.svc.cluster.local
        http:
          - match:
              - sourceLabels:
                  ASM_TRAFFIC_TAG: v1
            route:
              - destination:
                  host: mocka.default.svc.cluster.local
                  subset: s1
          - match:
              - sourceLabels:
                  ASM_TRAFFIC_TAG: v2
            route:
              - destination:
                  host: mocka.default.svc.cluster.local
                  subset: s2
          - match:
              - sourceLabels:
                  ASM_TRAFFIC_TAG: v3
            route:
              - destination:
                  host: mocka.default.svc.cluster.local
                  subset: s3
      
  3. 分別建立三條泳道對應的引流規則。

    1. 流量泳道頁面的流量規則定義地區,單擊目標泳道右側操作列下的引流規則

    2. 添加引流規則對話方塊,配置相關資訊,然後單擊確定

      本文以泳道服務對應入口API均為/mock為例,為每條泳道配置相同的引流規則。

      配置項

      說明

      入口服務

      選擇mocka.default.svc.cluster.local

      引流規則

      配置名稱r1網域名稱*

      匹配請求的URI

      配置匹配方式精確匹配內容/mock

      添加Header匹配規則

      單擊添加Header匹配規則,配置名稱x-asm-prefer-tag匹配方式精確,三條泳道的匹配內容分別配置為s1s2s3

      為s1泳道添加引流規則的樣本圖如下:

      image.png

      三條泳道的引流規則建立成功後,樣本效果如下:image.png

      建立成功後,會自動產生每條泳道的引流規則,即虛擬服務。例如,針對s1泳道會產生如下的虛擬服務。

      展開查看虛擬服務YAML樣本

      apiVersion: networking.istio.io/v1beta1
      kind: VirtualService
      metadata:
        labels:
          asm-system: 'true'
          provider: asm
          swimlane-group: test
        name: swimlane-ingress-vs-test-s1
        namespace: istio-system
      spec:
        gateways:
          - istio-system/ingressgateway
        hosts:
          - '*'
        http:
          - match:
              - headers:
                  x-asm-prefer-tag:
                    exact: s1
                uri:
                  exact: /mock
            name: r1
            route:
              - destination:
                  host: mocka.default.svc.cluster.local
                  subset: s1
      

步驟三:驗證全鏈路灰階功能是否生效

  1. 擷取ASM網關的公網IP。具體操作,請參見擷取ASM網關地址

  2. 執行以下命令,設定環境變數。

    xxx.xxx.xxx.xxx為上一步擷取的IP。

    export ASM_GATEWAY_IP=xxx.xxx.xxx.xxx
  3. 驗證全鏈路灰階功能是否生效。

    1. 執行以下命令,查看s1泳道的訪問效果。

      x-asm-prefer-tag對應的值s1步驟二中第2步建立s1泳道時配置的泳道名稱。

      for i in {1..100};  do curl   -H 'x-asm-prefer-tag: s1' http://${ASM_GATEWAY_IP}/mock ;  echo ''; sleep 1; done;

      預期輸出:

      -> mocka(version: v1, ip: 172.17.0.54)-> mockb(version: v1, ip: 172.17.0.129)-> mockc(version: v1, ip: 172.17.0.130)

      由預期輸出得到,通過設定HTTP標題x-asm-prefer-tag: s1聲明的流量流向s1泳道下的相關服務,符合預期。

    2. 執行以下命令,查看s2泳道的訪問效果。

      x-asm-prefer-tag對應的值s2步驟二中第2步建立s2泳道時配置的泳道名稱。

      for i in {1..100};  do curl   -H 'x-asm-prefer-tag: s2' http://${ASM_GATEWAY_IP}/mock ;  echo ''; sleep 1; done;

      預期輸出:

      -> mocka(version: v2, ip: 172.17.0.9)-> mockb(version: v2, ip: 172.17.0.126)-> mockc(version: v2, ip: 172.17.0.128)

      由預期輸出得到,通過設定HTTP標題x-asm-prefer-tag: s2聲明的流量流向s2泳道下的相關服務,符合預期。

    3. 執行以下命令,查看s3泳道的訪問效果。

      x-asm-prefer-tag對應的值s3步驟二中第2步建立s3泳道時配置的泳道名稱。

      for i in {1..100};  do curl   -H 'x-asm-prefer-tag: s3' http://${ASM_GATEWAY_IP}/mock ;  echo ''; sleep 1; done;

      預期輸出:

      -> mocka(version: v3, ip: 172.17.0.132)-> mockb(version: v3, ip: 172.17.0.127)-> mockc(version: v3, ip: 172.17.0.69)

      由預期輸出得到,通過設定HTTP標題x-asm-prefer-tag: s3聲明的流量流向s3泳道下的相關服務,符合預期。

通過自訂虛擬服務為strict 模式的泳道引流

流量泳道預置了配置引流規則的功能。通過為泳道建立引流規則,可以在流量泳道對應的網關上建立虛擬服務,從而實現通過ASM入口網關向不同泳道引流(即轉寄請求)的效果。

流量泳道的引流規則包含針對要求標頭以及請求路徑的匹配規則,您可以通過自訂虛擬服務的方式來實現更複雜的匹配規則或者自訂請求路由的需求。

說明

在使用自訂虛擬服務為泳道引流時,不建議建立泳道的引流規則,因為自訂虛擬服務和泳道內建的引流規則可能會發生衝突,從而導致流量分發過程出現異常或不可預期的情況。

基於ASM網關建立自訂虛擬服務

  1. 以文中情境為例,在步驟二的第3步:分別建立三個泳道對應的引流規則,將建立引流規則的步驟,改為使用以下內容建立虛擬服務。具體操作,請參見管理虛擬服務

    apiVersion: networking.istio.io/v1beta1
    kind: VirtualService
    metadata:
      name: swimlane-ingress-vs-custom
      namespace: istio-system
    spec:
      gateways:
        - istio-system/ingressgateway
      hosts:
        - '*'
      http:
        - match: # 這條匹配規則表示精準匹配形如 env: dev 的要求標頭
            - headers:
                env:
                  exact: dev
          name: dev-route
          route:
            - destination:
                host: mocka.default.svc.cluster.local # 流量轉寄的目標服務
                subset: s2 # subset 填寫泳道的名稱
              weight: 50
            - destination:
                host: mocka.default.svc.cluster.local # 流量轉寄的目標服務
                subset: s3 # subset 填寫泳道的名稱
              weight: 50
        - name: base-route
          route:
            - destination:
                host: mocka.default.svc.cluster.local # 流量轉寄的目標服務
                subset: s1 # subset 填寫泳道的名稱
  2. 執行步驟三:驗證全鏈路灰階功能是否生效中的命令,訪問s1、s2、s3三條泳道的預期輸出如下:

    -> mocka(version: v1, ip: 192.168.0.50)-> mockb(version: v1, ip: 192.168.0.46)-> mockc(version: v1, ip: 192.168.0.48)

    執行以下命令,驗證在訪問s1泳道時帶有headerenv: dev的效果。

    for i in {1..100};  do curl -H 'x-asm-prefer-tag: s1' -H 'env: dev' http://${ASM_GATEWAY_IP}/mock ;  echo ''; sleep 1; done;

    預期輸出:

    展開查看預期輸出

    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)

    可以看到帶有headerenv: dev時訪問泳道s1返回的是v2和v3的鏈路,比例大約50:50左右。即對於帶有env: dev要求標頭的請求,請求將會以50:50的比例轉寄到s2和s3泳道,其餘請求將會被轉寄到s1泳道。

上述的虛擬服務在ASM網關上指定了一個自訂的路由規則,從而將流量轉寄到不同的流量泳道。當通過自訂虛擬服務為strict 模式的泳道引流時,想要將請求發往某條泳道,只需要在虛擬服務的路由目標subset欄位中填寫泳道名稱即可。當請求發往一條流量泳道後,後續的流量調用將保持在該泳道內部。

基於Sidecar建立自訂虛擬服務

除了在ASM網關上指定自訂路由規則外,您也可以通過生效在所有Sidecar上的虛擬服務來指定叢集內部服務訪問流量泳道內服務的引流規則。與ASM網關自訂路由規則不同,Sidecar虛擬服務不再需要gateway欄位,且hosts中填寫的是mocka服務的叢集本地服務網域名稱。樣本YAML如下:

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: swimlane-ingress-vs-custom
  namespace: istio-system
spec:
  hosts:
    - mocka.default.svc.cluster.local
  http:
    - match: # 這條匹配規則表示精準匹配形如 env: dev 的要求標頭
        - headers:
            env:
              exact: dev
      name: dev-route
      route:
        - destination:
            host: mocka.default.svc.cluster.local # 流量轉寄的目標服務
            subset: s2 # subset 填寫泳道的名稱
          weight: 50
        - destination:
            host: mocka.default.svc.cluster.local # 流量轉寄的目標服務
            subset: s3 # subset 填寫泳道的名稱
          weight: 50
    - name: base-route
      route:
        - destination:
            host: mocka.default.svc.cluster.local # 流量轉寄的目標服務
            subset: s1 # subset 填寫泳道的名稱
  1. 執行以下命令,驗證Sidecar模式下不帶env: dev要求標頭時訪問mocka服務。

    kubectl exec -it deploy/sleep -c sleep --  sh -c 'for i in $(seq 1 100);  do curl http://mocka:8000;  echo ""; sleep 1; done;'

    預期輸出:

    -> mocka(version: v1, ip: 192.168.0.50)-> mockb(version: v1, ip: 192.168.0.46)-> mockc(version: v1, ip: 192.168.0.48)

    可以看到,不帶env: dev要求標頭時訪問所有泳道返回的都是v1鏈路,說明流量全部進入了s1泳道。

  2. 執行以下命令,驗證Sidecar模式下帶有env: dev要求標頭時訪問mocka服務。

    kubectl exec -it deploy/sleep -c sleep --  sh -c 'for i in $(seq 1 100);  do curl -H "env: dev" http://mocka:8000;  echo ""; sleep 1; done;'

    預期輸出:

    展開查看訪問mocka服務的預期輸出

    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
    -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)

    可以看到,以上預期輸出與基於ASM網關建立自訂虛擬服務中的預期輸出一致,帶有env: dev要求標頭時訪問mocka服務,流量會以50:50的比例進入s2和s3泳道。

基於ASM網關建立自訂虛擬服務原理相同,當叢集內其它服務調用泳道內的mocka服務時,後續的請求調用鏈將一直保持在泳道內部。

相關文檔

  • 流量泳道分為嚴格與寬鬆兩種模式。關於兩種模式的說明和差異,請參見流量泳道概述

  • 當您的應用程式在調用鏈路中存在透傳要求標頭的行為時,寬鬆模式可以實現更為靈活的泳道使用情境,例如只發布了調用鏈路中的部分服務的新版本,基於這些新版本服務構建測試環境。具體操作,請參見使用寬鬆模式流量泳道實現全鏈路流量管理

  • 您可以基於VirtualService和DestinationRule等流量規則實現流量泳道,同時通過配置流量降級,在某個版本(或者其他特徵)的應用不可用時,將流量發往一個指定的降級版本(或其他特徵)的應用。具體操作,請參見基於流量規則配置實現流量泳道和流量降級