當前 Kubernetes 已經成為名副其實的企業級容器編排規範,很多雲平臺都開始提供相容 Kubernetes 介面的容器服務。而在多使用者支援方面,多數平臺選擇直接提供專屬虛機叢集,使用者需要花費大量精力處理叢集規模、資源利用率、費用等問題。
本次分享帶來的是華為雲在基於 K8S 構建企業級 Serverless Container 平臺過程中的探索與實踐,涉及容器安全隔離、多租管理、Serverless 理念在 Kubernetes 平臺的落地等相關內容。
Kubernetes 在華為雲的歷程
首先來了解一下華為雲在 Kubernetes 的發展歷程。2014 年,華為雲就開始研究並使用 Kubernetes,早期的重點是將 Kubernetes 應用在私有云環境中。2016 年,華為公有云上釋出了容器引擎平臺 ( CCE),它的形式與市面上多數的公有云Kubernetes服務(如 GKE、AKS) 類似,是給使用者提供完整一套託管的K8S叢集。而在今年年初,華為雲釋出了 Kubernetes 容器例項服務(Serverless Container),不過它與業界一些傳統的容器例項服務不太一樣。
容器的三大好處,為應用而生
眾所周知,容器技術有三大好處。一是它提供資源隔離,使用者很容易通過應用合設來提升資源利用率;二是,它具備秒級彈性的能力。因為容器本身技術特點,不用載入重型虛擬化,所以它可以做到非常快速的彈性擴縮容;三是,容器映象技術,解決了包括應用及其依賴環境的一致性問題,簡化業務交付流程。
但在實際環境中,容器技術帶來的終端便利有多少呢?這還得從Kubernetes的使用形態談起。
Kubernetes 的常見使用形態
私有云部署Kubernetes
人們使用Kubernetes的一種常見形式就是在自己的資料中心搭建叢集。
這種做法的優點在於:第一,可以享受DIY過程帶來的樂趣和成就感(當然也可能隨使用時間的增長,問題越來越多而變成苦難)。第二,在全套私有化的模式下,資料請求都在本地處理,不會存在隱私顧慮。第三,資源規劃、叢集安裝部署升級,都是使用者自己端到端控制。
但是缺點也很明顯:首先,很多人在自建時只看中了 Kubernetes,對周邊配套並沒做過很深度的研究,在實施過程中就會面臨網路、儲存等配套系統的選型問題。其次,使用者需要負擔 100% 的運維成本,而且資源的投入往往是一次性(或階段性的),投入成本門檻非常高。此外,在自建的環境中 Kubernetes 的叢集數量、中的單個叢集規模往往不會很大,所以業務部署規模比較大時,彈性伸縮還會受限於底層資源規模,偏偏硬體資源的擴容速度往往慢得不可想象。最後,開發者習慣於做比較多的資源預留,因此資源利用率也非常有限。也就是說,自建者還要為全套資源利用率買單。
公有云半托管Kubernetes專屬叢集
第二種 Kubernetes 的常見形態是公有云的(半)託管叢集。可以這樣理解,使用者購買一組虛機,雲平臺則自動在這些機器上部署一套 Kubernetes,而半托管含義在於有些平臺,它的控制面可能是附送的。
這種形態的優點是:
(1)使用者自己擁有叢集,不用擔心與其他使用者共用一套 Kubernetes 可能引起一系列干擾問題。
(2)雲平臺在提供 Kubernetes 服務時,往往經過大量的測試和調優,所以給出叢集的配置是在自家平臺上的最佳實踐。使用者通過這種模式在雲上執行 Kubernetes,可以獲得比自己部署運維好很多的體驗。
(3) Kubernetes 社群釋出新版本後,雲平臺會至少做一輪額外的測試、問題修復,再上線並推薦使用者升級。這用就節省了使用者對升級時機評估的工作量。而直接使用開源版本的使用者,如果對新版本跟進太快,自己要踩很多坑,但要延後到哪個版本再升,則要持續跟進社群bug和fix的進度,費時費力。
(4)當使用者的 Kubernetes 出現問題時,可以從雲平臺獲得專業的技術支援。所以在公有云上使用(半)託管的 Kubernetes 服務,是一種很好的成本轉嫁方式,運維成本與雲平臺共同分擔。
當然仍有一些明顯的缺點,首先還是價格,當使用者購買一組虛機,需要付出的價格是 虛機 Flavor 單價 乘以 節點數量 N。其次,因為使用者獨佔一套 Kubernetes 叢集,規格不會太大,整體資源利用率仍然比較低。即使嘗試調優也效果不大,況且多數情況下使用者名稱不能完全自定義控制面元件的配置。另外,當叢集空閒資源不多而業務需要擴容時,還必須先擴叢集,端到端的擴容會受限於虛機的建立時間。
容器例項服務
第三種,嚴格說是使用者使用容器的形態,使用公有云的容器例項服務。
它的優點顯而易見:使用者不感知底層叢集,也無需運維;資源定價顆粒度足夠細,用多少買多少;真正的秒級擴縮容,並且是秒級計費。
其缺點在於:很多平臺的容器例項服務主要提供私有API,並不能很好相容kubernetes的API,而且容易被廠商繫結。
迫於滿足使用者使用K8S API的需求,這些容器例項服務也推出了基於virtual-kubelet專案的相容方案。通過把整個容器例項服務虛擬成 Kubernetes 叢集中的節點,對接 kubernetes master 來處理 Pod 的執行。
然而,由於整個容器例項服務被虛擬成了一個超級節點。Kubernetes 中原本針對多節點精心設計的一系列應用高可用相關特性都無法生效。另一個問題是這個基於virtual-kubelet專案的相容方案在資料面並不完整,這裡包括專案成員在Kube-proxy部署層級位置上的搖擺,以及仍無音訊的容器儲存如何相容。
如何基於 K8S 多租能力構建 Serverless Container
看了前面這麼多的背景,你可能不禁要問:為什麼不嘗試使用 Kubernetes 的多租方案來構建 Serverless Container 服務?實際上基於 Kubernetes 多租來構建容器例項服務,優點有很多,最大的在於是支援 K8S 原生 API 和命令列。使用者圍繞 Kubernetes 開發的應用都以直接在基於 K8S 的 Serverless Container 上部署和執行。因為容器可以做到秒級計費,使用者可以享受容器例項服務價格門檻較低的特點。另外,這種形態下通常是雲平臺來運維一個大資源池,使用者只需為業務容器的資源付費,不需要關心底層叢集的資源利用率,也沒有叢集運維的開銷。
這種形體現存的主要挑戰是 K8S 原生只支援軟多租,隔離性等方面還有有欠缺。
接下來我們回顧一下 K8S 中典型的多租場景。
第一是 SaaS 平臺,或其他基於 K8S 封裝提供的服務,它不直接暴露 K8S 的 API。因為有一層自己的 API 封裝,平臺可以做很多額外工作,比如自己實現租戶定義,所以對於 k8s 控制面的租戶隔離要求較低。而應用來自終端使用者,並不可信,所以實際上在容器執行時,需要較強的資料面資源隔離和訪問控制。
第二小公司的內部平臺。使用者和應用都來自於公司內部,互信程度比較高,控制面和資料面都不需要做過多額外的隔離增強。原生的 K8S 就能滿足需要。
第三是大型企業的平臺,這種場景下 K8S 的使用者,基本來自於企業內部的各個部門,開發部署的應用也是經過內部的驗證之後才可以上線。所以應用的行為是可信的,資料面不需要做太多的隔離。更多的是要在控制面做一些防護控制,來避免不同部門、業務之間的管理干擾,如API呼叫時,需要實現針對租戶的限流。
第四種場景,在公有云上對外提供一個多租的 K8S 平臺,它對控制面和資料面的要求都是最高的。因為應用的來源不可控,很可能包含一些惡意程式碼。而 K8S 的 API 直接暴露給終端使用者,控制面的隔離能力,如區分租戶的API限流、訪問控制等都是不可或缺的。
總結一下,對於 K8S 來說,如果要在公有云場景下提供 Serverless Container 服務,需要解決三大類挑戰。一是租戶概念的引入、訪問控制實現。目前 K8S 仍然沒有原生的租戶概念,以 Namespace 為邊界的並不能很多好適配多租場景。二是節點 (計算資源) 的隔離還有 Runtime 的安全。三是網路隔離,K8S 預設網路全通的模式在這種景下會有很多問題。