Kruise Rollout:靈活可插拔的漸進式發佈框架
前言
Kruise Rollout 是 OpenKruise 社區開源的漸進式交付框架。Kruise Rollout 支持配合流量和實例灰度的金絲雀發佈、藍綠髮布、A/B Testing 發佈,以及發佈過程能夠基於 Prometheus Metrics 指標自動化分批與暫停,並提供旁路的無感對接、兼容已有的多種工作負載(Deployment、CloneSet、DaemonSet)。
近期也在《2022 開放原子全球開源峯會》上面做了主題分享,以下是主要內容。
什麼是漸進式交付?
漸進式發佈主要區別於全量、一次性發布。它主要包含以下特點:
-
增量的發佈過程:通俗講就是我們可以將一次發佈分成多個批次,並且可以控制每個批次的開始與停止。
-
實例與流量雙重維度的灰度:比如社區常見的金絲雀發佈、A/B Testing 發佈、藍綠髮布。
-
階段可驗證性:就是發佈的每個批次,可以驗證發佈的正確性、是否符合預期。
下面我們來看一個實際的例子。
假如線上是 X 版本,現在需要發佈到 Y 版本。首先,會將發佈分爲多個批次(比如,第一批只發布十個實例);然後,灰度一定規則的流量到 Y 版本,比如:像淘寶每次重大發布,會使用 A/B Testing 的方式,只將公司員工灰度到新版本;最後,驗證新版本的健康情況,驗證 OK 後,可以重複上述的過程,完成剩餘的批次。如果在這個過程中發現了任何異常,可以快速回滾到 X 版本。通過上面這個例子,漸進式發佈與全量發佈相比,增加了很多中間的驗證過程,漸進式發佈可以說是極大的提高了交付的穩定性,尤其是針對一些大規模的場景而言,漸進式發佈是非常有必要的。
漸進式發佈與 K8s 工作負載之間的關係
K8s 當中所有的 Pod 都是由工作負載來管理的,其中最常見的兩個工作負載就是 Deployment 和 statefulset。Deployment 對於升級而言提供了 maxUnavailable 和 maxSurge 兩個參數,但是本質上來講 Deployment 它只支持流式的一次性發布,用戶並不能控制分批。StatefulSet 雖然支持分批,但是跟我們想要的漸進式發佈的能力還有比較大的距離。
所以漸進式發佈與工作負載從能力上講是一種包含關係,它除了基礎的 Pod 發佈之外,還應該包含流量發佈和進度控制。既然能力上已經梳理清楚了,下面我們就要看看實現,如何去設計和實現 Rollout 能力也是非常重要的。在這我們可以考慮一個問題,從設計的角度看他們也是包含關係嗎?
Rollout 方案的設計理念
準備開始做這件事情前,肯定要先調研一下社區的優秀方案,看看其他人是如何解決的。
Argo Rollout 是 Argo 公司推出的 Workload,它的實現思路是:重新定義一個類似於 Deployment 的工作負載,在實現 Deployment 原有能力的基礎上,又擴展了 Rollout 的相關能力。它的優點是工作負載內置了 Rollout 能力,配置簡單、實現也會比較簡單,並且目前支持的功能也非常的豐富,支持各種發佈策略、流量灰度和 metrics 分析,是一個比較成熟的項目。
但是它也存在一些問題,因爲它本身就是一個工作負載,所以它不能適用於社區 Deployment,尤其是針對已經用 Deployment 部署的公司,需要一次線上遷移工作負載的工作。其次呢,現在社區的很多方案是依賴 Deployment 實現的,並且很多公司已經構建了基於 Deployment 的容器管理平臺,都要進行兼容適配。所以,Argo-Rollout 更加適用於定製化能力較強的、沒有存量 Deployment 的公司業務。
另一個社區項目是 Flagger,它的實現思路跟 Argo-Rollout 完全不同。它沒有單獨的實現一個 workload,而是在現有 Deployment 的基礎之上,擴展了流量灰度、分批發布的能力。
Flagger 的優勢是支持原生 Deployment 、並且與社區的 Helm、Argo-CD 等方案都是兼容的。但是也存在一些問題,首先就是發佈過程中的 Double Deployment 資源的問題,因爲它是先升級用戶部署的 Deployment,再升級 Primary,所以在這過程中需要準備雙倍的 Pod 資源。第二呢,針對一些自建的容器平臺需要額外對接,因爲它的實現思路是將用戶部署資源都 copy 一份,且更改資源的名字以及 Label。所以,Flagger 更加適合那種規模不大、基於社區方案部署、定製化較小的公司。
另外,百花齊放是雲原生的一大特點。阿里雲容器團隊負責整個容器平臺雲原生架構的演進,在應用漸進式交付領域也有強烈的需求,因此在參考社區方案以及考慮阿里內部場景的基礎上,我們在設計 Rollout 過程中有以下幾個目標:
-
無侵入性:對原生的 Workload 控制器以及用戶定義的 Application Yaml 定義不進行任何修改,保證原生資源的乾淨、一致
-
可擴展性:通過可擴展的方式,支持 K8s Native Workload、自定義 Workload 以及 Nginx、Isito 等多種 Traffic 調度方式
-
易用性:對用戶而言開箱即用,能夠非常方便的與社區 Gitops 或自建 PaaS 結合使用
Kruise Rollout 工作機制與演進
Kruise Rollout API 設計是非常簡單的,主要包含以下四個部分:
-
ObjectRef:用於表明 Kruise Rollout 所作用的工作負載,例如:Deployment Name
-
Strategy:定義了 Rollout 發佈的過程,如上是一個金絲雀發佈的示例,第一批發布 5% 的實例,並且灰度 5% 流量到新版本,待人工確認後,再進行後續發佈
-
TrafficRouting:流量灰度所需要的資源 Name,例如:Service、Ingress 或 Gateway API
-
Status:用來展示 Rollout 的過程以及狀態
接下來介紹一下 Kruise Rollout 的工作機制。
首先,用戶基於容器平臺做一次版本發佈(一次發佈從本質上講就是將 K8s 資源 apply 到集羣中)。
-
Kruise Rollout 包含一個 webhook 組件,它會攔截用戶的發佈請求,然後通過修改 workload strategy 的方式 Pause 住 workload 控制器的工作。
-
然後,就是根據用戶的 Rollout 定義,動態的調整 workload 的參數,比如:partition,實現 workload 的分批發布。
-
等到批次發佈完成後,又會調整 ingress、service 配置,將特定的流量導入到新版本。
-
最後,Kruise Rollout 還能夠通過 prometheus 中的業務指標判斷髮布是否正常。比如說,對於一個 web 類 http 的服務,可以校驗 http 狀態碼是否正常。
上面的過程,就完成了第一批次的灰度,後面的批次也是類似的。完整的 Rollout 過程結束後,kruise 會將 workload 等資源的配置恢復回來。 所以說,整個 Rollout 過程,是與現有工作負載能力的一種協同,它儘量複用工作負載的能力,又做到了非 Rollout 過程的零入侵。
Kruise Rollout 工作機制就先介紹到這裏,下面我簡單介紹一下 OpenKruise 社區。
最後
隨着 K8s 上面部署的應用日益增多,如何做到業務快速迭代與應用穩定性之間的平衡,是平臺建設方必須要解決的問題。Kruise Rollout 是 OpenKruise 在漸進式交付領域的新探索,旨在解決應用交付領域的流量調度以及分批部署問題。Kruise Rollout 目前已經正式發佈 v0.2.0 版本,並且與社區 OAM KubeVela 項目進行了集成,vela 用戶可以通過 Addons 快速部署與使用 Rollout 能力。此外,也希望社區用戶能夠加入進來,我們一起在應用交付領域做更多的擴展。
-
Github:
https://github.com/openkruise/rollouts
-
Official:
https://openkruise.io/
-
_Slack: _
_https://kruise-workspace.slack.com/ _
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/lZ3n1ip_9SV3PiFSSP_nnA