Service Mesh (ASM)支援將應用的多個版本或者特徵隔離成一個獨立的運行環境(即泳道),然後通過設定泳道規則,將滿足規則的請求流量路由到目標版本或特徵的應用上。在生產環境中,開發人員可能會希望使用泳道對穩定版本和灰階版本進行隔離,並根據使用者身份路由至不同的泳道中。具體來說,您可能希望指定一部分特定身份的使用者路由至灰階版本進行測試,其餘使用者則通過權重的方式隨機匹配一定數量的請求路由至灰階版本。本文將介紹如何結合泳道和雜湊打標來實現按使用者身份的灰階測試。
前提條件
已建立並添加叢集到ASM執行個體,執行個體版本為1.18及以上。具體操作,請參見添加叢集到ASM執行個體。
已部署入口網關。具體操作,請參見建立入口網關。
操作步驟
本樣本情境將建立三個應用,調用鏈如下圖。
mocka,包含v1版本。
mockb,包含v1版本。
mockc,包含v1版本和v2版本。
其中應用通過x-user-id
要求標頭來標識使用者身份,同時應用之間也會透傳此要求標頭。本情境將示範以下內容:
當
x-user-id: jason
時,請求流向新版本應用。對於其餘使用者,根據
x-user-id
雜湊,並按照雜湊結果將指定比例的使用者路由到新版本。
步驟一:部署樣本應用
使用以下內容建立sample.yaml。
使用資料面叢集的kubeconfig,執行以下命令,部署樣本應用。
kubectl apply -f sample.yaml
步驟二:建立網關規則
使用以下內容建立ingressgateway且命名空間為istio-system的網關規則。具體操作,請參見管理網關規則。
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:
- '*'
步驟三:建立泳道組和泳道
建立泳道組。
登入ASM控制台,在左側導覽列,選擇 。
在網格管理頁面,單擊目標執行個體名稱,然後在左側導覽列,選擇
。在流量泳道頁面,單擊建立泳道組,在建立泳道組面板,配置相關資訊,然後單擊確定。
配置項
說明
泳道組名稱
本樣本配置為canary。
入口網關
選擇ingressgateway。
泳道模式
選擇寬鬆模式。
調用鏈路上下文透傳方式
選擇透傳trace id。
trace id要求標頭
本樣本配置為x-user-id。
引流要求標頭
用於網關根據要求標頭內容向不同泳道引流及泳道上下文保持,可任意指定。本樣本配置為x-asm-prefer-tag。
泳道服務
選擇目標Kubernetes叢集和default命名空間,在下方列表中選中mocka、mockb和mockc服務,單擊表徵圖,添加目標服務到已選擇地區。
建立s1和s2泳道,並分別綁定v1和v2版本。
在流量泳道頁面的流量規則定義地區,單擊建立泳道。
在建立泳道對話方塊,配置相關資訊,然後單擊確定。
配置項
說明
泳道名稱
分別配置為s1和s2。
佈建服務標籤
標籤名稱:選擇ASM_TRAFFIC_TAG
標籤值:兩條泳道分別選擇v1、v2。
添加服務
s1泳道:選擇mocka(default)、mockb(default)、mockc(default)。
s2泳道:選擇mockc(default)。
建立s1泳道的樣本圖如下:
兩條泳道建立完成後,樣本效果如下:
說明預設情況下,您在泳道組中建立的第一條泳道將被設定為基準泳道。您可以修改基準泳道,當流量發往其他泳道中不存在的服務時,通過回退機制將請求轉寄至基準泳道。具體操作,請參見在寬鬆模式中修改基準泳道。
建立泳道對應的引流規則。
使用以下內容,為泳道建立網關引流規則,該引流規則可以分為三部分:
包含
x-user-id: jason
的請求流向s2泳道,並為請求加入x-asm-prefer-tag: s2
要求標頭用於標識該請求流向s2泳道。包含
x-asm-prefer-tag: s2
的請求流向s2泳道。包含
x-asm-prefer-tag: s1
的請求流向s1泳道。
步驟四:部署雜湊打標外掛程式
使用以下內容,建立wasm.yaml。
apiVersion: extensions.istio.io/v1alpha1 kind: WasmPlugin metadata: name: hash-tagging namespace: istio-system spec: imagePullPolicy: IfNotPresent selector: matchLabels: istio: ingressgateway url: registry-cn-hangzhou.ack.aliyuncs.com/acs/asm-wasm-hash-tagging:v1.22.6.2-g72656ba-aliyun phase: AUTHN pluginConfig: rules: - header: x-user-id modulo: 100 tagHeader: x-asm-prefer-tag policies: # 20% 的使用者的請求流量會路由至泳道 s2 - range: 20 tagValue: s2 # 80% 的使用者的請求流量會路由至泳道 s1 - range: 100 tagValue: s1
使用ASM執行個體的kubeconfig,執行以下命令,部署打標外掛程式。
kubectl apply -f wasm.yaml
步驟五:驗證
執行以下命令,配置入口網關地址的臨時環境變數。
export GATEWAY_ADDRESS=`kubectl get svc -n istio-system | grep istio-ingressgateway | awk '{print $4}'`
執行以下命令,以Jason身份訪問應用。
curl ${GATEWAY_ADDRESS} -H 'x-user-id: jason'
預期輸出:
-> mocka(version: v1, ip: 10.0.0.15)-> mockb(version: v1, ip: 10.0.0.130)-> mockc(version: v2, ip: 10.0.0.133)%
可以看到,請求直接路由到mockc應用的v2版本。
執行以下命令,指定隨機使用者路由到新版本。
for i in 'bob' 'stacy' 'jessie' 'vance' 'jack'; do curl ${GATEWAY_ADDRESS} -H "x-user-id: $i";echo " user $i requested"; done
預期輸出:
-> mocka(version: v1, ip: 10.0.0.15)-> mockb(version: v1, ip: 10.0.0.130)-> mockc(version: v1, ip: 10.0.0.131) user bob requested -> mocka(version: v1, ip: 10.0.0.15)-> mockb(version: v1, ip: 10.0.0.130)-> mockc(version: v1, ip: 10.0.0.131) user stacy requested -> mocka(version: v1, ip: 10.0.0.15)-> mockb(version: v1, ip: 10.0.0.130)-> mockc(version: v2, ip: 10.0.0.133) user jessie requested -> mocka(version: v1, ip: 10.0.0.15)-> mockb(version: v1, ip: 10.0.0.130)-> mockc(version: v1, ip: 10.0.0.131) user vance requested -> mocka(version: v1, ip: 10.0.0.15)-> mockb(version: v1, ip: 10.0.0.130)-> mockc(version: v2, ip: 10.0.0.133) user jack requested
可以看到,使用者Jessie和Jack的請求直接路由到了mockc應用的v2版本,其他使用者路由到了v1版本。