您可以使用寬鬆模式的流量泳道實現應用版本隔離,基於Baggage要求標頭透傳引流要求標頭,並將流量路由到不同泳道。泳道中服務相互調用時,若目標服務不存在當前泳道則轉寄至基準泳道,保障鏈路完整性,簡化流量管理。
開始閱讀前,請確保您已經閱讀並理解了使用寬鬆模式流量泳道實現全鏈路流量管理及其相關的內容。
情境概述
本樣本使用三個服務(mocka、mockb、mockc)建立三條泳道(s1、s2、s3)類比調用鏈路。基準泳道s1包含全部服務,s2僅包含mocka和mockc,s3隻有mockb。首先利用OpenTelemetry自動插裝為服務啟用Baggage能力,再建立三條寬鬆模式泳道,通過流量權重策略進行流量引導。
步驟一:部署樣本服務
為default命名空間啟用Sidecar網格代理自動注入。具體操作,請參見管理全域命名空間。
說明關於自動注入的更多資訊,請參見配置Sidecar注入策略。
使用以下內容,建立mock.yaml檔案。
對於每個執行個體服務Pod,都加入了
instrumentation.opentelemetry.io/inject-java: "true"
和instrumentation.opentelemetry.io/container-names: "default"
兩個註解,以聲明該執行個體服務使用Java語言實現,並要求OpenTelemetry Operator對名稱為default
的容器進行自動插裝。執行以下命令,部署執行個體服務。
kubectl apply -f mock.yaml
基於OpenTelemetry自動插裝機制,部署的服務Pod將自動具有在調用鏈路中傳遞Baggage的能力。
步驟二:建立泳道組和對應泳道
建立泳道組。
登入ASM控制台,在左側導覽列,選擇 。
在網格管理頁面,單擊目標執行個體名稱,然後在左側導覽列,選擇 。
在流量泳道頁面,單擊建立泳道組,在建立泳道組面板中,配置相關資訊,然後單擊確定。
配置項
說明
泳道組名稱
本樣本配置為test。
入口網關
選擇ingressgateway。
泳道模式
選擇寬鬆模式。
調用鏈路上下文透傳方式
選擇透傳baggage。
引流要求標頭
填寫x-asm-prefer-tag。
泳道服務
選擇目標Kubernetes叢集和default命名空間,在下方列表中選中mocka、mockb和mockc服務,單擊表徵圖,將目標服務添加到已選擇地區。
建立s1、s2、s3泳道,並分別綁定v1、v2、v3版本。
在流量泳道頁面的流量規則定義地區,單擊建立泳道。
在建立泳道對話方塊,配置相關資訊,然後單擊確定。
配置項
說明
泳道名稱
三條泳道分別配置為s1、s2、s3。
佈建服務標籤
標籤名稱:配置為ASM_TRAFFIC_TAG。
標籤值:三條泳道分別配置為v1、v2和v3。
添加服務
s1泳道:選擇mocka(default)、mockb(default)、mockc(default)。
s2泳道:選擇mocka(default)、mockc(default)。
s3泳道:選擇mockb(default)。
建立s1泳道的樣本圖如下。
三個泳道建立完成後,樣本效果如下。
預設情況下,您在泳道組中建立的第一個泳道將被設定為基準泳道。您也可以修改基準泳道,當流量發往其它泳道中不存在的服務時,通過回退機制將請求轉寄至基準泳道。關於修改基準泳道的具體操作,請參見在寬鬆模式中修改基準泳道。
您可以在控制台左側導覽列,選擇流量管理中心 > 目標規則或虛擬服務查看泳道組中的每個服務的泳道規則自動產生的目標規則DestinationRule和虛擬服務VirtualService。例如,針對mocka服務會自動建立如下DestinationRule和VirtualService。
建立基於權重的統一引流規則。
在流量泳道頁面的流量規則定義地區,單擊引流策略中的基於權重引流。
在設定統一引流規則對話方塊中,配置相關資訊,然後單擊確定。以下以泳道服務對應入口API為/mock為例,為三條泳道配置統一的引流規則。
配置項
說明
網域名稱
配置為*。
匹配請求的URI
配置匹配方式為首碼,匹配內容為/。
設定統一引流規則的樣本圖如下:
設定三條泳道的引流權重,引流權重確定了流量向每條泳道發送的比例。
在流量泳道頁面的流量規則定義地區,在每條泳道的引流權重列,單擊數字右側的按鈕,在編輯引流權重對話方塊,配置相關資訊,然後單擊確定。
配置項
說明
入口服務
三條泳道都配置為mocka.default.svc.cluster.local。
權重數值
對於s1泳道,配置為60。
對於s2泳道,配置為20。
對於s3泳道,配置為20。
編輯流量權重的樣本圖如下。
步驟三:驗證全鏈路灰階功能是否生效
擷取ASM網關的公網IP。具體操作,請參見擷取ASM網關地址。
執行以下命令,設定環境變數。xxx.xxx.xxx.xxx為上一步擷取的IP。
export ASM_GATEWAY_IP=xxx.xxx.xxx.xxx
驗證全鏈路灰階功能是否生效。
執行以下命令,查看三條泳道的訪問效果。
for i in {1..100}; do curl http://${ASM_GATEWAY_IP}/ ; echo ''; sleep 1; done;
預期輸出:
-> mocka(version: v1, ip: 192.168.0.193)-> mockb(version: v1, ip: 192.168.0.1)-> mockc(version: v1, ip: 192.168.0.190) -> mocka(version: v1, ip: 192.168.0.193)-> mockb(version: v3, ip: 192.168.0.2)-> mockc(version: v1, ip: 192.168.0.190) -> mocka(version: v1, ip: 192.168.0.193)-> mockb(version: v1, ip: 192.168.0.1)-> mockc(version: v1, ip: 192.168.0.190) -> mocka(version: v1, ip: 192.168.0.193)-> mockb(version: v1, ip: 192.168.0.1)-> mockc(version: v1, ip: 192.168.0.190) -> mocka(version: v2, ip: 192.168.0.184)-> mockb(version: v1, ip: 192.168.0.1)-> mockc(version: v2, ip: 192.168.0.189) -> mocka(version: v1, ip: 192.168.0.193)-> mockb(version: v1, ip: 192.168.0.1)-> mockc(version: v1, ip: 192.168.0.190) -> mocka(version: v2, ip: 192.168.0.184)-> mockb(version: v1, ip: 192.168.0.1)-> mockc(version: v2, ip: 192.168.0.189) -> mocka(version: v1, ip: 192.168.0.193)-> mockb(version: v1, ip: 192.168.0.1)-> mockc(version: v1, ip: 192.168.0.190) -> mocka(version: v1, ip: 192.168.0.193)-> mockb(version: v1, ip: 192.168.0.1)-> mockc(version: v1, ip: 192.168.0.190) -> mocka(version: v1, ip: 192.168.0.193)-> mockb(version: v3, ip: 192.168.0.2)-> mockc(version: v1, ip: 192.168.0.190) -> mocka(version: v1, ip: 192.168.0.193)-> mockb(version: v1, ip: 192.168.0.1)-> mockc(version: v1, ip: 192.168.0.190) -> mocka(version: v1, ip: 192.168.0.193)-> mockb(version: v1, ip: 192.168.0.1)-> mockc(version: v1, ip: 192.168.0.190) -> mocka(version: v2, ip: 192.168.0.184)-> mockb(version: v1, ip: 192.168.0.1)-> mockc(version: v2, ip: 192.168.0.189) -> mocka(version: v1, ip: 192.168.0.193)-> mockb(version: v1, ip: 192.168.0.1)-> mockc(version: v1, ip: 192.168.0.190) -> mocka(version: v1, ip: 192.168.0.193)-> mockb(version: v1, ip: 192.168.0.1)-> mockc(version: v1, ip: 192.168.0.190) -> mocka(version: v2, ip: 192.168.0.184)-> mockb(version: v1, ip: 192.168.0.1)-> mockc(version: v2, ip: 192.168.0.189) -> mocka(version: v1, ip: 192.168.0.193)-> mockb(version: v3, ip: 192.168.0.2)-> mockc(version: v1, ip: 192.168.0.190) -> mocka(version: v1, ip: 192.168.0.193)-> mockb(version: v1, ip: 192.168.0.1)-> mockc(version: v1, ip: 192.168.0.190) -> mocka(version: v2, ip: 192.168.0.184)-> mockb(version: v1, ip: 192.168.0.1)-> mockc(version: v2, ip: 192.168.0.189) -> mocka(version: v2, ip: 192.168.0.184)-> mockb(version: v1, ip: 192.168.0.1)-> mockc(version: v2, ip: 192.168.0.189) -> mocka(version: v1, ip: 192.168.0.193)-> mockb(version: v1, ip: 192.168.0.1)-> mockc(version: v1, ip: 192.168.0.190) -> mocka(version: v1, ip: 192.168.0.193)-> mockb(version: v1, ip: 192.168.0.1)-> mockc(version: v1, ip: 192.168.0.190) -> mocka(version: v1, ip: 192.168.0.193)-> mockb(version: v1, ip: 192.168.0.1)-> mockc(version: v1, ip: 192.168.0.190) -> mocka(version: v1, ip: 192.168.0.193)-> mockb(version: v3, ip: 192.168.0.2)-> mockc(version: v1, ip: 192.168.0.190) -> mocka(version: v1, ip: 192.168.0.193)-> mockb(version: v1, ip: 192.168.0.1)-> mockc(version: v1, ip: 192.168.0.190) -> mocka(version: v1, ip: 192.168.0.193)-> mockb(version: v1, ip: 192.168.0.1)-> mockc(version: v1, ip: 192.168.0.190) -> mocka(version: v1, ip: 192.168.0.193)-> mockb(version: v3, ip: 192.168.0.2)-> mockc(version: v1, ip: 192.168.0.190) -> mocka(version: v2, ip: 192.168.0.184)-> mockb(version: v1, ip: 192.168.0.1)-> mockc(version: v2, ip: 192.168.0.189) -> mocka(version: v1, ip: 192.168.0.193)-> mockb(version: v3, ip: 192.168.0.2)-> mockc(version: v1, ip: 192.168.0.190) -> mocka(version: v1, ip: 192.168.0.193)-> mockb(version: v1, ip: 192.168.0.1)-> mockc(version: v1, ip: 192.168.0.190) -> mocka(version: v1, ip: 192.168.0.193)-> mockb(version: v3, ip: 192.168.0.2)-> mockc(version: v1, ip: 192.168.0.190) -> mocka(version: v2, ip: 192.168.0.184)-> mockb(version: v1, ip: 192.168.0.1)-> mockc(version: v2, ip: 192.168.0.189) -> mocka(version: v1, ip: 192.168.0.193)-> mockb(version: v1, ip: 192.168.0.1)-> mockc(version: v1, ip: 192.168.0.190) -> mocka(version: v1, ip: 192.168.0.193)-> mockb(version: v1, ip: 192.168.0.1)-> mockc(version: v1, ip: 192.168.0.190) -> mocka(version: v1, ip: 192.168.0.193)-> mockb(version: v3, ip: 192.168.0.2)-> mockc(version: v1, ip: 192.168.0.190) -> mocka(version: v2, ip: 192.168.0.184)-> mockb(version: v1, ip: 192.168.0.1)-> mockc(version: v2, ip: 192.168.0.189) -> mocka(version: v1, ip: 192.168.0.193)-> mockb(version: v1, ip: 192.168.0.1)-> mockc(version: v1, ip: 192.168.0.190) -> mocka(version: v1, ip: 192.168.0.193)-> mockb(version: v1, ip: 192.168.0.1)-> mockc(version: v1, ip: 192.168.0.190) -> mocka(version: v1, ip: 192.168.0.193)-> mockb(version: v1, ip: 192.168.0.1)-> mockc(version: v1, ip: 192.168.0.190) -> mocka(version: v1, ip: 192.168.0.193)-> mockb(version: v1, ip: 192.168.0.1)-> mockc(version: v1, ip: 192.168.0.190) -> mocka(version: v1, ip: 192.168.0.193)-> mockb(version: v1, ip: 192.168.0.1)-> mockc(version: v1, ip: 192.168.0.190) -> mocka(version: v1, ip: 192.168.0.193)-> mockb(version: v1, ip: 192.168.0.1)-> mockc(version: v1, ip: 192.168.0.190)
可以看到,流量以約6:2:2的比例發送到s1、s2、s3泳道,並由s1作為基準泳道,當調用鏈路中不存在某個服務的特定版本時,將會調用s1泳道中的對應服務。