基於 K8S 構建企業級 Serverless Container 平臺的探索與實踐
當前 Kubernetes 已經成為名副其實的企業級容器編排規範,很多雲平臺都開始提供相容 Kubernetes 介面的容器服務。而在多使用者支援方面,多數平臺選擇直接提供專屬虛機叢集,使用者需要花費大量精力處理叢集規模、資源利用率、費用等問題。 本次分享帶來的是華為雲在基於 K8S 構建企業級 Serverless Container 平臺過程中的探索與實踐,涉及容器安全隔離、多租管理、Serverless 理念在 Kubernetes 平臺的落地等相關內容。
Kubernetes 在華為雲的歷程
首先來了解一下華為雲在 Kubernetes 的發展歷程。2014 年,華為雲就開始研究並使用 Kubernetes,早期的重點是將 Kubernetes 應用在私有云環境中。2016 年,華為公有云上釋出了容器引擎平臺 ( CCE),它的形式與市面上多數的公有云 Kubernetes 服務(如 GKE、AKS) 類似,是給使用者提供完整一套託管的K8S叢集。而在今年年初,華為雲釋出了 Kubernetes 容器例項服務(Serverless Container),不過它與業界一些傳統的容器例項服務不太一樣。
容器的三大好處,為應用而生
眾所周知,容器技術有三大好處。
- 一是它提供資源隔離,使用者很容易通過應用合設來提升資源利用率;
- 二是,它具備秒級彈性的能力。因為容器本身技術特點,不用載入重型虛擬化,所以它可以做到非常快速的彈性擴縮容;
- 三是,容器映象技術,解決了包括應用及其依賴環境的一致性問題,簡化業務交付流程。
Kubernetes 的常見使用形態
私有云部署Kubernetes
人們使用 Kubernetes 的一種常見形式就是在自己的資料中心搭建叢集。
這種做法的優點在於:
- 第一,可以享受DIY過程帶來的樂趣和成就感(當然也可能隨使用時間的增長,問題越來越多而變成苦難)。
- 第二,在全套私有化的模式下,資料請求都在本地處理,不會存在隱私顧慮。
- 第三,資源規劃、叢集安裝部署升級,都是使用者自己端到端控制。
但是缺點也很明顯:首先,很多人在自建時只看中了 Kubernetes,對周邊配套並沒做過很深度的研究,在實施過程中就會面臨網路、儲存等配套系統的選型問題。其次,使用者需要負擔 100% 的運維成本,而且資源的投入往往是一次性(或階段性的),投入成本門檻非常高。此外,在自建的環境中 Kubernetes 的叢集數量、中的單個叢集規模往往不會很大,所以業務部署規模比較大時,彈性伸縮還會受限於底層資源規模,偏偏硬體資源的擴容速度往往慢得不可想象。最後,開發者習慣於做比較多的資源預留,因此資源利用率也非常有限。也就是說,自建者還要為全套資源利用率買單。

公有云半托管Kubernetes專屬叢集
第二種 Kubernetes 的常見形態是公有云的(半)託管叢集。
可以這樣理解,使用者購買一組虛機,雲平臺則自動在這些機器上部署一套 Kubernetes,而半托管含義在於有些平臺,它的控制面可能是附送的。
這種形態的優點是:
- 使用者自己擁有叢集,不用擔心與其他使用者共用一套 Kubernetes 可能引起一系列干擾問題。
- 雲平臺在提供 Kubernetes 服務時,往往經過大量的測試和調優,所以給出叢集的配置是在自家平臺上的最佳實踐。使用者通過這種模式在雲上執行 Kubernetes,可以獲得比自己部署運維好很多的體驗。
- Kubernetes 社群釋出新版本後,雲平臺會至少做一輪額外的測試、問題修復,再上線並推薦使用者升級。這用就節省了使用者對升級時機評估的工作量。而直接使用開源版本的使用者,如果對新版本跟進太快,自己要踩很多坑,但要延後到哪個版本再升,則要持續跟進社群bug和fix的進度,費時費力。
- 當用戶的 Kubernetes 出現問題時,可以從雲平臺獲得專業的技術支援。所以在公有云上使用(半)託管的 Kubernetes 服務,是一種很好的成本轉嫁方式,運維成本與雲平臺共同分擔。
當然仍有一些明顯的缺點
首先還是價格,當用戶購買一組虛機,需要付出的價格是 虛機 Flavor 單價 乘以 節點數量 N。其次,因為使用者獨佔一套 Kubernetes 叢集,規格不會太大,整體資源利用率仍然比較低。即使嘗試調優也效果不大,況且多數情況下使用者名稱不能完全自定義控制面元件的配置。另外,當叢集空閒資源不多而業務需要擴容時,還必須先擴叢集,端到端的擴容會受限於虛機的建立時間。

容器例項服務
第三種,嚴格說是使用者使用容器的形態,使用公有云的容器例項服務。
它的優點顯而易見:
- 使用者不感知底層叢集,也無需運維;
- 資源定價顆粒度足夠細,用多少買多少;
- 真正的秒級擴縮容,並且是秒級計費。
其缺點在於:
很多平臺的容器例項服務主要提供私有API,並不能很好相容kubernetes的API,而且容易被廠商繫結。

迫於滿足使用者使用K8S API的需求,這些容器例項服務也推出了基於virtual-kubelet專案的相容方案。通過把整個容器例項服務虛擬成 Kubernetes 叢集中的節點,對接 kubernetes master 來處理 Pod 的執行。
然而,由於整個容器例項服務被虛擬成了一個超級節點。Kubernetes 中原本針對多節點精心設計的一系列應用高可用相關特性都無法生效。另一個問題是這個基於 virtual-kubelet 專案的相容方案在資料面並不完整,這裡包括專案成員在Kube-proxy部署層級位置上的搖擺,以及仍無音訊的容器儲存如何相容。

實際上基於 Kubernetes 多租來構建容器例項服務,優點有很多,最大的在於是支援 K8S 原生 API 和命令列。使用者圍繞 Kubernetes 開發的應用都以直接在基於 K8S 的 Serverless Container 上部署和執行。因為容器可以做到秒級計費,使用者可以享受容器例項服務價格門檻較低的特點。另外,這種形態下通常是雲平臺來運維一個大資源池,使用者只需為業務容器的資源付費,不需要關心底層叢集的資源利用率,也沒有叢集運維的開銷。
這種形體現存的主要挑戰是 K8S 原生只支援軟多租,隔離性等方面還有有欠缺。

- 第一是 SaaS 平臺 。或其他基於 K8S 封裝提供的服務,它不直接暴露 K8S 的 API。因為有一層自己的 API 封裝,平臺可以做很多額外工作,比如自己實現租戶定義,所以對於 k8s 控制面的租戶隔離要求較低。而應用來自終端使用者,並不可信,所以實際上在容器執行時,需要較強的資料面資源隔離和訪問控制。
- 第二小公司的內部平臺 。使用者和應用都來自於公司內部,互信程度比較高,控制面和資料面都不需要做過多額外的隔離增強。原生的 K8S 就能滿足需要。
- 第三是大型企業的平臺 。這種場景下 K8S 的使用者,基本來自於企業內部的各個部門,開發部署的應用也是經過內部的驗證之後才可以上線。所以應用的行為是可信的,資料面不需要做太多的隔離。更多的是要在控制面做一些防護控制,來避免不同部門、業務之間的管理干擾,如API呼叫時,需要實現針對租戶的限流。
- 第四種場景,在公有云上對外提供一個多租的 K8S 平臺 。它對控制面和資料面的要求都是最高的。因為應用的來源不可控,很可能包含一些惡意程式碼。而 K8S 的 API 直接暴露給終端使用者,控制面的隔離能力,如區分租戶的API限流、訪問控制等都是不可或缺的。
- 一是租戶概念的引入、訪問控制實現。目前 K8S 仍然沒有原生的租戶概念,以 Namespace 為邊界的並不能很多好適配多租場景。
- 二是節點 (計算資源) 的隔離還有 Runtime 的安全。
- 三是網路隔離,K8S 預設網路全通的模式在這種景下會有很多問題。
華為雲的探索與實踐
下圖是華為雲容器例項服務的全貌,它基於 Kubernetes 打造,對終端使用者直接提供 K8S 的 API。正如前面所說,它最大的優點是使用者可以圍繞 K8S 直接定義執行應用。

。大家知道 K8S 現開源的版本最大隻能支援到 5000 節點,並且這是在 Google 雲上的驗證結果,而在很多其他的雲平臺往往達不到。主要是受限於底層網路和儲存系統。
所以在華為雲,我們的做法是通過一層封裝和引入 Federation 來獲得整體服務的超大規模。同時因為 K8S 原生多租能力非常有限,所以我們選擇將額外基於租戶的驗證、多租限流等工作放在這一層封裝中實現。但對於應用定義等介面,則是直接透傳 K8S 原生的 API 資料,只是在呼叫過程中增加如請求合法性等的校驗。圖中右側的容器網路、容器儲存,現有的開源方案是無法滿足的,所以華為雲採用自研的策略。
租戶概念和網路隔離
前面已經講過,K8S 原生並沒有租戶概念,只有一層以 Namespace 為邊界的隔離。在 Namespace 這一層,除了API物件的可見性隔離,K8S 還提供了 Resource Quota(資源總和限制)以及 Limit Range(定義每個Pod、Container能使用的資源範圍)等精細的配額管理能力。而在華為雲上,我們設計的租戶模型是:租戶(使用者)、專案、Namespace 三層模型,方便使用者管理多個專案的開發、測試、生產等不同階段。
網路隔離方面,採用多網路模型,一個專案中可以定義多個VPC,VPC 和 Namespace 是一對多的關係。使用者可以結合實際需要將開發、測試階段的應用部署在同個 VPC 的不同 Namespace 中便於除錯和問題定位,生產環境部署在擁有單獨 VPC 的 Namespace 保證不受其他活動干擾。

Runtime安全與隔離
再看 Runtime,由於是全物理機的模式,節點被不同的租戶共享,普通docker容器無法滿足Pod間的隔離性要求,Runtime採用的是安全容器(即早期的runV,現在的Kata Container)。 使用安全容器的主要思路,就是在Pod外圍包一層輕量級虛擬機器,這樣既保證了Pod間的隔離性,又相容了K8S原生Pod內容器共享網路和儲存的設計 。而包裝這層輕量級的虛機,因為裡面只需要執行容器,可以通過裁剪等手段優化到與普通容器相同數量級的啟動時間。

。使用者原本使用 Docker 容器的習慣幾乎沒有改變,在指定容器映象時也是需要指定所需執行的 Docker 映象,外層輕量級虛機的映象直接由宿主機提供。這樣既解決了安全隔離的問題,又不會給使用者帶來額外的切換成本。

最後,讓我們來回顧一下本次分享的關鍵內容。
- 首先,我們基於 Kubernetes 構建了華為雲容器例項服務的核心部分,在其上封裝實現了多租戶的定義和訪問隔離。對使用者來說,最大的好處是可以使用原生 K8S 的 API 和命令列,不需要感知 K8S 叢集和底層資源,不需要在使用前建立叢集,使用過程中也不用擔心叢集出現任何問題,完全由平臺自身來保證服務的可用性。
- 其次,在計算資源隔離方面,我們採用是Docker原生API後端對接 kata container,可以最大限度相容兩個專案的生態。而對於終端使用者來說,使用者只需要知道安全隔離足夠可靠。而在網路隔離方面,採用多網路的模型,使用者可以定義多個 VPC,將 Namespace 和應用建立到不同的 VPC 中,以此實現彼此之間的隔離。
- 此外,針對高效能運算場景,我們還完成了GPU、FPGA加速晶片的分配排程優化,配合高效能網路與本地儲存加速,進一步提升了端到端計算效能。
結語
以上是華為雲對Kubernetes在Serverless Container產品落地中的實踐經驗。隨著產品的成熟,我們也計劃將一些共性的增強點回饋社群,推動Kubernetes在面向Serverless容器和多租隔離等場景的能力補齊和生態發展。