在進行應用的自動化構建和部署時,通常希望能夠快速將部署后的應用發布到灰度環境,并且能夠方便地對灰度環境的應用進行全鏈路測試,將運維效率提升到極致。本文介紹如何通過云效整合MSE全鏈路灰度來實現。
前提條件
應用使用云效進行構建和部署。
整體架構
整體上應用的調用鏈路是,客戶端入口流量首先達到網關應用,而后按順序經過A、B、C三個應用:
在一次上線窗口中,A和C進行了迭代,進行了灰度發布。在測試流程中,需要對A和C的灰度版本進行全鏈路灰度的測試,調用鏈路如下:
通過云效,在流水線上增加一個灰度流程。每個應用走到線上環境部署階段前,都會先發布到灰度環境。等到開發/測試人員對灰度環境的應用測試沒有問題時,再手工放行流水線走到真正的線上發布部署階段:
準備工作
本文將以A、B、C三個SpringCloud應用為例,介紹如何通過阿里云云效整合MSE全鏈路灰度的功能,實現將應用一鍵部署到灰度環境,并進行全鏈路灰度的測試。假設已有A、B、C三個應用的基線版本正在運行。
步驟一:開啟MSE微服務治理
將ACK微服務應用接入MSE治理中心。具體操作,請參見ACK微服務應用接入MSE治理中心。
步驟二:準備基線版本(若已有則可忽略)
您可以按如下步驟,部署基線環境:
創建MSE Nacos,并復制其內網域名。具體操作,請參見創建Nacos引擎。
創建MSE云原生網關,并關聯第一步創建的Nacos。具體操作,請參見創建MSE云原生網關和新建服務來源。
登錄容器服務管理控制臺,在左側導航欄選擇集群。
在集群列表頁面,單擊目標集群名稱,然后在左側導航欄,選擇 。
在無狀態頁面,單擊使用YAML創建資源。模板內容使用如下YAML示例部署A、B、C三個應用,然后單擊創建。
說明代碼中的{nacos server address}需要替換成您的Nacos內網域名,同時需要去掉大括號{}。
# 應用 A 的基線版本 apiVersion: apps/v1 kind: Deployment metadata: name: spring-cloud-a namespace: default spec: selector: matchLabels: app: spring-cloud-a template: metadata: labels: app: spring-cloud-a msePilotCreateAppName: spring-cloud-a msePilotAutoEnable: 'on' spec: containers: - name: spring-cloud-a image: "registry.cn-hangzhou.aliyuncs.com/mse-governance-demo/spring-cloud-a:3.0.1" imagePullPolicy: Always ports: - containerPort: 20001 livenessProbe: tcpSocket: port: 20001 initialDelaySeconds: 30 periodSeconds: 60 env: - name: spring.cloud.nacos.discovery.server-addr value: {nacos server address} - name: dubbo.registry.address value: 'nacos://{nacos server address}:8848' --- # 應用 B 的基線版本 apiVersion: apps/v1 kind: Deployment metadata: name: spring-cloud-b namespace: default spec: selector: matchLabels: app: spring-cloud-b template: metadata: labels: app: spring-cloud-b msePilotCreateAppName: spring-cloud-b msePilotAutoEnable: 'on' spec: containers: - name: spring-cloud-b image: "registry.cn-hangzhou.aliyuncs.com/mse-governance-demo/spring-cloud-b:3.0.1" imagePullPolicy: Always ports: - containerPort: 20002 livenessProbe: tcpSocket: port: 20002 initialDelaySeconds: 30 periodSeconds: 60 env: - name: spring.cloud.nacos.discovery.server-addr value: {nacos server address} - name: dubbo.registry.address value: 'nacos://{nacos server address}:8848' --- # 應用 C 的基線版本 apiVersion: apps/v1 kind: Deployment metadata: name: spring-cloud-c namespace: default spec: selector: matchLabels: app: spring-cloud-c template: metadata: labels: app: spring-cloud-c msePilotCreateAppName: spring-cloud-c msePilotAutoEnable: 'on' spec: containers: - name: spring-cloud-c image: "registry.cn-hangzhou.aliyuncs.com/mse-governance-demo/spring-cloud-c:3.0.1" imagePullPolicy: Always ports: - containerPort: 20003 livenessProbe: tcpSocket: port: 20003 initialDelaySeconds: 30 periodSeconds: 60 env: - name: spring.cloud.nacos.discovery.server-addr value: {nacos server address} - name: dubbo.registry.address value: 'nacos://{nacos server address}:8848'
登錄MSE治理中心控制臺。選擇 治理中心 > 應用治理,在頂部選擇您的命名空間。單擊進入目標應用,在 QPS 數據中可以看到流量的情況,確認流量都打到未打標的節點,并沒有灰度節點的流量。
步驟三:創建MSE全鏈路灰度泳道
登錄MSE治理中心控制臺,并在頂部菜單欄選擇地域。
在左側導航欄,選擇治理中心 > 全鏈路灰度。
在全鏈路灰度頁面,單擊+ 創建泳道組及泳道。
如果您已經創建過泳道組,則單擊+ 創建泳道組。
在創建泳道組面板,設置如下相關配置,然后單擊確定。
配置項
說明
泳道組名稱
自定義泳道組的名稱。
入口類型
選擇MSE 云原生網關。
泳道組流量入口
選擇目標云原生網關。
泳道組涉及應用
選擇spring-cloud-a、spring-cloud-b和spring-cloud-c。
泳道組創建完成后,在全鏈路灰度頁面的泳道組區域,可以查看您創建的泳道組。如需變更泳道組信息,單擊圖標,可在頁面修改相關信息。
在全鏈路灰度頁面底部,單擊點擊創建第一個分流泳道。
如果您已經創建過泳道,則單擊創建泳道。
在創建泳道對話框中設置相關配置,然后單擊確定。
在云效上整合MSE全鏈路灰度
您可以根據以下兩種方式集成MSE全鏈路灰度。
方式一:通過Flow方式構建CI/CD流水線
在本例中,使用其他 > 空模板創建云效流水線,創建后,需要進行四部分配置:
步驟一:配置云效流水線源
配置流水線的代碼源。配置完成后,添加到流水線中。
代碼倉庫:https://gitee.com/mse-group/alibabacloud-microservice-demo.git。
為了避免網絡延遲,所以采用gitee倉庫。
默認分支:master。
選擇憑證類型:選擇服務連接。
由于本示例中代碼倉庫為公開代碼倉庫,所以只需要按照默認值創建即可。
步驟二:構建階段配置
此階段配置云效如何構建Docker鏡像。刪除原有的階段和空任務,手動添加新任務。
配置項 | 說明 |
構建集群 | 就近選擇。本示例選擇北京構建集群。 |
服務連接 | 按照提示添加ACR的服務連接。通過RAM授權的方式,讓云效可以推送鏡像到ACR中。 |
倉庫 | 選擇您需要推送、部署的鏡像倉庫。 |
標簽 | 默認 |
Dockerfile路徑 | 輸入Dockerfile路徑。本示例為 |
步驟三:部署Gray階段配置
本步驟介紹如何部署Gray節點。云效可以直接替換Kubernetes中的Workload鏡像,可以直接使用此機制來發布。
配置項 | 說明 |
集群連接 | 授權云效修改ACK集群中Workload配置。按照授權添加對應ACK集群連接。 |
Kubectl版本 | 選擇相近版本。 |
命名空間 | 輸入命名空間。 |
Workloads類型 | 選擇Workloads類型。本示例為Deployment。 |
Workloads名稱 | 輸入Workloads名稱。本示例為 |
容器名稱 | 輸入容器名稱。本示例為spring-cloud-a-gray。 |
鏡像 | 選擇上一步構建的鏡像。可以選擇鏡像公網地址。 |
步驟四:部署線上階段配置
類似步驟三的配置:
Workloads名稱:此處為基線環境的Workloads,值為spring-cloud-a。
容器名稱:spring-cloud-a。
最后,將部署Gray階段和部署線上階段的發模式改為手動觸發。
完整配置好后的效果如下圖所示:
步驟五:運行流水線
配置好流水線后,您可以按照發布流程逐步運行流水線:
打包構建。手動運行剛剛的創建好的流水線,觀察構建狀態。
運行成功效果如下:
您也可以查看日志來確定運行狀態、排查問題等:
部署Gray并驗證。單擊部署Gray階段的手動觸發按鈕,開始部署。
方式二:通過AppStack方式構建CI/CD流水
步驟一:在云效上創建應用并做好灰度配置
登錄云效控制臺,設置創建應用。進入應用首頁,單擊右上角新建應用(若已有則可忽略)。
單擊新創建的應用。進入應用概覽,選擇部署編排 > 前往配置 > 選擇 Kubernetes 部署 > 從模板開始 > 空模板,然后單擊確定(若已有則可忽略)。
在Kubernetes部署中,創建應用發布流程(以A應用為例)。單擊添加組件 > 輸入名稱(如spirng-cloud-a-deploy)> 空模板(若已有則可忽略)。
輸入應用的YAML配置。
一些關鍵的地方使用占位符取代。您可以參考以下代碼部署A的Deployment(其中{{}}需要定義相應的變量,AppStack開頭的表示云效預置占位符,Values開頭的表示自定義占位符,可以在上方點擊提取占位符后,在右邊編輯占位符的值。值可以定義成常量,也可以從變量組中引用):
apiVersion: apps/v1 kind: Deployment metadata: name: {{ .AppStack.appName }}-{{ .AppStack.envName }} labels: run: {{ .AppStack.appName }}-{{ .AppStack.envName }} namespace: {{ .Values.namespace }} spec: selector: matchLabels: app: {{ .AppStack.appName }}-{{ .AppStack.envName }} template: metadata: labels: app: {{ .AppStack.appName }}-{{ .AppStack.envName }} spec: containers: - name: {{ .AppStack.appName }} image: {{ .AppStack.image.backend }} imagePullPolicy: Always ports: - containerPort: 20001 livenessProbe: tcpSocket: port: 20001 initialDelaySeconds: 30 periodSeconds: 60 env: - name: spring.cloud.nacos.discovery.server-addr value: 'nacos-server' - name: dubbo.registry.address value: 'nacos://nacos-server:8848'
在應用配置的
spec.template.metadata.labels
下加入MSE基本配置及灰度相關。msePilotCreateAppName: {{ .AppStack.appName }} msePilotAutoEnable: 'on' {{if eq .Values.mseGrayTag "gray" }} alicloud.service.tag: gray {{end}}
說明msePilotCreateAppName
為MSE服務治理接入的應用名;msePilotAutoEnable
為是否接入MSE服務治理的開關on
表示開啟,off
表示關閉;alicloud.service.tag
則是MSE用于灰度發布的節點標簽。您可以在MSE服務治理控制臺,節點詳情頁面看到節點的標簽情況。更多信息,請參見ACK微服務應用接入MSE服務治理和節點詳情。其中
{{if eq .Values.mseGrayTag "gray" }}
是基于GO template的方式識別當前云效發布的應用。環境變量中如果有mseGrayTag=gray
的變量,則認定該應用屬于灰度應用。更多信息,請參見Kubernetes 部署編排。
在頁面右上方,單擊提取占位符。您可按需設置配置中的占位符。
namespace設置成常量;值填寫default;mseGrayTag設置成變量,值使用mseGrayTag。
單擊保存。
保存時需要勾選可用的環境,建議全選。
說明如果您使用本文中的示例A、B、C應用,則您都需要創建對應的應用,并做好相應的配置。
步驟二:在云效中加入灰度環境和灰度變量組
登錄云效控制臺,進入需要做灰度發布的應用(比如A和C,都需要做如下操作)。
在控制臺左側選擇變量組,然后單擊新建變量組,創建一個灰度環境變量組。保存后單擊編輯變量,輸入
mseGrayTag=gray
,然后保存并提交。在控制臺左側選擇環境,然后單擊新建灰度環境。輸入灰度環境的信息,在關聯變量組一欄,單擊添加關聯,選中上一步創建的灰度環境變量組。
當應用通過云效發布到灰度環境時,會自動加入mseGrayTag=gray
,并在我們的應用YAML中添加alicloud.service.tag: gray標簽,這樣就完成了灰度環境發布的應用,能夠攜帶灰度標簽alicloud.service.tag: gray。
如果您使用本文中的示例A、B、C應用,建議您除灰度環境和灰度變量組外,再創建其他環境和對應的變量組,以方便您的測試。但是需要明確的是,其他環境的變量組不應該添加變量mseGrayTag=gray
。
步驟三:使用云效AppStack研發流程進行應用灰度發布
如果您的云效菜單中沒有研發流程和變更按鈕,您可以在創建應用后按以下步驟開啟變更流程的功能:
開啟后,您可以按照以下子步驟創建灰度環境發布流程并進行應用發布。
子步驟 1:新增灰度研發流程和變更信息
如果您尚未配置任何研發流程,請單擊研發流程 > 前往配置,輸入研發流程名稱,選擇Java k8s 應用標準研發流程模板,完成后進入第二步。如果您已存在一些研發配置,單擊研發流程 > 研發流程設置 > 新建研發流程,輸入研發流程名稱,選擇Java k8s 應用標準研發流程模板,單擊創建。
說明如果您使用本文中的示例A、B、C應用,您還需要在應用概覽頁面代碼源設置中配置代碼源。A、B、C應用源碼可以從github上獲取。更多內容,請參見mse-simple-demo。
在上一步配置的研發流程中,選擇生產階段 > 編輯流水線。在合適的節點處(一般為生產環境部署之前),單擊加號圖標或者添加任務按鈕添加灰度任務。
在當前流程下方的變更集成方式中,選擇運行固定分支,選擇master分支(可按需設置)。
流水線配置完畢后,保存當前的流水線。
子步驟2:進行灰度發布
單擊研發流程,選擇上一步創建的灰度發布流程,然后單擊運行。
當流程執行完畢后,查看您的集群是否已經啟動了灰度應用。
應用名稱為步驟一:在云效上創建應用并做好灰度配置中配置的名稱,格式為:應用名-環境名。
子步驟3:發布生產環境
灰度驗證通過后,即可繼續發布生產環境。點擊手動觸發生產環境發布,查看生產發布批次,觀測新老版本號,部署完成后觀測生產監控日志。
子步驟4:銷毀灰度環境
生產發布成功后,銷毀灰度環境資源,所有流量都進入生產環境。
至此即完成了應用基線環境的準備、灰度流程配置、灰度發布驗證、生產發布、灰度銷毀完整流程。
其他參考
針對AppStack方式灰度發布,支持擴縮容和應用回滾。更多信息,請參見2.3 回滾。如果是Flow方式,則需要登錄容器服務管理控制臺進行相關操作。
驗證全鏈路灰度是否生效
如果您啟動的是您自己的灰度應用,則您可以考慮按照您的方式去做驗證。如果您使用本文中示例的A、B、C應用程序,您可以按照一定的訪問條件(比如攜帶特定的灰度header或query參數)直接訪問MSE云原生網關,查看結果是否包含gray字樣,包含則表明全鏈路灰度生效。如本文示例中配置的全鏈路灰度路由規則:請求參數中攜帶group=gray的去往灰度泳道。
發起符合條件的請求,則結果如下(A和C進行了灰度發布,B沒有進行灰度發布,所以請求去往了B的基線環境)所示:
> curl -X GET http://47.96.XX.XXX/A/a?group=gray
Agray[192.168.110.161][config=base] -> B[192.168.110.14] -> Cgray[192.168.110.160]
如果請求條件不符合條件,則去往A、B、C的基線環境:
> curl -X GET http://47.96.XX.XXX/A/a?group=xxx
A[192.168.110.162][config=base] -> B[192.168.110.57] -> C[192.168.110.62]
您還可以在MSE控制臺上看到剛剛發起的灰度請求:
相關文檔
通過云效AppStack和MSE微服務引擎實現灰度發布的具體內容,請參見MSE+云效AppStack實現應用服務全鏈路灰度。