當您需要在多個服務間實現全鏈路的灰階發布時,可以通過配置TrafficLabel來識別流量特徵,將網關入口流量分為正常流量和灰階流量。灰階流量特徵會在請求調用鏈經過的各個服務間進行傳遞,從而實現全鏈路灰階發布。本文介紹如何通過TrafficLabel實現微服務的全鏈路灰階發布。
前提條件
已建立ASM企業版或旗艦版執行個體,且版本為1.17.2.22及以上。具體操作,請參見建立ASM執行個體或升級ASM執行個體。
已添加叢集到ASM執行個體。具體操作,請參見添加叢集到ASM執行個體。
已建立ASM網關。具體操作,請參見建立入口網關。
功能介紹
灰階發布有多種實現方式,例如基於ASM完成藍綠和灰階發布。該灰階方式偏重於單個服務的發布,通過使用Istio原生提供的VirtualService標籤路由和權重分流進行實現。某些情境下,僅限於兩個服務間的灰階不能滿足需求。
ASM基於流量打標和標籤路由功能,提供全鏈路灰階功能,協助您解決多個服務同時發布灰階版本的問題。當業務進行功能灰階驗證時,將入口流量分為正常流量和灰階流量,對請求流量進行流量特徵識別。若請求流量為灰階流量,則將請求灰階的應用服務。該情境不再是簡單的按流量比例灰階分發到後端不同的版本,而且灰階流量特徵會在請求調用鏈經過的各個服務間進行傳遞。更多資訊,請參見流量標籤TrafficLabel說明。
配置說明
您可以單擊設定檔,直接下載部署樣本及相關設定檔。樣本中應用服務調用鏈路如下:

本樣本服務中的應用A在調用B時,已包含傳播HTTP標題my-trace-id的代碼實現邏輯。更多資訊,請參見設定檔中的src/mock-abc/go/main.go。
如果您使用其他的應用樣本,請確保在調用中包含傳播HTTP標題的邏輯,後續的功能依賴於這個傳播的HTTP標題。
步驟一:在ACK叢集下部署樣本應用
步驟二:初始化路由規則配置
使用以下內容,建立routing.yaml檔案。
使用ASM執行個體的KubeConfig,執行以下命令,配置路由。
kubectl apply -n default -f routing.yaml驗證服務訪問是否可以連通。
執行以下命令,設定環境變數。
xxxx為上一步擷取的IP。export ASM_GATEWAY_IP=xxxx執行以下命令,驗證服務訪問是否可以連通。
for i in {1..200}; do curl -H'my-asm-prefer-tag: version-base' -H'my-trace-id: x000'$i http://${ASM_GATEWAY_IP}/; echo; sleep 1; done;預期輸出:
-> mocka(version: canary, ip: 172.17.0.129)-> mockb(version: base, ip: 172.17.0.70) -> mocka(version: base, ip: 172.17.0.132)-> mockb(version: base, ip: 172.17.0.70) -> mocka(version: base, ip: 172.17.0.132)-> mockb(version: canary, ip: 172.17.0.54) -> mocka(version: canary, ip: 172.17.0.129)-> mockb(version: canary, ip: 172.17.0.54) -> mocka(version: canary, ip: 172.17.0.129)-> mockb(version: base, ip: 172.17.0.70) -> mocka(version: base, ip: 172.17.0.132)-> mockb(version: base, ip: 172.17.0.70) -> mocka(version: canary, ip: 172.17.0.129)-> mockb(version: canary, ip: 172.17.0.54)預期輸出表明從ASM入口網關到應用服務A,以及從應用A調用B的過程,負載平衡是隨機的路由策略。 通過
curl命令指定的my-asm-prefer-tag或者其他要求標頭都不會改變隨機路由的策略。
步驟三:為樣本應用設定流量標籤
ASM支援通過TrafficLabel CRD設定流量標籤,然後根據流量標籤將流量路由到不同的工作負載。更多資訊,請參見流量標籤TrafficLabel說明。
使用以下內容,建立trafficlabel.yaml檔案。
配置說明如下:
TrafficLabel
trafficlabel-ns配置針對命名空間default下所有的應用服務生效,即樣本中部署的mocka和mockb服務;TrafficLabelingressgateway針對網關ingressgateway生效。用於區分版本的要求標頭為
my-asm-prefer-tag,因此getExternalInboundRequestHeader中的第一個參數對應設定為my-asm-prefer-tag。請您根據實際情況進行修改。傳播的HTTP標題為
my-trace-id,因此getExternalInboundRequestHeader中的第二個參數對應設定為my-trace-id。請您根據實際情況進行修改。
使用ASM執行個體的KubeConfig,執行以下命令,部署TrafficLabel。
kubectl apply -f trafficlabel.yaml
步驟四:配置標籤路由規則
您可以通過配置標籤路由規則,控制流程量的走向。
一、驗證服務提供側的灰階
驗證應用A→B的調用是否符合預期,其中包括流向A的灰階流量打到灰階版本,以及Base流量打到Base版本。
配置應用B的基於流量標籤的路由規則後,流量示意圖如下。
使用以下內容,建立vs-tf-mockb.yaml檔案。
apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: vs-mockb spec: hosts: - mockb http: - route: - destination: host: mockb subset: $asm-labels-sample執行以下命令,在A服務側生效路由規則。
kubectl apply -n default -f vs-tf-mockb.yaml執行以下命令,驗證流向A的灰階流量打到灰階版本。
for i in {1..200}; do curl -H'my-asm-prefer-tag: version-canary' -H'my-trace-id: x000'$i http://${ASM_GATEWAY_IP}/; echo; sleep 1; done;預期輸出:
-> mocka(version: canary, ip: 172.17.0.129)-> mockb(version: canary, ip: 172.17.0.54) -> mocka(version: base, ip: 172.17.0.132)-> mockb(version: canary, ip: 172.17.0.54) -> mocka(version: base, ip: 172.17.0.132)-> mockb(version: canary, ip: 172.17.0.54) -> mocka(version: canary, ip: 172.17.0.129)-> mockb(version: canary, ip: 172.17.0.54) -> mocka(version: canary, ip: 172.17.0.129)-> mockb(version: canary, ip: 172.17.0.54) -> mocka(version: base, ip: 172.17.0.132)-> mockb(version: canary, ip: 172.17.0.54)執行以下命令,驗證流向A的Base流量打到Base版本。
for i in {1..200}; do curl -H'my-asm-prefer-tag: version-base' -H'my-trace-id: x000'$i http://${ASM_GATEWAY_IP}/; echo; sleep 1; done;預期輸出:
-> mocka(version: canary, ip: 172.17.0.129)-> mockb(version: base, ip: 172.17.0.70) -> mocka(version: base, ip: 172.17.0.132)-> mockb(version: base, ip: 172.17.0.70) -> mocka(version: base, ip: 172.17.0.132)-> mockb(version: base, ip: 172.17.0.70) -> mocka(version: canary, ip: 172.17.0.129)-> mockb(version: base, ip: 172.17.0.70) -> mocka(version: base, ip: 172.17.0.132)-> mockb(version: base, ip: 172.17.0.70) -> mocka(version: canary, ip: 172.17.0.129)-> mockb(version: base, ip: 172.17.0.70) -> mocka(version: canary, ip: 172.17.0.129)-> mockb(version: base, ip: 172.17.0.70) -> mocka(version: base, ip: 172.17.0.132)-> mockb(version: base, ip: 172.17.0.70)預期輸出表明入口流量訪問A服務未流向指定版本。您需要配置A服務的基於流量標籤的路由規則。具體操作,請參見下一步。
二、驗證全鏈路灰階
配置A服務的TrafficLabel路由vs-tf-mocka.yaml,在ASM網關側生效。預期結果為入口請求灰階流量打到A的灰階版本,Base流量打到A的Base版本,並傳遞到B服務。
配置應用A的基於流量標籤的路由規則後,流量示意圖如下。
使用以下樣本,建立檔案vs-tf-mocka.yaml。
apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: vs-gateway-mocka spec: gateways: - simple-gateway hosts: - "*" http: - route: - destination: host: mocka subset: $asm-labels-sample執行以下命令,在ASM網關側生效路由規則。
kubectl apply -n default -f vs-tf-mocka.yaml執行以下命令,驗證入口請求灰階流量打到A的灰階版本。
for i in {1..200}; do curl -H'my-asm-prefer-tag: version-canary' -H'my-trace-id: x000'$i http://${ASM_GATEWAY_IP}/; echo; sleep 1; done;預期輸出:
-> mocka(version: canary, ip: 172.17.0.69)-> mockb(version: canary, ip: 172.17.0.130) -> mocka(version: canary, ip: 172.17.0.69)-> mockb(version: canary, ip: 172.17.0.130) -> mocka(version: canary, ip: 172.17.0.69)-> mockb(version: canary, ip: 172.17.0.130) -> mocka(version: canary, ip: 172.17.0.69)-> mockb(version: canary, ip: 172.17.0.130) -> mocka(version: canary, ip: 172.17.0.69)-> mockb(version: canary, ip: 172.17.0.130) -> mocka(version: canary, ip: 172.17.0.69)-> mockb(version: canary, ip: 172.17.0.130) -> mocka(version: canary, ip: 172.17.0.69)-> mockb(version: canary, ip: 172.17.0.130)執行以下命令,驗證Base流量打到A的Base版本,並傳遞到B服務。
for i in {1..200}; do curl -H'my-asm-prefer-tag: version-base' -H'my-trace-id: x000'$i http://${ASM_GATEWAY_IP}/; echo; sleep 1; done;預期輸出:
-> mocka(version: base, ip: 172.17.0.90)-> mockb(version: base, ip: 172.17.0.93) -> mocka(version: base, ip: 172.17.0.90)-> mockb(version: base, ip: 172.17.0.93) -> mocka(version: base, ip: 172.17.0.90)-> mockb(version: base, ip: 172.17.0.93) -> mocka(version: base, ip: 172.17.0.90)-> mockb(version: base, ip: 172.17.0.93) -> mocka(version: base, ip: 172.17.0.90)-> mockb(version: base, ip: 172.17.0.93) -> mocka(version: base, ip: 172.17.0.90)-> mockb(version: base, ip: 172.17.0.93) -> mocka(version: base, ip: 172.17.0.90)-> mockb(version: base, ip: 172.17.0.93)
三、驗證路由權重
當在應用A上配置基於權重與基於流量標籤的路由規則後,流量示意圖如下。
使用以下內容,建立vs-tf-mocka-90-10.yaml檔案。
apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: vs-gateway-mocka spec: gateways: - simple-gateway hosts: - "*" http: - route: - destination: host: mocka subset: version-base weight: 90 - destination: host: mocka subset: $asm-labels-sample weight: 10執行以下命令,在ASM網關側生效路由規則。
kubectl apply -n default -f vs-tf-mocka-90-10.yaml執行以下命令,驗證入口請求灰階流量打到應用A的版本。
for i in {1..200}; do curl -H'my-asm-prefer-tag: version-canary' -H'my-trace-id: x000'$i http://${ASM_GATEWAY_IP}/; echo; sleep 1; done;預期輸出:
-> mocka(version: base, ip: 172.17.0.90)-> mockb(version: canary, ip: 172.17.0.130) -> mocka(version: base, ip: 172.17.0.90)-> mockb(version: canary, ip: 172.17.0.130) -> mocka(version: base, ip: 172.17.0.90)-> mockb(version: canary, ip: 172.17.0.130) -> mocka(version: base, ip: 172.17.0.90)-> mockb(version: canary, ip: 172.17.0.130) -> mocka(version: base, ip: 172.17.0.90)-> mockb(version: canary, ip: 172.17.0.130) -> mocka(version: base, ip: 172.17.0.90)-> mockb(version: canary, ip: 172.17.0.130) -> mocka(version: base, ip: 172.17.0.90)-> mockb(version: canary, ip: 172.17.0.130) -> mocka(version: base, ip: 172.17.0.90)-> mockb(version: canary, ip: 172.17.0.130) -> mocka(version: base, ip: 172.17.0.90)-> mockb(version: canary, ip: 172.17.0.130) -> mocka(version: canary, ip: 172.17.0.69)-> mockb(version: canary, ip: 172.17.0.130)由預期輸出得到,入口請求灰階流量約90%左右流嚮應用A的Base版本,10%左右流向到Canary版本。在上述生效的路由規則中,90%的請求進入應用A的Base版本,剩下的10%請求按照指定的要求標頭
my-asm-prefer-tag的值來決定去向,而請求命令中指定version-canary為要求標頭my-asm-prefer-tag的值,即這10%的請求將流向Canary版本。執行以下命令,驗證入口請求的Base版本流量全部轉到應用A的Base版本。
for i in {1..200}; do curl -H'my-asm-prefer-tag: version-base' -H'my-trace-id: x000'$i http://${ASM_GATEWAY_IP}/; echo; sleep 1; done;預期輸出:
-> mocka(version: base, ip: 172.17.0.90)-> mockb(version: base, ip: 172.17.0.93) -> mocka(version: base, ip: 172.17.0.90)-> mockb(version: base, ip: 172.17.0.93) -> mocka(version: base, ip: 172.17.0.90)-> mockb(version: base, ip: 172.17.0.93) -> mocka(version: base, ip: 172.17.0.90)-> mockb(version: base, ip: 172.17.0.93) -> mocka(version: base, ip: 172.17.0.90)-> mockb(version: base, ip: 172.17.0.93) -> mocka(version: base, ip: 172.17.0.90)-> mockb(version: base, ip: 172.17.0.93) -> mocka(version: base, ip: 172.17.0.90)-> mockb(version: base, ip: 172.17.0.93) -> mocka(version: base, ip: 172.17.0.90)-> mockb(version: base, ip: 172.17.0.93) -> mocka(version: base, ip: 172.17.0.90)-> mockb(version: base, ip: 172.17.0.93) -> mocka(version: base, ip: 172.17.0.90)-> mockb(version: base, ip: 172.17.0.93)上述生效的路由規則中,90%的請求進入Base版本,剩下的10%請求按照指定的要求標頭
my-asm-prefer-tag的值來決定去向,而請求命令中指定version-base為要求標頭my-asm-prefer-tag的值,即這10%的請求將流向Base版本。