KubeVela 1.0:開啓可編程式應用平臺的未來

作爲 OAM(Open Application Model)在 Kubernetes 上的實現,KubeVela 項目從 oam-kubernetes-runtime 演進至今不過半年多時間,但發展勢頭非常迅猛,不僅連續登上 GitHub Go 語言趨勢榜首和 HackerNews 首頁,更是迅速收穫了包括 MasterCard、Springer Nature、第四範式、SILOT、Upbound 等來自世界各地、不同行業的終端用戶,甚至還出現了像 Oracle Cloud、Napptive 等基於它構建的商業化產品。就在 2021年3月底,KubeVela 社區宣佈包含所有穩定版 API 的 v1.0 版本發佈,正式開始向企業級生產可用邁進。

不過,如果你對雲原生領域不太關注,可能對 KubeVela 還沒有做過太深入的瞭解。彆着急,本文就藉着 v1.0 發佈之際,爲你詳細地梳理一次 KubeVela 項目的發展脈絡,解讀它的核心思想和願景,領悟這個正冉冉升起的雲原生應用管理平臺之星背後的“道之所在”。

首先,什麼是 KubeVela?

一言以蔽之,KubeVela 是一個“可編程式”的雲原生應用管理與交付平臺

可是,什麼是“可編程”呢?它跟 Kubernetes 又是什麼關係?它能幫助我們解決什麼問題?

PaaS 系統的“能力困境”

PaaS 系統(比如 Cloud Foundry、Heroku 等)自誕生以來,就以其簡單、高效的應用部署體驗而被所有人津津樂道。然而,大家也知道,我們今天的“雲原生”,卻是一個 Kubernetes 大行其道的世界,曾經的 PaaS(包括 Docker)到底遇到了什麼問題呢?

其實任何一個嘗試使用過 PaaS 的人,都會對這種系統的一個本質缺陷感觸頗深,那就是 PaaS 系統的“能力困境”。

如圖 1 所示,PaaS 系統在最開始使用的時候,往往體驗非常好,也總能恰如其分地解決問題。但隨着使用時間的推移,一個非常討厭的情況就會出現:應用的訴求,開始超過 PaaS 系統能夠提供的能力。而更可怕的是,一旦這個問題出現,用戶對 PaaS 系統的滿意度就會斷崖式下跌,這是因爲無論是重新開發平臺增加功能,還是修改應用去適配平臺,都是一項投入巨大但收益很低的事情。更何況所有人這時候都會開始對平臺失去信心:誰知道下一次系統或者應用大改,是不是很快又要發生了?

這個“命門”,可以說是 PaaS 雖然具備雲原生所需的一切要素、卻最終未能成爲主流的主要原因。

而相比之下,Kubernetes 的特點就比較突出了。儘管 Kubernetes 被人詬病“複雜”,但隨着應用複雜度的提升,Kubernetes 的優點就會慢慢體現出來,尤其是當用戶的訴求開始需要你去通過 CRD Controller 支持的時候,你一定會慶幸:幸虧當初選了 K8s。

這裏的原因在於,Kubernetes 的本質其實是一個強大和健壯的基礎設施能力接入平臺,也就是所謂的 The Platform for Platform。它的這套 API 和工作方式,天然不適合直接跟人去進行交互,但卻能夠以非常一致的方式接入任何基礎設施能力,爲平臺工程師構建 PaaS 等上層系統提供“無限彈藥”。這種“BUG 級”的基礎設施能力供給方式,讓再精密的 PaaS 系統相比之下都像是一個礙手礙腳的“玩具”,這一點對於很多正掙扎於構建內部應用平臺的大型企業來說(它們纔是 PaaS 廠商真正想贏取的用戶)無異於是久旱逢甘霖。

雲原生 PaaS :新瓶裝舊酒

前面提到的一點其實很重要:假如一個大型企業要決定採納一個 PaaS 系統還是選擇 Kubernetes,平臺團隊往往纔是能決定拍板的那一方。但另一方面,平臺團隊的意見雖然重要,並不意味着最終用戶的想法就可以不管了。事實上,在任何一個組織中,直接創造價值的業務團隊才持有最高的話語權,只不過起作用的時間稍晚而已。

所以在絕大多數情況下,任何一個平臺團隊拿到 Kubernetes 之後,並不會直接去讓業務去學習 Kubernetes,而是會基於 Kubernetes 構建一個“雲原生” PaaS,用它去服務業務方。

咦,於是乎大家兜兜繞繞,又回到了故事的原點。唯一的變化是,咱們今天這個 PaaS 是基於 K8s 實現的,確實輕鬆了不少。

但實際情況呢?

這個基於 Kubernetes 構建 PaaS 的故事,看似美好,其實整個過程卻難免有些“心酸”。說得好聽點是開發 PaaS,其實 80% 的工作是在設計和開發 UI,剩下的工作則是安裝和運維 K8s 插件。而更令人遺憾的是,我們這樣構建出來的 PaaS,其實跟以前的 PaaS 沒有本質不同,任何時候用戶訴求改變,我們都需要花大量時間重新設計、修改前端、排期上線。結果就是,K8s 日新月異的生態和無限可擴展的特性,都被“封印”在我們親手構建的 PaaS 之下“不見天日”。終於有一天,業務方也實在忍不住要問了:你們平臺團隊上了 K8s,到底有啥價值?

上面這個“爲了解決 PaaS 的固有限制,結果又引入一個新的 PaaS 和限制”的困局,是現今很多公司在落地雲原生技術的過程中遇到的一個核心問題。我們似乎再一次把用戶鎖定在一層固定的抽象和能力集當中。所謂雲原生化的好處,僅僅體現在咱們自己開發這個平臺變得簡單了 —— 而對業務用戶來說,這似乎沒什麼太大的意義

更爲麻煩的是,雲原生和 K8s 的引入,也讓運維人員這個角色變得非常微妙。本來,他們所掌握的業務運維最佳實踐,是整個公司中最重要的經驗和資產。然而,在企業雲原生化之後,這個工作的內容都必須交給 K8s 去接管。所以,很多人都說,K8s 要讓“運維”失業了,這個說法雖然有點誇張,但確實反映出了這個趨勢帶來的焦慮。而且我們不禁也在從另一個角度思考,雲原生化的背景下,應用運維的經驗和最佳實踐,又該怎麼落實?就拿一個簡單的工作負載舉例子,一個 K8s Deployment 對象,哪些字段暴露給用戶、哪些不能,雖然體現在 PaaS 的 UI 上,但肯定不能是靠前端開發說了算的吧。

KubeVela:下一代可編程式應用平臺

阿里巴巴是整個業界在雲原生技術上的先行者之一。所以上述這個圍繞着應用平臺的雲原生技術難題,相對也比較早地暴露了出來。在 2019 年末,阿里基礎技術團隊與研發效能團隊合作針對這個問題進行了大量的探索與嘗試,最終提出了“可編程式”應用平臺的思想,並以 OAM 和 KubeVela 開源項目的方式同大家見面。這套體系,目前已經迅速成爲了阿里構建應用平臺的主流方式。

簡單地說,所謂“可編程”,指的是我們在構建上層平臺的過程中,不會直接在 Kubernetes 本身上疊加抽象(哪怕只是一個 UI),而是通過 CUE 模板語言這種代碼化(Code)的方式來抽象和管理、並透出基礎設施提供的能力。

舉個例子,比如阿里的某個 PaaS 要對用戶提供一個能力叫做 Web Service,這個能力是指任何需要從外部訪問的服務,都以 K8s Deployment + Service 的方式來部署,對用戶暴露鏡像、端口等配置項。

在傳統方法中,我們可能會實現一個 CRD 叫做 WebService,然後在它的 Controller 裏來封裝 Deployment 和 Service。但這必然會帶來前面 PaaS “能力困境”的問題:

  1. 我們應該給用戶暴露幾種 Service 類型?未來用戶想要其他類型怎麼辦?
  2. 用戶 A 和用戶 B 需要暴露的字段不統一該怎麼辦?比如我們允許用戶 B 修改 Label,但 用戶 A 不可以,那這個 PaaS 該怎麼設計?
  3. ……

而在 KubeVela 中,像上面這樣面向用戶的功能,則可以通過一段簡單的 CUE 模板來描述(這裏有完整的例子)。而當你編寫好這樣一個 CUE 文件之後,直接通過一句 kubectl apply,用戶就可以立即使用到這個能力:

$ kubectl apply -f web-service.yaml

更重要的是,只要執行上面這條命令,KubeVela 就會自動根據 CUE 模板內容生成這個能力的幫助文檔和前端表單結構,所以用戶立刻就會在 PaaS 裏面看到這個 WebService 功能如何使用(比如有哪些參數、字段類型),並且直接使用它,如下 圖 2 所示:

在 KubeVela 中,平臺的所有能力比如金絲雀發佈、Ingress,Autoscaler 等等,都是通過這種方式定義、維護和透出給用戶的。這種端到端打通用戶體驗層與 Kubernetes 能力層的設計,使得平臺團隊可以以極低的成本快速實現 PaaS 以及任何上層平臺(比如 AI PaaS,大數據 PaaS),同時高效地響應用戶的持續演進訴求。

1. 不只是 Kubernetes 原生,是 Platform-as-Code

尤爲重要的是,在實現層,KubeVela 並不是簡單的在客戶端去渲染 CUE 模板,而是使用 Kubernetes Controller 去渲染和維護生成的 API 對象。這裏的原因有三點:

  1. Kubernetes Controller 天然適合維護用戶層抽象到底層資源之間的映射,並且通過控制循環(Reconcile)機制永遠確保兩者的一致性,而不會發生 IaC(Infrastructure-as-Code) 系統裏常見的 Configuration Drift(配置漂移)問題(即:底層資源跟用戶層的輸入發生不一致)。
  2. 平臺團隊編寫的 CUE 模板 kubectl apply 到集羣之後,就變成了一個 Kubernetes 中的一個自定義資源(Custom Resource),它代表了一個抽象化、模塊化的平臺能力。這個能力可以被全公司的平臺團隊複用,也可以繼續修改演進,而且它是 Namespace 化的資源,所以平臺的不同租戶可以分配同名但不一樣的模板,互不影響。這樣徹底解決了不同租戶對同一個能力的使用訴求不一樣的問題。
  3. 如果隨着時間推移,用戶對平臺功能的設計提出了新的要求,那麼平臺維護團隊只需要安裝一個新的模板,新的設計就會立刻生效,平臺本身不需要做任何修改,也不用重啓或者重新部署。而且新模板也會立刻被渲染成表單出現在用戶 UI 上。

所以說,KubeVela 的上述設計,從根本上解決了傳統 IaC 系統用戶體驗雖好,但是生產環境上“靠不住”的老大難問題,又在絕大多數情況下讓整個平臺響應用戶需求的時間從原先的數週,降低到幾小時,完全打通了雲原生技術與最終用戶體驗之間的壁壘。而它完全基於 Kubernetes 原生方式實現,確保了整個平臺嚴格的健壯性,並且無論任何 CI/CD 以及 GitOps 工具,只要它支持 Kubernetes,就一定支持 KubeVela,沒有任何集成成本。

這套體系,被大家形象地稱爲:Platform-as-Code(平臺即代碼)

2. 別急,KubeVela 當然支持 Helm

提到 KubeVela 以及 CUE 模板這些概念,很多小夥伴就開始問了:KubeVela 跟 Helm 又是什麼關係啊?

實際上,Helm 和 CUE 一樣,都是一種封裝和抽象 Kubernetes API 資源的工具,而且 Helm 使用的是 Go 模板語言,天然適配 KubeVela Platform-as-Code 的設計思路。

所以在 KubeVela v1.0 中,任何 Helm 包都可以作爲應用組件被部署起來,並且更重要的是,無論是 Helm 組件還是 CUE 組件,KubeVela 裏的所有能力對它們都適用。這就使得通過 KubeVela 交付 Helm 包可以給你帶來一些非常重要但是現有工具很難提供的能力。

舉個例子,Helm 包其實很多是來自第三方的,比如 Kafka Chart,可能就是 Kafka 背後的公司製作的。所以一般情況下,你只能用,但不能改它裏面的模板,否則修改後的 Chart 你就得自己維護了。

而在 KubeVela 中,這個問題就很容易解決。具體來說,KubeVela 提供一個運維側的能力叫做 Patch,它允許你以聲明式的方式給待交付組件(比如 Helm 包)裏封裝的資源打 Patch,而不用去關心這個字段有沒有通過 Chart 模板透出來,而且 Patch 操作的時機,是在資源對象被 Helm 渲染出來之後、提交到 Kubernetes 集羣處理之前的這個時間,不會讓組件實例重啓。

再比如,通過 KubeVela 內置的灰度發佈系統(即:AppRollout 對象),你還可以將 Helm 包作爲一個整體進行漸進式發佈且無需關心工作負載類型(即:哪怕 Chart 裏是 Operator,KubeVela 也可以進行灰度發佈),而不是像 Flagger 等控制器那樣只能針對單一的 Deployment 工作負載進行發佈。此外,如果將 KubeVela 同 Argo Workflow 集成,你還可以輕鬆地指定 Helm 包的發佈順序和拓撲等更復雜的行爲。

所以說,KubeVela v1.0 不僅支持 Helm,它的目標是成爲交付、發佈和運維 Helm Chart 最強大的平臺。一些社區同學已經在本文發佈之前就迫不及待地試用了這部分功能,大家可以移步到這篇文章來閱讀。

3. 全自助式用戶體驗和雲原生時代的運維

得益於 Platform-as-Code 的設計,基於 KubeVela 的應用平臺天然對用戶是自助式的使用方式,如圖 3 所示。

具體來說,平臺團隊只需要極小的人力成本就可以在系統中維護大量的、代碼化的“能力模板”。而作爲平臺的終端用戶,業務團隊只需要根據自己的應用部署需求在 PaaS UI 上選擇幾個能力模板,填入參數,就可以自助式的完成一次交付,無論這個應用多麼複雜,業務用戶的學習成本都非常低,並且默認就會遵循模板中所定義的規範;而這個應用的部署和運維過程,則由 Kubernetes 以自動化的方式去管理,從而減輕了業務用戶大量的心智負擔。

而更爲重要的是,這種機制的存在,讓運維人員再次成爲了平臺團隊中的核心角色。具體地說,他們通過 CUE 或者 Helm 設計和編寫能力模板,然後把這些模板安裝到 KubeVela 系統中給業務團隊使用。大家試想一下,這個過程,其實就是運維人員把業務對平臺的訴求,結合整個平臺的最佳實踐,以代碼化的方式固化成可被複用和定製的能力模塊的過程。而且這個過程中,運維並不需要去進行復雜的 K8s 定製和開發,只需要理解 k8s 的核心概念即可。另一方面,這些代碼化的能力模塊,複用性極高,變更和上線非常容易,並且大多數情況下不需要額外的研發成本,可以說是最敏捷的“雲原生”運維實踐,能夠真正讓業務感受到雲原生“研發、交付、運維高效一體化”的核心價值。

4. 多環境多集羣、多版本應用交付

KubeVela v1.0 的另一個重大更新,就是改進了系統的部署結構,提供了 Control Plane (控制平面)模式,從而具備了面向多環境、多集羣進行版本化應用交付的能力。所以現在,一個典型的生產環境 KubeVela 部署形態如下圖 4 所示:

在這個場景下,KubeVela 支持爲多環境應用進行描述,支持爲應用配置 Placement 策略以及應用多版本同時部署在線、並通過 Istio 進行灰度的發佈模型。大家可以通過這個文檔進行深入瞭解。

在 v1.0 發佈之後,KubeVela 會圍繞上述架構進行持續的演進,其中的一個主要的工作項就是將 KubeVela Dashboard、CLI 和 Appfile 全部遷移和升級到同 KubeVela 控制平面通過 gRPC 進行交互,而不是像之前的版本那樣需要直接跟目標集羣打交道。這部分工作目前尚在進行中,歡迎對構建下一代“可編程式”開發者體驗有心得的同學一起來參與。與此同時,歐洲知名科技出版商 Springer Nature 也正在一起參與這部分工作以便從 CloudFoundry 上平滑遷移到 KubeVela。

結語

如果我們總結一下 KubeVela 今天的設計與能力,其實不難發現它是今天雲原生應用平臺發展的一條必然路徑:

  1. 完全基於 Kubernetes 構建,天然的被集成能力和普適性,天然透出 Kubernetes 及其生態的所有能力而不是疊加抽象;
  2. 基於 X-as-Code 的平臺能力模塊化,配合 OAM 模型實現超低成本的能力封裝、抽象和組裝機制,快速敏捷的響應用戶需求,提供全自助、無鎖定的應用管理與交付體驗;
  3. 基於 Kubernetes 控制器模式進行組件解封裝和應用部署,確保最終一致性、確保應用交付與運維流程的健壯性;
  4. 內置以應用爲單位的發佈策略和麪向多環境、多集羣交付策略,極大地補充了社區目前以單一工作負載爲中心的發佈能力;
  5. 無論應用部署多麼複雜,只需要 1-2 個 Kubernetes YAML 文件就能做完整的描述,天然適合並且大大簡化 GitOps 工作流,極大程度降低了終端用戶使用雲原生和 Kubernetes 得上手成本,並且不帶來任何能力或者抽象鎖定。

更重要的是,KubeVela 以 Platform-as-Code 的設計思想,給未來基於雲原生的應用平臺團隊提出了更加合理的組織方式:

  1. 平臺 SRE 負責 Kubernetes 集羣和組件的健壯性;
  2. 平臺研發工程師負責開發 CRD Controller,同 Kubernetes 內置能力一起對應用層提供完整的應用管理、運維和基礎設施能力;
  3. 業務運維結合業務訴求,負責將最佳實踐代碼化爲 CUE 或者 Helm 模板,將平臺的能力模塊化;
  4. 業務用戶以完全自助化的方式使用平臺的模塊化能力來進行應用管理與交付,心智負擔低,部署效率高。

而基於這套體系,KubeVela 應用平臺還可以用來實現強大的“無差別”應用交付場景,達成完全與環境無關的雲端應用交付體驗:

  1. 組件提供方將應用交付所需的能力(工作負載、運維行爲、雲服務)定義爲 Helm 包或者 CUE 包,註冊到 KubeVela 系統當中;
  2. 應用交付人員使用 KubeVela 組裝上述模塊化能力成爲一個完全與基礎設施無關的應用部署描述,同時可以藉助 KubeVela 的 Patch 等能力定製和覆蓋組件提供方的配置,或者定義複雜的部署拓撲;
  3. 通過多環境、多集羣交付模型定義應用在不同環境中的部署形態和交付策略,配置不同版本應用實例的流量分配策略。

KubeVela v1.0 的發佈是我們基於 OAM 模型以及雲原生應用交付使用場景最大化驗證的結果,它不僅代表了穩定的API,還代表了成熟的使用方式。然而這不代表結束,而是一個全新的開始,它開啓了一個“可編程式”應用平臺的未來,這是一個能夠充分釋放雲原生潛力、讓最終用戶和軟件交付方從第一天開始就充分享受雲原生技術魅力的有效路徑。我們期待這個項目能達成它最樸素的願景:Make shipping applications more enjoyable!

作者 | KubeVela 項目維護者

原文鏈接

本文爲阿里雲原創內容,未經允許不得轉載。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章