k8s 多租戶實現與優化

多數情況下,Kubernetes 用戶爲了滿足多個團隊和多個客戶的需求會共享集羣,這通常用術語多租戶來描述。多租戶節省成本並簡化管理。雖然 Kubernetes 沒有終端用戶或租戶的概念,但它提供了幾個功能來幫助管理不同的租戶需求。基於這些特性,Kubernetes 社區出現了多租戶項目。

在本文中,我們將討論 Kubernetes 中的多租戶問題。特別是,我們將徹底研究多租戶的兩種實現方式:集羣共享和多集羣—併爲陷入這方面困惑的企業提供建議。

控制面隔離

Kubernetes 提供了三種實現控制平面隔離的機制,即命名空間、RBAC 和配額。

幾乎每個 Kubernetes 用戶都熟知的概念,命名空間用於提供一個單獨的名稱空間。不同命名空間中的對象名稱可以相同。此外,RBAC 和配額的作用域也僅限於名稱空間。

基於角色的訪問控制 (RBAC) 通常用於在 Kubernetes 控制平面對用戶和工作負載 (服務帳戶) 強制授權。通過設置適當的 RBAC 規則,可以實現對 API 資源的隔離訪問。

ResourceQuota 可用於對命名空間的資源使用設置上限。這確保了租戶不能壟斷集羣的資源或超過其控制平面,從而最小化 “干擾其他命名空間資源” 問題。使用 ResourceQuota 的一個限制是,當向命名空間應用配額時,Kubernetes 還要求用戶爲該名命名間中的每個容器指定資源請求和限制。

這三種機制雖然在一定程度上可以實現控制平面隔離,但不能一勞永逸地解決問題。集羣範圍內的資源 (如 CRD) 不能用這些機制很好地隔離。

數據面隔離

數據平面隔離通常涉及三個方面: 容器運行時、存儲和網絡。

由於內核由容器和主機共享,因此攻擊者可以利用應用程序和系統層中未打補丁的漏洞進行容器突破和遠程代碼執行,從而允許訪問主機資源或其他容器。這可以通過在隔離的環境中運行容器來解決,例如 vm(Kata 容器) 和用戶模式內核 (例如,gVisor)。

存儲隔離應該確保卷不被跨租戶訪問。因爲 StorageClass 是集羣範圍的資源,所以 reclaimPolicy 應該指定爲 Delete,以防止跨租戶訪問 pv。此外,還應禁止使用 hostPath 等卷,以避免濫用節點的本地存儲。

網絡隔離通常通過設置 NetworkPolicy 來實現。默認情況下,所有 pod 都可以相互通信。使用 NetworkPolicy 可以限制 pods 之間的網絡通信,減少意外的網絡訪問。高級網絡隔離可以通過服務網格實現。

實現多租戶

上面提到的控制面隔離和數據面隔離只是 Kubernetes 提供的單獨功能。在將這些特性作爲集成的多租戶解決方案交付之前,還有很長的路要走。幸運的是,Kubernetes 社區有許多專門解決多租戶問題的開源項目。這些項目分爲兩類,一類通過命名空間劃分租戶,另一類爲租戶提供虛擬控制平面。

每個租戶一個命名空間

在 Kubernetes 的控制面隔離中,RBAC 和 ResourceQuota 都受到命名空間的限制。雖然按命名空間劃分租戶似乎很容易,但規定每個租戶一個命名空間有很大的侷限性。例如,單個租戶或應用團隊再劃分,這種細粒度級別幾乎無法完成,這增加了管理難度。有鑑於此,Kubernetes 正式提供了一種支持分層命名空間的控制器。像 Capsule 和 kiosk 這樣的第三方開源項目也提供了更復雜的多租戶支持。

虛擬控制面

另一種選擇是爲每個租戶提供單獨的虛擬控制面,以便完全隔離租戶的資源。虛擬控制面通常是通過爲每個租戶運行一組單獨的 apiserver 來實現的,同時使用控制器將資源從租戶 apiserver 同步到原有的 Kubernetes 集羣。每個租戶只能訪問其相應的 apiserver,而原始 Kubernetes 集羣的 apiserver 通常不能從外部訪問。

虛擬控制面的完全隔離通常需要較高的資源消耗。但與數據面隔離技術結合使用,它是一個更徹底和安全的多租戶解決方案。其中一個例子是 vcluster 項目。

兩種方案的對比

是使用 “每個租戶一個命名空間” 還是使用虛擬控制面實現多租戶,基本取決於應用場景。一般來說,通過命名空間劃分租戶減少了隔離性和靈活性,同時適用於輕量級場景,例如在多個團隊之間共享集羣。而在多個客戶的場景中,虛擬控制平面通常可以提供更安全的隔離。

多集羣解決方案

從上面的討論可以看出,共享 Kubernetes 集羣不是一件容易的事情;多租戶不是 Kubernetes 的內置特性,只能在其他項目的支持下在控制和數據平面上的租戶隔離中實現。這爲整個解決方案帶來了相當大的學習和適應成本。因此,我們看到越來越多的用戶轉而採用多集羣解決方案。

與集羣共享解決方案相比,多集羣解決方案有利有弊,優點是隔離程度高、邊界清晰,缺點是開銷和運維成本高。由於每個集羣都需要獨立的控制面和工作節點,Kubernetes 集羣通常構建在虛擬機上,以提高物理集羣的利用率。然而,傳統的虛擬化產品往往又大又重,因爲它們需要處理廣泛的場景。這使得它們過於昂貴,無法成爲支持虛擬化 Kubernetes 集羣的最佳選擇。

基於此,我們認爲一個理想的虛擬化 Kubernetes 集羣的虛擬化平臺應該具備以下特徵:

而這些特性正是 Virtink 虛擬化引擎所具有的。Virtink 是 SmartX 爲 Kubernetes 發佈的開源輕量級虛擬化插件。基於 Cloud Hypervisor 項目,Virtink 能夠在 Kubernetes 上編排輕量級 vm。

Virtink 儘可能地使用 virtio 來提高 I/O 效率。在安全性方面,用 Rust 語言編寫的 Cloud Hypervisor 項目的內存管理更加安全。此外,不支持遺留的和不必要的硬件,以減少虛擬機暴露的攻擊面,提高主機安全性。

總的來說,Virtink 更加輕量級、高效和安全,爲 Kubernetes 中的 Kubernetes 提供了更理想的虛擬化支持,同時降低了虛擬化層的開銷。

此外,爲了滿足在 Virtink 上創建、操作和維護虛擬化 Kubernetes 集羣的需求,社區開發了 knest 命令行工具,幫助用戶一鍵式創建和操作集羣。特別是,要在 Virtink 集羣上創建一個虛擬化的 Kubernetes 集羣,用戶只需運行 knest create 。還支持一鍵擴展。

總結

儘管 Kubernetes 沒有內置的多租戶,但它提供了一些細粒度的特性支持。多租戶集羣共享可以通過這些特性和一些第三方工具實現,但這需要額外的學習和運維成本。從這個角度來看,多集羣解決方案更合適,已經被很多用戶採用。但是,用戶可能會遇到傳統虛擬化平臺效率低、成本高等問題。

基於高效和安全的 Cloud Hypervisor 項目,開源虛擬化引擎 Virtink 在 Kubernetes 上編排輕量級 vm 方面進行了優化。還提供了一個 knest 命令行工具,允許用戶通過簡單的單擊就可以創建和管理集羣,降低了多個集羣的整體運維成本。

參考文獻

[virink] https://www.smartx.com/blog/2022/07/virtink-for-k8s-en/

[vcluster] https://github.com/loft-sh/vcluster

[capsule] https://github.com/clastix/capsule

[kiosk] https://github.com/loft-sh/kiosk

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/g97I8Y8M31WPbVkkyunsVw