云效发布策略指南|滚动、分批、灰度怎么选?
簡介:在日常和用戶交流過程中,我們也經常會被用戶問到關于發(fā)布的問題,比如不同職能團隊之間應該如何配合、發(fā)布的最佳實踐應該是什么樣子的等等。今天我們就來聊聊常見應用發(fā)布方式的選擇,以及每種發(fā)布模式適合什么樣的場景。
無論從開發(fā)運維還是產品運營的角度來看,任何一次上線都是有風險的。從最基本的應用停止導致流量丟失、服務不可用、服務QPS水位下降,到步驟的遺漏、流程的不規(guī)范、開發(fā)過程中引入的bug,以及新產品/新功能上線導致用戶體驗的變化,都會導致線上風險。在日常和用戶交流過程中,我們也經常會被用戶問到關于發(fā)布的問題,比如不同職能團隊之間應該如何配合、發(fā)布的最佳實踐應該是什么樣子的等等。今天我們就來聊聊常見應用發(fā)布方式的選擇,以及每種發(fā)布模式適合什么樣的場景。
平滑升級:滾動發(fā)布
分批發(fā)布通常指取出一例或多例應用實例,將其停止服務、升級到新版本;周而復始地重復這一過程,直到所有實例都升級到新版本。使用滾動發(fā)布,可以最大程度地避免因發(fā)布導致的流量丟失和服務不可用問題;這一模式也是Kubernetes應用部署使用的缺省模式。
針對部署規(guī)模較小、領域邊界較清晰,同時面臨業(yè)務快速發(fā)展變化的微服務應用,滾動發(fā)布流程簡易且可靠性較高。不過由于通常情況下缺乏強干預手段,發(fā)布的可逆程度較差;一旦在發(fā)布過程中覺察到問題,往往需要進行全量回滾。
一般來說,滾動發(fā)布適用于符合如下條件的場景:
- 應用部署規(guī)模較小、啟動和回滾的速度較快;
- 應用所關注的業(yè)務領域范圍相對小、邊界較清晰,且易于進行線上回歸驗證;
- 發(fā)布人員充分理解、掌握平臺所提供的滾動發(fā)布策略;
- 新版本引入的變更,具有向下兼容性。
下面我們分別以ECS和Kubernetes為例,展示如何在云效平臺上進行滾動發(fā)布。
面向ECS的滾動發(fā)布
在云效中,我們可以使用主機部署任務進行滾動發(fā)布。如圖所示,假設需要對以下由2臺ECS構成的主機組進行滾動發(fā)布,每次滾動更新1臺主機:
在流水線中,配置主機部署任務:
設置“暫停方式”為“不暫停”、“分批數量”為2,即可實現滾動發(fā)布。
在進行ECS滾動發(fā)布時需要注意一點:通常情況下,滾動發(fā)布中的主機無法對外提供服務,這意味著集群整體服務水位(如可承接的QPS)會降低——例如在上面2臺主機分2批發(fā)布的過程中,集群始終只有1臺主機可以響應請求,整體QPS水位下降了50%。發(fā)布人員需要仔細評估“由于發(fā)布而導致服務主機不可用”對服務水位的影響,并選擇合適的時間(如業(yè)務低峰期)進行發(fā)布。
原生支持:Kubernetes YAML滾動發(fā)布
YAML發(fā)布是我們在使用Kubernetes時最直接的應用部署方式。在持續(xù)交付流水線中,我們一般將這些用于描述Kubernetes資源的YAML文件通過Git進行統(tǒng)一版本管理,通過云效CI/CD平臺監(jiān)聽代碼庫的變更事件,并通過流水線將這些YAML變更同步到集群當中。
例如下面的app.yaml:
apiVersion: apps/v1 kind: Deployment metadata:name: nginx-deploymentlabels:app: nginx spec:replicas: 3selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- name: nginximage: ${IMAGE}ports:- containerPort: 80由于沒有聲明發(fā)布策略,Kubernetes會缺省指定RollingUpdate策略,也即滾動發(fā)布。
YAML文件中的占位符${IMAGE}是為云效流水線專門留出的替換變量,發(fā)布時會被替換成具體的鏡像。
如下圖所示,我們可以通過“Kubernetes發(fā)布”任務實現上述Deployment的滾動發(fā)布:
具體的發(fā)布進度,可以參考發(fā)布單中的展示:
極簡體驗:Kubernetes鏡像升級
在一些開發(fā)團隊與運維團隊分工較為明確的場景中,開發(fā)團隊可能希望夠盡可能少地理解Kubernetes相關概念,由專職的運維團隊負責完成應用環(huán)境的部署和初始化;開發(fā)團隊只負責完成代碼開發(fā),并通過流水線自動化完成應用鏡像構建,并使用該鏡像對集群中已有的應用進行升級。
如下圖所示,在云效流水線中,我們監(jiān)聽應用代碼庫的變化,并構建出相應的Docker鏡像;發(fā)布階段只需要指定對集群中實例并關聯(lián)前序任務產生的鏡像,即可完成應用的升級發(fā)布。與YAML發(fā)布相同,缺省情況下,鏡像升級也使用了滾動發(fā)布模式:
如上所述,該場景適用于:
- 開發(fā)和運維分離:運維團隊充分理解Kubernetes的原生發(fā)布策略,開發(fā)團隊只負責產出代碼以及應用鏡像,由運維團隊負責集群中應用的實際運維管理
過程可控:分批發(fā)布
分批發(fā)布通常指取出一批應用實例,將其停止服務、升級到新版本;人工觀察實際效果符合期望后,再取出下一批;周而復始地重復這一過程,直到所有實例都升級到新版本。在滾動過程中,新舊版本共存且同等地接受流量、提供服務;發(fā)布人員基于對服務質量(如請求成功率、響應時間等基礎指標,或特定的業(yè)務成功率等業(yè)務指標)進行觀察,決定是否進一步擴大新版本部署比例,或是放棄發(fā)布進行回滾。
分批發(fā)布的基本模式與滾動發(fā)布相似,主要差異則在于允許人工控制新版本上線、老版本下線的過程。由于新版本的部署比例可控,發(fā)布人員可以預先制定批次部署計劃,在少量部署的新版本上,基于生產環(huán)境流量進行小規(guī)模線上驗證;若應用自身規(guī)模較大或邏輯較復雜,維持一段時間的小規(guī)模驗證也能起到線上回歸測試的作用。另一方面,人工控制部署批次使得發(fā)布整體具有較好的可逆性:一旦在小規(guī)模驗證中發(fā)現問題,可以快速回滾已經發(fā)布的新版本。
分批發(fā)布通常適合:
- 應用在業(yè)務鏈路中較為關鍵,部署規(guī)模較大,業(yè)務邏輯較復雜;
- 進行線上驗證時,難以圈定灰度流量,需要使用較少比例的新版本部署進行驗證,以期控制風險影響面;
- 新版本引入的變更,具有向下兼容性。
面向ECS的分批發(fā)布
在云效中,主機部署任務也可以被配置為分批發(fā)布模式,如下圖所示:
我們可以通過指定“第一批暫停”或“每批暫停”,實現分批控制:
- 若指定“每批暫停”,則每一批發(fā)布完成后,都需要人工確認后方可發(fā)布下一批。這種模式適合需要全程控制發(fā)布節(jié)奏的場景,通過逐步觀察線上指標,逐步確認新版本的正確性;或是有明確的發(fā)布計劃,如“先部署1批(占比10%)、夜間業(yè)務低峰期+次日9-11點業(yè)務高峰期觀察無問題后,按30%、50%、80%、100%實例數遞進部署,每批停頓不少于30分鐘,期間觀察線上指標,若出現問題則回滾”。
- 若指定“第一批暫停”,則只有第一批發(fā)布結束后,會等待發(fā)布人員確認;一經確認,此后的各批次將自動部署,與滾動發(fā)布類似。這種模式結合了滾動發(fā)布的簡便性,以及分批發(fā)布的小規(guī)模驗證、快速回滾能力,通常適用于“先進行一批小規(guī)模線上驗證,驗證通過后即可全量發(fā)布”的場景。
發(fā)布人員可根據應用的部署規(guī)模、重要程度及邏輯的復雜程度,選用不同的分批暫停模式。
面向Kubernetes的分批發(fā)布
云效的分批發(fā)布中,我們以Service為最小發(fā)布單元,在發(fā)布開始階段我們將基于新版鏡像創(chuàng)建出應用的版本V2,并根據當前應用的副本總數以及分批數量,對新舊兩個版本的應用實例分別進行縮容和擴容,來控制實際進入到新版應用的流量比例,從而可以實現小規(guī)模的發(fā)布驗證,在對發(fā)布進行充分驗證后,再逐步完全下線老版應用。
與ECS部署類似,批次之間支持暫停和手動恢復,用以對發(fā)布過程進行控制。
該模式適用于:采用Kubernetes原生的服務發(fā)現機制,并希望獲得相比于原生Kubernetes發(fā)布更好過程控制性以及安全性的用戶。
流量可控:灰度發(fā)布
較之滾動/分批發(fā)布,灰度發(fā)布加強了對線上驗證影響范圍的控制:通常需要以同樣的實例數,部署新/老版本兩套服務;再通過流量分發(fā)控制手段,將特定的線上流量導入新版本、其余流量仍然流入老版本;線上驗證通過后,所有流量都將導入新版本實例,而老版本實例則可用作下一次發(fā)布的模板。
常見的流量分發(fā)控制手段如:
- 支持流量在新/老版本之間按比例分配;
- 支持匹配特定URL/cookie/header/業(yè)務字段(如用戶ID)的流量,流入新版本。
使用相對明確的規(guī)則進行流量分發(fā)控制,從技術團隊的角度來看意味著進一步的變更風險控制:發(fā)布人員可以選定具有某種特征的請求,用于在驗證新發(fā)布的功能同時,使得影響范圍盡量容易識別。而從產品運營團隊的角度來看,灰度發(fā)布除了可以更精確地控制技術風險的影響面之外,更重要的一點是可以輔助他們進行客戶數據對比:舉例來說,運營團隊可以事先和某些有意向體驗新功能的客戶達成合作,使用灰度方式為他們開通新功能進行試用;另一類典型的例子則是A/B test, 通過灰度發(fā)布提供的流量控制能力,收集新/老版本的用戶數據,用以評估新的設計是否更為合理。
灰度發(fā)布一般適用于:
- 能夠定義流量分發(fā)規(guī)則(如header、cookie、用戶ID等);
- 變更具有較高的技術風險,或對業(yè)務有較大改動,需要將受影響的流量控制在較為精確的范圍內(如先讓內部員工試用)進行線上驗證;
- 產品運營團隊希望使用線上的自然流量,對新/老設計進行比較。
由于Kubernetes生態(tài)提供了很多方便的流量管控手段,我們以kubernetes發(fā)布為例,展示如何在云效上進行灰度發(fā)布。
Kubernetes外部流量:Ingress灰度發(fā)布
一種典型的對外接收流量的場景,是使用Ingress暴露服務。在云效流水線的Ingress灰度發(fā)布中,我們以Ingress作為發(fā)布單元,當觸發(fā)部署后,將會根據當前Ingress以及其關聯(lián)的Service/Deployment資源,基于新版鏡像創(chuàng)建出V2版本的Service/Deployment,并通過Nginx Ingress的Annoation完成對流量規(guī)則聲明,從而確保只有滿足特定特征的流量才能進入到V2版本中。
例如在下圖的流水線中,我們根據cookie匹配流量,進行灰度發(fā)布:
當處于灰度狀態(tài)時,流水線將會等待人工驗證,以觸發(fā)發(fā)布或者或者回滾操作。
Kubernetes內部流量:Istio/ASM藍綠發(fā)布
當采用微服務架構時,大部分的后端服務只在集群內部開放,微服務之間通過Kubernetes Service進行相互訪問。在這種情況下,如果希望采用灰度發(fā)布模式,則需要在Service級別進行流量控制,以確保指定的流量進入到灰度的鏈路,而不對正常用戶產生影響。
不過由于Kubernetes原生Service級別并不支持任何的流量控制規(guī)則,因此我們需要在集群中部署Istio或者采用阿里云ServiceMesh來對服務之間的流量進行細粒度的控制。
如下圖所示,當使用Kubernetes藍綠發(fā)布模式時,可以設置灰度流量規(guī)則,從而只有當請求中包含指定的Cookie配置的請求轉發(fā)到灰度版本當中:
該模式適用于:采用Istio或者阿里云ServiceMesh的Kubernetes用戶,并且希望能夠通過灰度的方式對發(fā)布進行驗證。
原文鏈接
本文為阿里云原創(chuàng)內容,未經允許不得轉載。?
總結
以上是生活随笔為你收集整理的云效发布策略指南|滚动、分批、灰度怎么选?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何在golang代码里面解析容器镜像
- 下一篇: 电脑DNS修复