當前 Kubernetes 已經成爲名副其實的企業級容器編排規範,不少雲平臺都開始提供兼容 Kubernetes 接口的容器服務。而在多用戶支持方面,多數平臺選擇直接提供專屬虛機集羣,用戶須要花費大量精力處理集羣規模、資源利用率、費用等問題。 本次分享帶來的是華爲雲在基於 K8S 構建企業級 Serverless Container 平臺過程當中的探索與實踐,涉及容器安全隔離、多租管理、Serverless 理念在 Kubernetes 平臺的落地等相關內容。docker
首先來了解一下華爲雲在 Kubernetes 的發展歷程。2014 年,華爲雲就開始研究並使用 Kubernetes,早期的重點是將 Kubernetes 應用在私有云環境中。2016 年,華爲公有云上發佈了容器引擎平臺 ( CCE),它的形式與市面上多數的公有云 Kubernetes 服務(如 GKE、AKS) 相似,是給用戶提供完整一套託管的K8S集羣。而在今年年初,華爲雲發佈了 Kubernetes 容器實例服務(Serverless Container),不過它與業界一些傳統的容器實例服務不太同樣。後端
衆所周知,容器技術有三大好處。安全
人們使用 Kubernetes 的一種常見形式就是在本身的數據中心搭建集羣。網絡
這種作法的優勢在於:less
可是缺點也很明顯:首先,不少人在自建時只看中了 Kubernetes,對周邊配套並沒作過很深度的研究,在實施過程當中就會面臨網絡、存儲等配套系統的選型問題。其次,用戶須要負擔 100% 的運維成本,並且資源的投入每每是一次性(或階段性的),投入成本門檻很是高。此外,在自建的環境中 Kubernetes 的集羣數量、中的單個集羣規模每每不會很大,因此業務部署規模比較大時,彈性伸縮還會受限於底層資源規模,恰恰硬件資源的擴容速度每每慢得不可想象。最後,開發者習慣於作比較多的資源預留,所以資源利用率也很是有限。也就是說,自建者還要爲全套資源利用率買單。 運維
第二種 Kubernetes 的常見形態是公有云的(半)託管集羣。性能
能夠這樣理解,用戶購買一組虛機,雲平臺則自動在這些機器上部署一套 Kubernetes,而半托管含義在於有些平臺,它的控制面多是附送的。測試
這種形態的優勢是:優化
固然仍有一些明顯的缺點spa
首先仍是價格,當用戶購買一組虛機,須要付出的價格是 虛機 Flavor 單價 乘以 節點數量 N。其次,由於用戶獨佔一套 Kubernetes 集羣,規格不會太大,總體資源利用率仍然比較低。即便嘗試調優也效果不大,何況多數狀況下用戶名不能徹底自定義控制面組件的配置。另外,當集羣空閒資源很少而業務須要擴容時,還必須先擴集羣,端到端的擴容會受限於虛機的建立時間。
第三種,嚴格說是用戶使用容器的形態,使用公有云的容器實例服務。
它的優勢顯而易見:
其缺點在於:
不少平臺的容器實例服務主要提供私有API,並不能很好兼容kubernetes的API,並且容易被廠商綁定。
迫於知足用戶使用K8S API的需求,這些容器實例服務也推出了基於virtual-kubelet項目的兼容方案。經過把整個容器實例服務虛擬成 Kubernetes 集羣中的節點,對接 kubernetes master 來處理 Pod 的運行。然而,因爲整個容器實例服務被虛擬成了一個超級節點。Kubernetes 中本來針對多節點精心設計的一系列應用高可用相關特性都沒法生效。另外一個問題是這個基於 virtual-kubelet 項目的兼容方案在數據面並不完整,這裏包括項目成員在Kube-proxy部署層級位置上的搖擺,以及仍無音訊的容器存儲如何兼容。
看了前面這麼多的背景,你可能不由要問: 爲何不嘗試使用 Kubernetes 的多租方案來構建 Serverless Container 服務?實際上基於 Kubernetes 多租來構建容器實例服務,優勢有不少,最大的在因而支持 K8S 原生 API 和命令行。用戶圍繞 Kubernetes 開發的應用都以直接在基於 K8S 的 Serverless Container 上部署和運行。由於容器能夠作到秒級計費,用戶能夠享受容器實例服務價格門檻較低的特色。另外,這種形態下一般是雲平臺來運維一個大資源池,用戶只需爲業務容器的資源付費,不須要關心底層集羣的資源利用率,也沒有集羣運維的開銷。
這種形體現存的主要挑戰是 K8S 原生只支持軟多租,隔離性等方面還有有欠缺。
接下來咱們回顧一下 K8S 中典型的多租場景。下圖是華爲雲容器實例服務的全貌,它基於 Kubernetes 打造,對最終用戶直接提供 K8S 的 API。正如前面所說,它最大的優勢是用戶能夠圍繞 K8S 直接定義運行應用。
這裏值得一提是,咱們採用了全物理機的方案,對於端到端資源利用率有一個很大的提高。而在 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,因爲是全物理機的模式,節點被不一樣的租戶共享,普通docker容器沒法知足Pod間的隔離性要求,Runtime採用的是安全容器(即早期的runV,如今的Kata Container)。使用安全容器的主要思路,就是在Pod外圍包一層輕量級虛擬機,這樣既保證了Pod間的隔離性,又兼容了K8S原生Pod內容器共享網絡和存儲的設計。而包裝這層輕量級的虛機,由於裏面只須要運行容器,能夠經過裁剪等手段優化到與普通容器相同數量級的啓動時間。
接口層面,按照社區如今的進展,推薦的作法是使用 CRI (container runtime interface) 直接對接安全容器的 CRI-shim 實現。不過由於項目啓動很早,CRI 還沒有成熟, 咱們採用的是在 Docker 內部分支處理的方案:在容器引擎服務中,仍然是原來的邏輯,直接建立普通容器;而在咱們的容器實例服務裏,經過 Docker API 調用建立出來的則是安全容器。用戶本來使用 Docker 容器的習慣幾乎沒有改變,在指定容器鏡像時也是須要指定所需運行的 Docker 鏡像,外層輕量級虛機的鏡像直接由宿主機提供。這樣既解決了安全隔離的問題,又不會給用戶帶來額外的切換成本。最後,讓咱們來回顧一下本次分享的關鍵內容。
以上是華爲雲對Kubernetes在Serverless Container產品落地中的實踐經驗。隨着產品的成熟,咱們也計劃將一些共性的加強點回饋社區,推進Kubernetes在面向Serverless容器和多租隔離等場景的能力補齊和生態發展。