灰度釋出,又名金絲雀釋出,是指能夠平滑過渡的一種釋出方式。基於系統穩定性和快速業務迭代的綜合考慮,業務應用開發團隊採取了新版本服務灰度上線的方式,即新版本服務並非全量釋出到線上環境,而是釋出少數幾個範例進行灰度驗證,沒有問題後再全量釋出。在部分核心服務進行介面升級和邏輯遷移時,還會通過在業務邏輯程式碼中增加黑白名單或者流量百分比控制的方式,逐步將舊版本介面實現遷移至新版本介面實現。尤其是對於toB業務和SAAS類平臺,很多情況需要根據租戶或使用者維度進行灰度控制,實現業務上的A/Best功能。
對於之前我們業務中實現的傳統的灰度釋出, 較好地權衡了服務穩定性和業務迭代效率,但仍存在以下問題:
a. 系統侵入性強,業務開發人員在服務介面中編碼大量與業務邏輯無關的黑白名單或流量百分比控制程式碼。
b. 當新版本介面出現波動或異常,通常需要業務團隊通過緊急修改程式碼和緊急釋出,來更新黑白名單和流量百分比控制策略,時間較長,業務影響較大。
c. 調整黑白名單或流量控制百分比,需要業務團隊釋出程式碼或者接入動態設定中心,過程複雜、可複用性差、操作靈活性差.
d. 對於單體應用來說,灰度釋出方案實現還算簡單,但對於微服務應用,每次釋出版本可能不是全部服務需要灰度釋出,實現微服務灰度釋出的原子維度控制,也是導致微服務架構下灰度方案不能很好落地的原因。
筆者實際業務專案(採靈通系統)採用的是微服務的架構設計,總計服務個數60+,技術底座採用K8s+Istio的服務治理方案。如果採用傳統的灰度釋出方案,每個服務上下游依賴過多,相對於傳統的灰度釋出方案,並不能很好滿足業務訴求。因此,探索了一條基於Istio的服務流量治理方案下的靈活可設定的灰度釋出方案。
先上一個方案簡介圖:
本發明的技術方案以k8s服務部署為基礎,以istio服務流量治理為核心,以Mysql為資料儲存,同時結合jenkins的自動化部署方案,可以實現低成本動態的高效微服務釋出方案,並且帶業務服務無程式碼侵入。
本發明的技術方案以activiti開源工作流引擎為基礎, 以Mysql作為資料儲存, 通過自定義的一套規則引擎框架, 可以實現流程規則的的快速搭建和動態修改功能.
a. 如圖所示,k8s management實現對服務的pod管理,在k8s管理中,正式環境和灰度環境分別隸屬兩個名稱空間,通過deployment實現服務的建立,建立中,灰度和正式的pod範例會打上prod或gray的標籤。Deployment建立過程通過jenkins管理,可以實現部署的自動化流程。具體deployment設定方案詳情請跳轉至3.2.2
b. 如圖所示,istio控制平面可以建立虛擬服務,通過對虛擬服務的路由策略的設定不同,可以實現不同的灰度策略,設定下發通過jenkins管理,可以實現設定的自動化下發。具體策略詳情請跳轉至2.1
c. 如圖所示,具體業務請求實現流程如上:
1. 使用者首先需要登入請求,請求發動到我們自建的認證中心服務中。如圖中1標所示。
2. 認證中心接收到請求會到cookie生成器中獲取使用者認證的cookie,如圖中2標所示
3. Cookie生成器會到資料庫中讀取灰度白名單資訊,來確定是否在cookie中打灰度標籤。如圖中3標所示。
4. 認證中心拿到cookie後返回給前端使用者 ,如圖中4,5標所示。
5. 使用者帶著cookie請求業務請求到虛擬服務A.虛擬服務A中存在istio控制面板下發的的灰度設定資訊,通過設定資訊,決定當前的請求流量是流入正式環境範例A還是灰度環境範例A。如圖中6,7標所示。
6. 服務A中存在呼叫服務B的業務邏輯,所以服務A會請求到虛擬服務B中,虛擬服務B中存在istio控制面板下發的的灰度設定資訊,通過設定資訊,決定當前的請求流量是流入正式環境範例B還是灰度環境範例B。如圖中8標所示。
通過以上8個步驟,我們完成了灰度方案下的流量管控,該方案對於業務服務A和業務服務B無任何程式碼侵入,同時,灰度的設定方案可以實時快速的通過jenkins管理頁面進行自動化下發,實現灰度釋出的動態靈活切換.
至於灰度環境的低成本,當程式碼完成灰度拉平線上後,通過更改灰度下發策略,可以實現灰度環境和正式環境的負載均衡,共同承擔正式環境的業務流量,保證了灰度環境的主機資源不會被浪費。
在k8s管理方面,要建立兩個名稱空間,一個是prod環境,一個是gray環境,通過名稱空間隔離正式環境和灰度環境資源,主要原因是可以更好的管理。當然此處並不強制。同時,需要設定一下deployment的標籤項,在標籤項增加一個profile鍵,根據場景,profile可以設定為prod和gray,具體設定demo如下圖所示。
灰度整體方案流程圖如上圖所屬,該流程圖中主要分為三大整體方案,包括:基於使用者白名單的灰度方案,按照流量百分比灰度方案,灰度拉平線上的負載均衡方案。以上灰度環境可以滿足之前提到的多場景,低成本,動態,無侵入的灰度方案要求。
以下2.3,2.4,2.5將分別詳細介紹三種灰度方案的具體設定策略。
1. cookie中打標籤。
通過認證中心,可以實現業務維度的灰度控制,cookie中會根據使用者白名單,進行灰度打標籤。Cookie格式如下:
cookie:tenantGray=0;rememberMe=*************;channel=****
當tenantGray=0時,表示當前使用者不是灰度使用者,當tenantGray=1時,表示當前使用者是灰度使用者。
2. 當選擇根據cookie動態設定灰度服務時,根據選中的服務,virtualService設定如下:
如圖所示,當請求的cookie資訊匹配到tenantGray=1時,根據istio的虛擬服務規則,走test-A.gray.svc.cluster.local路由,然後請求會打到灰度環境的服務範例上。當tennatGray=0時,根據istio的虛擬服務規則,走test-A.prod.svc.cluster.local的路由,然後請求會打到正式環境的服務範例上。
3. 如果使用者選擇根據灰度標籤進行灰度方案選擇,設定方案如下:
在k8s叢集中我們之前建立灰度服務的deployment時,當時增加過一個標籤,標籤為profile: pray,用來標記該服務為灰度服務。
如圖所示設定,match條件為,當請求來源是來自帶有灰度標籤的deployment服務時,走test-A.gray.svc.cluster.local路由,然後請求會打到灰度環境的服務範例上。反之,走test-A.prod.svc.cluster.local的路由,然後請求會打到正式環境的服務範例上。
4. 然後把所有需要灰度釋出的服務對應的vistualService的設定資訊通過jenkins的自動化流程下發到k8s叢集中。
當我們的業務場景不需要針對具體的使用者進行灰度時,尤其是我們只是在一定範圍內做A/Btest,這樣的話,我們可以更改設定資訊,實現業務的按照流量比例進行灰度控制,具體的設定virtualService方案如下:
該灰度方案比較明確,就是當該服務不再需要灰度時,為了不浪費伺服器資源,將灰度服務跟線上服務程式碼拉平,然後通過流量管理,正式環境的流量實現負載均衡的目的。假設灰度服務跟正式服務的服務範例數比率為1:1,具體virtualService設定如下:
眾所周知,對於單體應用來說,灰度釋出只需要對單一服務進行灰度控制就會要了。但是到了微服務架構下,會存在眾多服務,服務之間存在複雜的網路拓撲關係,所以當我們進行服務的灰度釋出時,需要控制服務之間的灰度呼叫關係,實現灰度釋出的服務治理功能,解決了微服務架構下動態管理多服務之間的灰度方案串聯問題。
以下舉例三種不同的灰度治理場景。
a.以下範例場景是,服務A採用基於灰度白名單的灰度策略,服務B採用灰度拉平線上的灰度策略,然後服務A存取服務B,可以實現服務A的灰度釋出,服務B為正式環境。
b. 下圖範例場景是,服務A採用基於灰度白名單的灰度策略,服務B採用基於服務灰度標籤的存取策略,然後服務A存取服務B,可以實現灰度服務A的流量存取灰度服務B,正式服務A的流量存取正式服務B。
c. 圖範例場景是,服務A採用基於流量比率的灰度策略正式環境和灰度環境的比率為8:2,服務B採用基於灰度白名單的灰度策略,然後服務A存取服務B時,在灰度白名單中的使用者,在灰度服務B,不在灰度白名單中的使用者,走正式服務B。
通過本次基於Istio的灰度方案的實踐,最大感觸就是基於服務網格的第二代微服務架構的優秀潛力。Service Mesh對流量的管理可以下沉至運維維度,並且靈活度是第一代微服務架構不可比擬的。通過這次時間,很好的解決了筆者現實業務中的灰度釋出問題,實現了通過設定自動化下發,無程式碼侵入,實現動態切換等多種靈活策略。
k8s:kubernates的簡稱。k8s是一個開源的,用於管理雲平臺中多個主機上的容器化的應用,Kubernetes的目標是讓部署容器化的應用簡單並且高效(powerful),Kubernetes提供了應用部署,規劃,更新,維護的一種機制
istio:Istio 是一個開源服務網格,它透明地分層到現有的分散式應用程式上。
負載均衡:意思是將負載(工作任務,存取請求)進行平衡、分攤到多個操作單元(伺服器,元件)上進行執行
virtualService:istio內建的一種設定型別,叫做虛擬服務,可以設定單獨的路由指向。通過virtualService可以實現istio的流量管理。
灰度拉平:是指將正式環境的服務程式碼跟灰度環境的服務程式碼拉成一致的。