MSE云原生網關以托管的方式來做流量入口,提供豐富的流量治理能力,支持多種服務發現方式,如容器服務、MSE Nacos、MSE Zookeeper、EDAS注冊中心、SAE注冊中心、固定地址和DNS域名,并以統一的模型支持服務版本以及灰度發布能力。本文介紹基于容器服務K8s和Nacos注冊中心兩種服務發現機制來實踐不同的服務發布策略。
前提條件
了解藍綠部署、A/B測試以及金絲雀發布機制。詳細信息,請參見服務發布策略。
服務發現方式:容器服務K8s
在本示例中,使用容器服務K8s原生的服務發現方式,即通過聲明式Service API資源將后端服務注冊到CoreDNS。示例中的后端服務提供一個查詢當前版本的接口:請求路徑為/version,并且當前版本為v1。云原生網關深度集成容器服務ACK,可以實時動態地從ACK集群中獲取服務信息,方便通過云原生網關將該后端服務暴露給外部用戶。
部署應用
登錄容器服務管理控制臺。使用如下YAML部署應用,當前應用版本為v1。
應用部署的具體操作,請參見創建無狀態工作負載Deployment。
apiVersion: v1 kind: Service metadata: name: httpbin spec: ports: - port: 8080 protocol: TCP selector: app: httpbin --- apiVersion: apps/v1 kind: Deployment metadata: name: httpbin-v1 spec: replicas: 3 selector: matchLabels: app: httpbin version: v1 template: metadata: labels: app: httpbin version: v1 spec: containers: - image: specialyang/spring-cloud-httpbin-k8s:v1 imagePullPolicy: Always name: spring-cloud-httpbin-k8s ports: - containerPort: 8080
登錄MSE網關管理控制臺。在網關詳情頁面左側導航欄,選擇路由管理 > 來源。單擊創建來源,添加容器服務的服務來源。
為云原生網關添加服務來源的具體操作,請參見創建服務來源。
在左側導航欄,選擇路由管理 > 服務。導入要暴露給云原生網關的服務httpbin。
為云原生網關添加服務的具體操作,請參見創建服務。
在httpbin服務的策略配置中添加服務版本v1。
為云原生網關添加服務版本的具體操作,請參見管理服務版本。
說明需要選擇對應的標簽來篩選出v1版本的節點,目前只部署了v1版本,所以v1版本的節點數占總實例數100%。
在路由管理中為該服務創建一條路由規則,從而將服務暴露給外部用戶。httpbin服務暴露的API的路由為/version,請求轉發至服務httpbin的v1版本。
為云原生網關配置路由的具體操作,請參見創建路由。
執行以下測試請求命令:
for i in {1..10}; do curl "${GATEWAY_EXTERNAL_IP}/version"; echo ""; done
響應結果:
version: v1 version: v1 version: v1 version: v1 version: v1 version: v1 version: v1 version: v1 version: v1 version: v1
藍綠部署
藍綠部署需要按照服務當前版本所占用的資源狀況為服務新版本申請同樣的資源規格,部署完畢之后將流量整體切換到服務新版本。
利用容器服務ACK的聲明式API資源部署httpbin服務的新版本v2,副本數同樣是3。
apiVersion: apps/v1 kind: Deployment metadata: name: httpbin-v2 spec: replicas: 3 selector: matchLabels: app: httpbin version: v2 template: metadata: labels: app: httpbin version: v2 spec: containers: - image: specialyang/spring-cloud-httpbin-k8s:v2 imagePullPolicy: Always name: spring-cloud-httpbin-k8s ports: - containerPort: 8080
在httpbin服務的策略配置中添加服務版本v2。
為云原生網關添加服務版本的具體操作,請參見管理服務版本。
說明需要選擇對應的標簽來篩選出v2版本的節點,集群中現在v1和v2版本的節點數一致,所以各占50%。
通過藍綠發布將流量從v1整體切換至v2,僅需要修改之前創建的路由規則中的目標服務。
修改云原生網關路由規則的具體操作,請參見管理路由。
執行以下測試請求命令:
for i in {1..10}; do curl "${GATEWAY_EXTERNAL_IP}/version"; echo ""; done
響應結果:
version: v2 version: v2 version: v2 version: v2 version: v2 version: v2 version: v2 version: v2 version: v2 version: v2
可以發現,訪問API資源/version請求的流量已經全部從v1切換至v2。
A/B測試
A/B測試是基于用戶請求的元信息將流量路由到新版本,也就是可以根據請求內容來動態路由。在本示例中,希望User-Agent的值為Android的請求 (來自安卓系統的請求)可以訪問新版本,其他系統仍然訪問舊版本。
仍然通過之前實踐中部署的httpbin服務v1和v2的應用。同時,需要創建兩條路由規則。
匹配Path為/version的請求訪問服務版本v1。
匹配Path為/version,且User-Agent頭部含有Android的請求訪問服務版本v2。
說明version-v2的路由規則中需要增加請求頭的匹配規則。
執行以下測試請求命令(User-Agent中不含有Android):
curl ${GATEWAY_EXTERNAL_IP}/version
響應結果:
version: v1
執行以下測試請求命令(User-Agent中含有Android):
curl -H "User-Agent: Mozilla/5.0 (Linux; Android 4.0.3)" ${GATEWAY_EXTERNAL_IP}/version
響應結果:
version: v2
可以發現,當前請求會按照來源的操作系統對流量進行分流。
金絲雀發布
金絲雀發布允許引流一小部分流量到新版本,待驗證通過后,逐步增加流量,直至完全切換,期間可伴隨著新版本的擴容,舊版本的縮容操作,達到資源利用率最大化。
在金絲雀發布策略中,服務新版本的副本初始部署數無需與原始保持一致。僅需保持資源始終滿足灰度流量,所以將新版本的副本數調為1,可以在服務策略中服務版本模塊看到當前各版本節點數的占比情況。
創建一條路由規則,在目標服務中按照權重將流量轉發至新舊版本。
其中,需要配置兩個目標服務,httpbin的v1和v2版本,并設置對應的流量比。例如,目標服務為標簽路由方式,且v1權重設置為80%,v2權重設置為20%。
執行以下測試請求命令:
for i in {1..10}; do curl "${GATEWAY_EXTERNAL_IP}/version"; echo ""; done
響應結果:
version: v1 version: v1 version: v1 version: v1 version: v1 version: v2 version: v1 version: v2 version: v1 version: v1
可以發現,10個請求中有2個是訪問的新版本v2,其流量比確實符合期望比例。
在真實業務場景中,新版本驗證完畢后,就可以繼續調大訪問新版本的流量權重,期間注意對新版本擴容,按需對舊版本縮容。
服務發現方式:Nacos注冊中心
本示例中的后端服務提供一個查詢當前版本的接口/version,并且當前版本為v1。云原生網關深度集成MSE Nacos注冊中心,可以實時動態地從MSE Nacos實例中獲取服務信息,方便通過云原生網關將該后端服務暴露給外部用戶。
部署應用
登錄容器服務管理控制臺。使用如下YAML部署應用,當前應用版本為v1。
應用部署的具體操作,請參見創建無狀態工作負載Deployment。
說明該YAML資源中變量
${NACOS_SERVER_ADDRESS}
需要替換為您的MSE Nacos地址,如果和網關在一個VPC,那么內網域名即可;否則,您需要配置公網域名。在K8s Service服務發現中,Pod中Labels信息可看作是節點的元數據信息。而在Nacos注冊中心中,節點的元數據信息取決于服務注冊時攜帶的信息。在Spring Cloud框架中,通過環境變量
spring.cloud.nacos.discovery.metadata.xxx
無侵入式為節點添加元數據信息,在該例子中,以version
作為版本標簽用來區分不同版本的節點。因此,需要為業務容器添加環境變量spring.cloud.nacos.discovery.metadata.version=v1
。
apiVersion: apps/v1 kind: Deployment metadata: name: httpbin-v1 spec: replicas: 3 selector: matchLabels: app: httpbin template: metadata: labels: app: httpbin spec: containers: - image: specialyang/spring-cloud-httpbin-nacos:v1 imagePullPolicy: Always name: spring-cloud-httpbin-nacos ports: - containerPort: 8080 env: - name: spring.cloud.nacos.discovery.server-addr value: ${NACOS_SERVER_ADDRESS} - name: spring.cloud.nacos.discovery.metadata.version value: v1
登錄MSE網關管理控制臺。在網關詳情頁面左側導航欄,選擇路由管理 > 來源,添加目標MSE Nacos注冊中心的服務來源。
為云原生網關添加服務來源的具體操作,請參見創建服務來源。
在左側導航欄,選擇路由管理 > 服務,導入要暴露給云原生網關的服務httpbin,服務來源選擇MSE Nacos注冊中心。
為云原生網關添加服務的具體操作,請參見創建服務。
在httpbin服務的策略配置中添加服務版本v1。
說明需要選擇對應的標簽來篩選出v1版本的節點,目前只部署了v1版本,所以v1版本的節點數占總實例數100%。
在路由管理中為該服務創建一條路由規則,從而將服務暴露給外部。httpbin服務暴露的API的路由為/version,請求轉發至服務httpbin的v1版本。
為云原生網關配置路由的具體操作,請參見創建路由。
執行以下測試請求命令:
for i in {1..10}; do curl "${GATEWAY_EXTERNAL_IP}/version"; echo ""; done
響應結果:
version: v1 version: v1 version: v1 version: v1 version: v1 version: v1 version: v1 version: v1 version: v1 version: v1
藍綠部署
藍綠部署需要按照服務當前版本所占用的資源狀況為服務新版本申請同樣的資源規格,部署完畢之后將流量整體切換到服務新版本。
部署httpbin服務的新版本v2。
說明注冊中心與容器服務ACK保持一致,同時為業務容器增加環境變量
spring.cloud.nacos.discovery.metadata.version=v2
,業務應用啟動時會向指定Nacos注冊服務,同時攜帶上自定義的元數據信息。云原生網關可以利用這些元數據信息來對節點區分不同的版本。apiVersion: apps/v1 kind: Deployment metadata: name: httpbin-v2 spec: replicas: 3 selector: matchLabels: app: httpbin template: metadata: labels: app: httpbin spec: containers: - image: specialyang/spring-cloud-httpbin-nacos:v2 imagePullPolicy: Always name: spring-cloud-httpbin-nacos ports: - containerPort: 8080 env: - name: spring.cloud.nacos.discovery.server-addr value: ${NACOS_SERVER_ADDRESS} - name: spring.cloud.nacos.discovery.metadata.version value: v2
在httpbin服務的策略配置中添加服務版本v2。
為云原生網關添加服務版本的具體操作,請參見管理服務版本。
說明需要選擇對應的標簽來篩選出v2版本的節點,集群中現在v1和v2版本的節點數一致,所以各占50%。
通過藍綠部署將流量從v1整體切換至v2,僅需要修改之前創建的路由規則中的目標服務。
修改云原生網關路由規則的具體操作,請參見管理路由。
執行以下測試請求命令:
for i in {1..10}; do curl "${GATEWAY_EXTERNAL_IP}/version"; echo ""; done
響應結果:
version: v2 version: v2 version: v2 version: v2 version: v2 version: v2 version: v2 version: v2 version: v2 version: v2
可以發現,訪問API資源/version請求的流量已經全部從v1切換至v2。
A/B測試
A/B測試是基于用戶請求的元信息將流量路由到新版本,也就是可以根據請求內容來動態路由。在本示例中,希望User-Agent的值為Android的請求 (來自安卓系統的請求)可以訪問新版本,其他系統仍然訪問舊版本。
仍然通過之前實踐中部署的httpbin服務v1和v2的應用。同時,需要創建兩條路由規則。
匹配Path為/version的請求訪問服務版本v1。
匹配Path為/version,且User-Agent頭部含有Android的請求訪問服務版本v2。
說明version-v2的路由規則中需要增加請求頭的匹配規則。
執行以下測試請求命令(User-Agent中不含有Android):
curl ${GATEWAY_EXTERNAL_IP}/version
響應結果:
version: v1
執行以下測試請求命令(User-Agent中含有Android):
curl -H "User-Agent: Mozilla/5.0 (Linux; Android 4.0.3)" ${GATEWAY_EXTERNAL_IP}/version
響應結果:
version: v2
可以發現,當前請求會按照來源的操作系統對流量進行分流。
金絲雀發布
金絲雀發布允許引流一小部分流量到服務新版本,待驗證通過后,逐步調大流量,直至切流完畢,期間可伴隨著新版本的擴容,舊版本的縮容操作,達到資源利用率最大化。
在金絲雀發布策略中,服務新版本的副本初始部署數無需與原始保持一致。僅需保持資源始終滿足灰度流量,所以將新版本的副本數調為1,可以在服務策略中服務版本模塊看到當前各版本節點數的占比情況。
創建一條路由規則,在目標服務中按照權重將流量轉發至新舊版本。
其中,需要配置兩個目標服務,httpbin的v1和v2版本,并設置對應的流量比。例如,目標服務為標簽路由方式,且v1權重設置為80%,v2權重設置為20%。
執行以下測試請求命令:
for i in {1..10}; do curl "${GATEWAY_EXTERNAL_IP}/version"; echo ""; done
響應結果:
version: v1 version: v1 version: v1 version: v1 version: v1 version: v2 version: v1 version: v2 version: v1 version: v1
可以發現,10個請求中有2個是訪問的新版本v2,其流量比確實符合期望比例。
在真實業務場景中,新版本驗證完畢后,就可以繼續調大訪問新版本的流量權重,期間注意對新版本擴容,按需對舊版本縮容。