概述
灰度發佈是一種常見的對新版本應用服務的發佈手段,其特點在於能夠將流量在服務的穩定版本和灰度版本之間時刻切換,以幫助我們用更加可靠的方式實現服務的升級。在流量比例切換的過程中,我們可以逐步驗證新版本服務的功能特性、可靠性等特性,一旦新版本服務不滿足需求,還可以時刻將流量切回老版本,因此灰度發佈也是一種在軟件工程領域中得到廣泛應用的發佈方案。
當前,服務網格的無侵入式灰度發佈已經是一個非常成熟的特性:我們可以同時部署服務的多個版本,使用 DestinationRule 來制定工作負載的版本定義,並使用 VirtualService 的流量比例分割的能力將不同比例的服務流量發往不同版本的工作負載,直至所有流量都直接發往新版本服務。
然而,在雲原生應用廣泛採用的大背景下,應用程序往往不再以單體服務的形式存在,而是被分解爲一系列雲原生服務部署在 Kubernetes 集羣中,服務之間存在調用鏈路、共同對外提供服務。
當服務之間存在調用鏈路時,對服務的灰度發佈往往不侷限於單個服務,而是需要對服務的整條請求鏈路進行環境隔離與流量控制,即:保證灰度流量只發往調用鏈路中服務的灰度版本,實現調用鏈路之間相互隔離的隔離環境。針對整個調用鏈路的流量管理需求爲服務網格的無侵入式流量管理方案帶來了新的挑戰:
- 流量規則複雜度高
基於 Istio 社區的 VirtualService 和 DestinationRule 規則需要針對每個服務進行單獨定製,在全鏈路流量管理的場景下會提高配置出錯的機率與服務流量的維護成本。
- 流量管理靈活度低
針對不同的全鏈路流量管理需求,難以通過簡單調整流量規則實現全部需求(例如:針對一條灰度鏈路,僅發佈鏈路中部分服務的新版本)。
服務網格 ASM 支持將應用的相關版本(或者其他特徵)隔離成一個獨立的運行環境(即泳道),然後通過設置泳道規則,將滿足規則的請求流量路由到目標版本(或者其他特徵)的應用上。ASM 流量泳道具有以下特點:
- 配置簡單
通過使用 ASM 流量泳道功能,您僅需制定少量的治理規則,便可構建從網關到整個後端服務的多個流量隔離環境,有效保障多個服務順利安全發佈以及服務多版本並行開發,進一步促進業務的快速發展。
- 支持不同維度的全鏈路流量管理需求
ASM 流量泳道支持嚴格模式與寬鬆模式,兩種模式各自有着自己的優勢、限制以及適配使用場景,適配更多樣的流量治理需求。
流量泳道的嚴格模式與寬鬆模式
1. 嚴格模式的流量泳道
在嚴格模式下,每條流量泳道中包含調用鏈路上的全部服務。該模式對於您的應用程序無任何要求,只需配置流量泳道即可實現。如下圖所示:
2. 寬鬆模式的流量泳道
在寬鬆模式下,您只需要確保創建一條包含調用鏈路中所有服務的泳道:基線泳道。其它泳道可以不包含調用鏈路上的全部服務。當一個泳道中的服務進行相互調用時,若目標服務在當前泳道中不存在,則請求將被轉發到基線泳道中的相同服務,並在請求目標存在當前泳道中存在時將請求重新轉發回當前泳道。使用寬鬆模式的流量泳道時,您的應用程序必須包含一個能夠在整條調用鏈路中透傳的請求頭(鏈路透傳請求頭),並另外使用一個引流請求頭用來根據請求頭內容將流量路由到不同的流量泳道上。如下圖所示:
本文接下來主要演示嚴格模式泳道在服務網格 ASM 中的應用。
演示:使用嚴格模式的流量泳道實現全鏈路灰度管理
在本文的示例場景下,將使用上圖所示的三個服務 mocka、mockb、mockc 創建代表服務調用鏈三個版本的三個泳道:s1、s2、s3。
1. 前提條件
- 已創建 ASM 企業版或旗艦版實例,且版本爲 1.18.2.111 及以上。具體操作,請參見創建 ASM 實例[1]。
- 已添加 ACK 集羣到 ASM 實例。具體操作,請參見添加集羣到 ASM 實例[2]。
- 已創建名稱爲 ingressgateway 的 ASM 網關。具體操作,請參見創建入口網關服務[3]。
- 已創建名稱爲 ingressgateway 且命名空間爲 istio-system 的網關規則。具體操作,請參見管理網關規則[4]。
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:
- '*'
2. 部署示例服務
首先在 ACK 集羣中部署示例中的應用服務,以實現全鏈路灰度場景。爲 default 命名空間啓用 Sidecar 網格代理自動注入(具體操作,請參見啓用自動注入[5]),接下來在 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
3. 創建泳道組和對應泳道
在示例中,我們將 mocka->mockb->mockc 服務調用鏈路的 v1、v2、v3 三個版本分隔成 s1、s2、s3 三條泳道,三條泳道組成的集合稱爲泳道組。在服務網格 ASM 中,可以通過簡單的配置完成泳道組和泳道的創建。
- 登錄 ASM 控制檯[6],在左側導航欄,選擇服務網格 > 網格管理。
- 在網格管理頁面,單擊目標實例名稱,然後在左側導航欄,選擇流量管理中心 > 流量泳道。
- 在流量泳道頁面,單擊創建泳道組,在創建泳道組面板,配置相關信息,然後單擊確定。
配置項 | 說明 |
泳道組名稱 | 本示例配置爲test。 |
入口網關 | 選擇ingressgateway。 |
泳道模式 | 選擇嚴格模式 |
泳道服務 | 選擇目標Kubernetes集羣和default命名空間,在下方列表中選中mocka、mockb和mockc服務,單擊圖標,添加目標服務到已選擇區域。 |
接下來在泳道組內創建 s1、s2、s3 泳道,分別對應服務調用鏈路的 v1、v2、v3 版本。
- 在流量泳道頁面的流量規則定義區域,單擊創建泳道。
- 在創建泳道對話框,配置相關信息,然後單擊確定。
三個泳道創建完成後,示例效果如下:
每創建一個泳道,流量泳道會自動創建出泳道對應的目標規則 DestinationRule。例如所有泳道創建完成後,會針對 mocka 服務自動創建如下目標規則 DestinationRule。
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
三個泳道創建完成後,針對泳道組中的每個服務都將生成泳道規則對應的虛擬服務 VirtualService。例如,針對 mocka 服務會自動創建如下虛擬服務 VirtualService。
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
最後創建各個泳道對應的引流規則。通過不同的引流規則,ASM 網關可以將不同特徵的請求路由到不同的泳道隔離環境之內,實現泳道內服務調用鏈路之間的完全隔離。下文以創建 s1 泳道的引流規則爲例進行說明,請參照以下步驟創建 s2 和 s3 泳道的引流規則。
- 在流量泳道頁面的流量規則定義區域,單擊目標泳道右側操作列下的引流規則。
- 在添加引流規則對話框,配置相關信息,然後單擊確定。本文以泳道服務對應入口 API 均爲 /mock 爲例,爲每個泳道配置相同的引流規則。
配置項 | 說明 |
入口服務 | 選擇mocka.default.svc.cluster.local。 |
引流規則 | 配置名稱爲r1,域名爲*。 |
匹配請求的URI | 配置匹配方式爲精確,匹配內容爲/mock。 |
添加Header匹配規則 | 單擊添加Header匹配規則,在添加的Header匹配規則中,填寫名稱爲x-asm-prefer-tag,匹配方式爲精確,匹配內容爲s1。 |
三個泳道的引流規則創建成功後,示例效果如下:
創建成功後,會自動生成每條泳道的引流規則,即虛擬服務 VirtualService。例如,針對泳道 s1 會生成如下的虛擬服務 VirtualService:
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
4. 驗證全鏈路灰度功能是否生效
通過以上的規則配置,ASM 流量泳道已經自動創建好了用於維護不同調用鏈路間相互隔離的流量規則。可以通過簡單的訪問驗證通過流量泳道實現的全鏈路灰度是否生效。
1)獲取 ASM 網關的 IP 地址(參考獲取 ASM 網關地址[7])。
2)執行以下命令設置環境變量。http://xxx.xxx.xxx.xxx 爲上一步獲取的 IP。
export ASM_GATEWAY_IP=xxx.xxx.xxx.xxx
3)驗證全灰度鏈路功能是否生效。
- 執行以下命令,查看 s1 泳道的訪問效果。x-asm-prefer-tag 對應的值 s1 爲步驟二創建 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 爲步驟二創建 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 爲步驟二創建 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 泳道下的相關服務,符合預期。
總結
本文簡要討論了在使用服務網格治理雲原生應用流量時,在全鏈路流量管理場景下的挑戰與侷限;並介紹了服務網格 ASM 中的流量泳道能力在服務網格全鏈路流量管理下的優勢與特點。接下來針對 ASM 流量泳道的嚴格模式進行了詳細演示與說明。接下來我們還會針對寬鬆模式下的 ASM 流量泳道進行進一步地深入介紹。
相關鏈接:
[1] 創建 ASM 實例
https://help.aliyun.com/document_detail/147793.html#task-2370657
[2] 添加集羣到 ASM 實例
https://help.aliyun.com/document_detail/148231.html#task-2372122
[3] 創建入口網關服務
https://help.aliyun.com/document_detail/150510.html#task-2372970
[4] 管理網關規則
https://help.aliyun.com/document_detail/150504.html
[5] 開啓 Sidecar 自動注入
https://help.aliyun.com/document_detail/186136.html#task-1962690
[6] ASM 控制檯
https://servicemesh.console.aliyun.com/
[7] 獲取 ASM 網關地址
https://help.aliyun.com/document_detail/444079.html#section-ida-zt6-md7
作者:尹航
點擊立即免費試用雲產品 開啓雲上實踐之旅!
本文爲阿里雲原創內容,未經允許不得轉載。