Istio流量管理實踐之(2): 通過Istio管理應用的灰度釋出
概述
在專案迭代的過程中,不可避免需要上線。上線對應著部署,或者重新部署;部署對應著修改;修改則意味著風險。
灰即在黑與白之間,灰度釋出就是指能夠平滑過渡的一種釋出方式。灰度釋出可以保證整體系統的穩定,在初始灰度的時候就可以發現、調整問題,以保證其影響度,而我們平常所說的AB測試、金絲雀釋出等也就是灰度釋出的不同方式。
藍綠髮布
藍綠髮布是指不停老版本,部署新版本然後進行測試,確認沒有問題之後,將流量切到新版本,然後老版本同時也升級到新版本。它的特點是無需停機,並且風險較小。
過程大致如下:
- 第一步、部署版本1的應用(一開始的狀態),所有外部請求的流量都打到這個版本上。
- 第二步、部署版本2的應用,版本2的程式碼與版本1不同(新功能、Bug修復等)。
- 第三步、將流量從版本1切換到版本2,即流量從v1:v2為100:0,切換為0:100。
- 第四步,如果版本2存在問題,需要回滾到版本1,進行流量切換回v1:v2為100:0。
A / B測試
A/B 測試不同於藍綠髮布,它是用來測試應用功能表現的一種方法,例如可用性、受歡迎程度、可見性等等。 A/B 測試通常會針對特定的使用者群體進行,其目的在於通過科學的實驗設計、取樣樣本代表性、流量分割與小流量測試等方式來獲得具有代表性的實驗結論,並確信該結論在推廣到全部流量可信;這與藍綠髮布的目的不盡相同,藍綠髮布主要是用於安全穩定地釋出新版本應用,並在必要時回滾。
金絲雀釋出
金絲雀釋出是指通過讓一小部分使用者流量引入的新版本進行測試,如果一切順利,則可以增加(可能逐漸增加)百分比,逐步替換舊版本。如在過程中出現任何問題,則可以中止並回滾到舊版本。最簡單的方式,是隨機選擇百分比請求到金絲雀版本,但在更復雜的方案下,則可以基於請求的內容、特定範圍的使用者或其他屬性等。
Kubernetes中的灰度釋出
Kubernetes自帶的rolling-update 功能提供了一種漸進式的更新過程,可以實現不中斷業務的應用升級。簡要回顧下Kubernetes的升級策略。
spec: replicas: 5 strategy: type: RollingUpdate rollingUpdate: maxSurge: 2 maxUnavailable: 2 minReadySeconds: 5
- maxSurge: 升級過程中最多可以比原先設定所多出的pod 數量,此欄位可以為固定值或是比例(%)。例如:maxSurge: 1、replicas: 5,代表Kubernetes 會先開好1 個新pod 後才刪掉一箇舊的pod,整個升級過程中最多會有5+1 個pod。
- maxUnavailable: 最多可以有幾個pod 處在無法服務的狀態,當maxSurge不為零時,此欄位亦不可為零。例如. maxUnavailable: 1,代表Kubernetes 整個升級過程中最多會有1 個pod 處在無法服務的狀態。
- minReadySeconds: 容器內應用程式的啟動時間,Kubernetes 會等待設定的時間後才繼續進行升級流程,如果沒有此欄位的話,Kubernetes 會假設該容器一開完後即可進行服務。
實現滾動升級的方式也有以下幾種:
- 使用kubectl set image
- 使用kubectl replace
- 使用kubectl rollout
儘管這種機制能夠很好地工作,但只適用於部署的經過適當測試的版本,也就是說,更多的是藍/綠髮布場景。實際上,Kubernetes 中的金絲雀釋出將使用具有相同Label的兩個 Deployment 來完成。在這種情況下,我們不能再使用AutoScaler,因為是有由兩個獨立的AutoScaler來進行控制,不同負載情況下,replicas比例(百分比)可能與所需的比例不同。
無論我們使用一個或者兩個部署,使用 Kubernetes 進行的金絲雀釋出都存在一個根本問題:使用例項擴容來管理流量;這是因為版本流量分發和副本部署在Kubernetes平臺中並非獨立。所有 pod 副本,無論版本如何,在 kube-proxy 迴圈池中都被相同對待,因此管理特定版本接收的流量的唯一方法是控制副本比例。以小百分比例的金絲雀流量需要許多副本(例如1% 將需要至少 100 個副本)。即使我們可以忽略這個問題,部署方式功能仍然非常有限,因為它只支援簡單(隨機百分比)金絲雀部署。如果想根據某些特定規則將請求路由到金絲雀版本上,仍然需要另一種解決方案。這就是Istio的。
使用 Istio進行灰度釋出
使用Istio的流量管理模型,本質上是將流量與基礎設施擴容進行解耦,讓運維人員可以通過Pilot指定流量遵循什麼規則,而不是指定哪些pods/VM應該接收流量。通過將流量從基礎設施擴充套件中解耦,就可以讓 Istio 提供各種獨立於應用程式程式碼之外的流量管理功能。 這些功能都是通過部署的Envoy sidecar代理來實現的。
在使用 Istio實現灰度釋出的情況下,流量路由和副本部署是兩個完全獨立的功能。服務的 pod 數量可以根據流量負載靈活伸縮,與版本流量路由的控制完全無關。這在自動縮放的情況下能夠更加簡單地管理金絲雀版本。
Istio 的路由規則非常靈活,可以支援細粒度控制流量百分比(例如,路由 1% 的流量而不需要 100 個 pod),也可以使用其他規則來控制流量(例如,將特定使用者的流量路由到金絲雀版本)。如下所示:
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: addedvalues spec: hosts: - addedvalues http: - match: - headers: end-user: prefix: yunqi route: - destination: host: addedvalues subset: v3 - route: - destination: host: addedvalues subset: v2 weight: 50 - destination: host: addedvalues subset: v1 weight: 50
獨立於AutoScaler
使用 Istio進行灰度釋出時,由於不再使用副本比例維持流量分發比例,所以可以安全地設定 Kubernetes HPA 來管理兩個版本 Deployment 的副本。
統一的流量路由規則
無論是藍綠髮布,還是AB測試或金絲雀釋出,基於Istio提供的統一的流量路由規則定義可以實現。具體如下:
基於流量比例的釋出
Istio根據輸入的流量比例來確定流量分發的比重。範圍限制為[0, 100],
- 例如,當版本v1配置為0,版本v2配置為100時,這種場景即為藍綠髮布中使用到的規則。
- 此外,如果版本v1比例設定為x,則x%的服務流量會走向此版本v1,(100-x)%的流量會走向版本v2,即從版本v1分走一部分流量。這種場景即為金絲雀釋出或AB測試中使用到的規則。
基於請求內容的釋出
基於請求內容的釋出會遍歷除預設版本外的全部金絲雀規則,若滿足某個版本的規則,則流量走向此版本,若全部不滿足,則流量會走到預設版本。這種場景即為金絲雀釋出或AB測試中使用到的規則。
總結
如上所述,Istio 可以支援靈活規則下的金絲雀釋出,以及區別於Kubernetes 部署方式。Istio 服務網格提供了管理流量分配所需的基礎控制,並完全獨立於AutoScaler,從而允許簡單而強大的方式來進行金絲雀測試和上線。
支援金絲雀部署的智慧路由只是 Istio 的眾多功能之一,它將使基於大型微服務的應用程式的生產部署變得更加簡單。歡迎大家使用阿里雲上的容器服務,快速搭建微服務的開放治理平臺Istio,比較簡單地整合到自己專案的微服務開發中。