當您需要對整條調用鏈路進行灰階發布或版本隔離時,可以使用strict 模式的流量泳道,將應用的相關版本(或其他特徵)隔離成獨立的運行環境,確保只有符合特定條件的流量被路由到新的服務版本,提高發布過程的穩定性和可控性。
前提條件
已建立ASM企業版或旗艦版執行個體,且版本為1.18.2.111及以上。具體操作,請參見建立ASM執行個體或升級ASM執行個體。
說明若您的執行個體版本為1.17.2.22及以上,1.18.2.111以下,請參見使用泳道模式下的流量管理功能。
已添加叢集到ASM執行個體。具體操作,請參見添加叢集到ASM執行個體。
已建立名稱為ingressgateway的ASM入口網關。具體操作,請參見建立入口網關服務。
已建立名稱為ingressgateway且命名空間為istio-system的網關規則。具體操作,請參見管理網關規則。
樣本說明
本樣本使用mocka、mockb、mockc三個服務建立代表格服務調用鏈三個版本的三條泳道:s1、s2、s3。
步驟一:部署樣本服務
為default命名空間啟用Sidecar網格代理自動注入。具體操作,請參見啟用自動注入。
關於自動注入的更多資訊,請參見配置Sidecar注入策略。
在ACK叢集中執行以下命令,部署樣本服務。
kubectl apply -f https://alibabacloudservicemesh.oss-cn-beijing.aliyuncs.com/asm-labs/swimlane/v1/mock-tracing-v1.yaml kubectl apply -f https://alibabacloudservicemesh.oss-cn-beijing.aliyuncs.com/asm-labs/swimlane/v2/mock-tracing-v2.yaml kubectl apply -f https://alibabacloudservicemesh.oss-cn-beijing.aliyuncs.com/asm-labs/swimlane/v3/mock-tracing-v3.yaml
步驟二:建立泳道組和對應泳道
建立泳道組。
登入ASM控制台,在左側導覽列,選擇 。
在網格管理頁面,單擊目標執行個體名稱,然後在左側導覽列,選擇 。
在流量泳道頁面,單擊建立泳道組,在建立泳道組面板,配置相關資訊,然後單擊確定。
配置項
說明
泳道組名稱
本樣本配置為test。
入口網關
選擇ingressgateway。
泳道模式
選擇strict 模式。
泳道服務
選擇目標Kubernetes叢集和default命名空間,在下方列表中選中mocka、mockb和mockc服務,單擊表徵圖,添加目標服務到已選擇地區。
建立s1、s2、s3泳道,並分別綁定v1、v2、v3版本。
在流量泳道頁面的流量規則定義地區,單擊建立泳道。
在建立泳道對話方塊,配置相關資訊,然後單擊確定。
配置項
說明
泳道名稱
三條泳道分別配置為s1、s2、s3。
佈建服務標籤
標籤名稱:選擇ASM_TRAFFIC_TAG。
標籤值:三條泳道分別選擇v1、v2、v3。
建立s1泳道的樣本圖如下:
三條泳道建立完成後,樣本效果如下:
三條泳道建立完成後,針對泳道組中的每個服務都將產生泳道規則對應的目標規則和虛擬服務。您可以在控制台左側導覽列,選擇
或虛擬服務進行查看。例如,針對mocka服務會自動建立如下目標規則和虛擬服務。
分別建立三條泳道對應的引流規則。
在流量泳道頁面的流量規則定義地區,單擊目標泳道右側操作列下的引流規則。
在添加引流規則對話方塊,配置相關資訊,然後單擊確定。
本文以泳道服務對應入口API均為
/mock
為例,為每條泳道配置相同的引流規則。配置項
說明
入口服務
選擇mocka.default.svc.cluster.local。
引流規則
配置名稱為r1,網域名稱為*。
匹配請求的URI
配置匹配方式為精確,匹配內容為/mock。
添加Header匹配規則
單擊添加Header匹配規則,配置名稱為x-asm-prefer-tag,匹配方式為精確,三條泳道的匹配內容分別配置為s1、s2、s3。
為s1泳道添加引流規則的樣本圖如下:
三條泳道的引流規則建立成功後,樣本效果如下:
建立成功後,會自動產生每條泳道的引流規則,即虛擬服務。例如,針對s1泳道會產生如下的虛擬服務。
步驟三:驗證全鏈路灰階功能是否生效
擷取ASM網關的公網IP。具體操作,請參見擷取ASM網關地址。
執行以下命令,設定環境變數。
xxx.xxx.xxx.xxx
為上一步擷取的IP。export ASM_GATEWAY_IP=xxx.xxx.xxx.xxx
驗證全鏈路灰階功能是否生效。
執行以下命令,查看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泳道下的相關服務,符合預期。執行以下命令,查看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泳道下的相關服務,符合預期。執行以下命令,查看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網關建立自訂虛擬服務
以文中情境為例,在步驟二的第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 填寫泳道的名稱
執行步驟三:驗證全鏈路灰階功能是否生效中的命令,訪問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泳道時帶有header
env: 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;
預期輸出:
可以看到帶有header
env: 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 填寫泳道的名稱
執行以下命令,驗證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泳道。執行以下命令,驗證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;'
預期輸出:
可以看到,以上預期輸出與基於ASM網關建立自訂虛擬服務中的預期輸出一致,帶有
env: dev
要求標頭時訪問mocka服務,流量會以50:50的比例進入s2和s3泳道。
與基於ASM網關建立自訂虛擬服務原理相同,當叢集內其它服務調用泳道內的mocka服務時,後續的請求調用鏈將一直保持在泳道內部。
相關文檔
流量泳道分為嚴格與寬鬆兩種模式。關於兩種模式的說明和差異,請參見流量泳道概述。
當您的應用程式在調用鏈路中存在透傳要求標頭的行為時,寬鬆模式可以實現更為靈活的泳道使用情境,例如只發布了調用鏈路中的部分服務的新版本,基於這些新版本服務構建測試環境。具體操作,請參見使用寬鬆模式流量泳道實現全鏈路流量管理。
您可以基於VirtualService和DestinationRule等流量規則實現流量泳道,同時通過配置流量降級,在某個版本(或者其他特徵)的應用不可用時,將流量發往一個指定的降級版本(或其他特徵)的應用。具體操作,請參見基於流量規則配置實現流量泳道和流量降級。