Multi-Tenancy Kubernetes Cluster Part 1: 認命吧!有一好,就沒兩好!

smalltown
Starbugs Weekly 星巴哥技術專欄
13 min readApr 25, 2021

Background

隨著 K8s 各方面功能性越來越齊全,生態系持續壯大之下,很多組織都已經開始使用它來運行重要的應用服務,而把程式部署到 K8s 中相當地簡單,但是當組織內使用的人和部署在叢集內的應用越來越多時,該怎麼管理這些人事物就會開始變成令人苦惱的問題了 ╮(╯_╰)╭ 尤其當規模大到一個程度時,有一個聲音一定會一直在維護人員的腦中迴盪:究竟該讓不同使用者或是應用服務一起使用一座 K8s Cluster,還是讓單一個使用者獨立使用一座 K8s Cluster? 雖然文章才剛開始,但我可以先說答案,答案就是…這要看情況,有講跟沒講一樣 (被揍飛

讓很多不同使用者一起共享資源的做法,稱為 Multi-Tenancy,其實這個術語從 1960 年開始就有了,有的公司需要使用運算資源時,並不會自己去買伺服器,而是跑去跟持有大型主機的供應商租用一部份運算資源,而因為大家一起分享共用,那麼隔離性就變得很重要了,畢竟住在同一個屋簷下最怕遇到恐怖的室友或是惡鄰居了,底下就讓我們開始來談談 Kubernetes 與 Multi-Tenancy 的相關議題:

  • 該選擇哪一種 Tenancy Model 來維運 Kubernetes
  • 各種 Kubernetes Tenancy 所遇到的挑戰和解決方案

Single-Tenancy K8s or Multi-Tenancy K8s?

這並不是一個簡易的單選題,最大的原因在於 K8s 一開始的架構設計,還有現在這個領域的相關解決方案並不成熟,所以沒有辦法選擇其中一個就解決所有的需求,所以接下來會開始分析原因,還有當前建議的做法

首先讓我們將一些術語定義一下,因為除了 Multi-Tenancy 和 Single-Tenancy 這兩個類別之外,其實 Multi-Tenancy 內還分成軟的跟硬的,也就是所謂的 Soft Multi-Tenancy 和 Hard Multi-Tenancy:

Soft Multi-Tenancy

所謂的 Soft Multi-Tenancy 是指不同的使用者或是應用程式間並沒有嚴格的隔離開來,對於受信任和已知的租戶 (Tenant) 來說是一種適宜的解決方案,亦即組戶們都相當地和藹和親,理論上不會去濫用別人的資源,也就是說大家都是好鄰居很有公德心,所以採用 Soft Multi-Tenancy 時的隔離方式,主要是希望避免意外事故的發生,而不是用來防範某個租戶對於其他租戶的惡意攻擊

Hard Multi-Tenancy

而 Hard Multi-Tenancy 則是對不同的使用者或是應用程式間實施嚴格的隔離方式,用來避免某個租戶的惡意行為給其他的租戶們帶來困擾,也就是說遇到沒有公德心且會侵犯其他人的惡鄰居,所以他可以用來當作不信任租戶間的解決方案,例如很多人使用的 AWS 就算是採用 Hard Multi-Tenancy 模式,不同的使用者之間並不會互相影響,不然要是自己儲存的機敏資料跟運行服務會被別人存取或是影響到的話,應該就沒有人敢用 AWS了

K8s Tenancy Mode Selection

再來就是通常在做這個選擇的時候,維運人員最主要考慮的不外乎安全性和可用性這兩個:

安全性

K8s 預設使用 Namespace 和 RBAC 的軟性隔離方式並沒有辦法確保哪天會不會突然來個 Vulnerability 允許惡意使用者存取到另外一個 Namespace 的資源跟資料;節點內的任意元件也可能出現 Vulnerability,讓攻擊者存取到任意的資訊,畢竟事事無絕對,每天又那麼多 CVE 冒出來,想躲也躲不掉

可用性

Control Plane 自己本身可能因為負荷不了大量存取而出問題,抑或是單純被某個出問題的應用服務給弄壞掉,進而導致其他應用服務受到影響;最常見的就是 Alpha, Beta 的某個服務有 Bug 或是在做測試時,導致身在同一個 K8s Cluster 的其他服務也受到影響,假如 Production 服務也在同一座 Cluster 內,那甚至會影響到真實使用者

一個成熟組職都會希望朝 Hard Multi-Tenancy 的方向走,因為既可以讓資源利用率最大化 (只需要一座 K8s Cluster),而且又可以確保安全性和可用性,但是不諱言採用 Multi-Tenancy 一定會提高 K8s 各個層面的複雜度,也可能會有一些限制產生,不過在軟體工程領域本來就有各種 Trade Off 需要去做抉擇,那接著就來看目前 K8s 在 Multi-Tenancy 這個領域所遭遇到的問題和解決方法

Multi-Tenancy Kubernetes

為什麼目前的 K8s 還無法達成 Hard Multi-Tenancy 模式,在正式開始進入主軸之前,先來看看 K8s 在導入 Hard Multi-Tenancy 時需要注意哪些重點:

  • 使用者管理:既然要讓多人使用,要如何管理這些使用者帳號便是首要重點,而且一般來說,組織裡面應該都會有統一管理使用者帳號的系統,例如 MicroSoft AS, Google Workspace, LDAP…等,如何讓既有的使用者帳號系統跟 K8s 整合再一起就是需要被先解決的問題,畢竟沒有管理單位會想要每多採用一個服務就需要多管理一組使用者帳號
  • 資源共享:多人一起使用同一座 K8s Cluster 的話,要如何讓 CPU, Memory…等資源一起公平的分享便是第二個重要的課題,畢竟就像之前提到的,沒有人會希望某個失去控制的應用服務,把所有資源耗盡進而去影響到其他的應用服務
  • 隔離性:第三個重點就是如何讓不同 Tenancy 之間的應用服務具有良好的隔離性,避免他們彼此之間可以互相溝通 (這裡是指不同租戶間的應用服務本來就沒有相依關係,不需要去存取其他租戶的應用服務)

Weak Soft Multi-Tenancy Kubernetes

K8s 預設的 Namespace 提供了邏輯性的隔離功能給想要使用 Multi-Tenancy 模式的人使用:

  • RBAC: 用來定義權限政策,並使用 Role 或是 ClusterRole 將權限政策綁定到使用者帳號或是 ServiceAccount
  • Limit Ranges: 在 Pod 中用來定義使用到的 CPU 和 Memory 資源的預設和最大值
  • Resource Quotas: 定義 CPU 和 Memory 在特定 Namespace 內的最大使用量
  • Network Policies: 有點像是防火牆規則,用來定義 K8s 內資源是否允許或是不允許連接到什麼地方去
  • Pod Security Policies: 定義 Pod 在建立還有修改時應該遵守的政策規則

Achieve Hard Multi-Tenancy?

接著來看看這些內建功能對於要採用 Hard Multi-Tenancy 來說是不是有達標:

🙅 K8s 在帳號管理這塊沒有多加著墨,看來勢必得依靠第三方解決方案的整合才能達成

🙆 資源共享這塊算是勉強及格,假如事先定義好 Namespace Resource Quotas,且所有的使用者都有定義好 Resource 的 Limit Range 的話,租戶之間就比較不會互相造成影響

🤷 隔離性我覺得沒有很好,因為 Namespace 只是邏輯性的隔離,透過 Networks Policy 和 RBAC 控制存取限制,要是這兩個東西設定錯誤,或是突然出現什麼 Vulnerability,就有可能讓不同 Namespace 的租戶間可以互相存取

所以 K8s 預設的 Multi-Tenancy 功能不止沒有辦法達成 Hard Multi-Tenancy,連 Soft Multi-Tenancy 都只能算是勉強達標,因為必須建立在所有的租戶都是受信任且有公德心的基礎之上,順便一提,Pod Security Policies 在 K8s V1.21 宣布即將在 V1.25 淘汰掉,這樣一來,在限制租戶不做壞事能力就又減弱了

Enhanced Kubernetes Weak Soft Multi-Tenancy

從上面了解到 K8s 預設提供的 Multi-Tenancy 功能其實還有很大的進步空間,所以市場上開始有不少解決方案的推出,讓我們一樣從使用者管理,資源共享,隔離性三個要點來介紹

使用者管理

在使用者管理上可以使用 dex 這個開源專案,他使用 OpenID Connnect 跟其他第三方服務整合,例如:常見的 LDAP, SAML…等,為 K8s 提供身份驗證服務,像 Argo CD 就是直接把 dex 整合在其中

資源共享 & 隔離性

正所謂逃得了和尚逃不了廟,畢竟還是在 K8s 內,所以也不可能真的有解決方案來幫助 K8s 做到不怕惡鄰居想要破壞的資源共享和隔離性,只能利用上面提到的既有功能來做加強的方式,讓我把這些解決方案分成預防型和補救型兩種作介紹

預防型: 這類型的工具構築在原來 K8s 提供的 Multi-Tenancy 功能之上,提供一個比較完整的框架,讓使用者輕易地去管理不同角色所應該具有的權限,底下舉幾個自己最近看到的開源專案:

  • Argo CD: 利用 casbin 所實做出來的 RBAC 管理,搭配 Project CRD,讓K8s 管理人員很輕易地實作出想要的權限控制
  • kiosk: 由 loft.sh 所推出的 kiosk,則是主打可以讓 K8s 達成 Multi-Tenancy 的延伸套件,整體架構還滿完整的,目前整再規劃 Multi-Cluster 的功能
  • Flux 2: 雖然是 Flux 第二版,整個架構改進滿多的,不管是多個 Cluster 或是 K8s Multi-Tenancy 的實作,主要都透過各種 CRD 與資料夾結構的拆分來達成

補救型: 但總是會有人不小心或是故意違反規則限制,這時候就可以使用Policy as Code 工具,而這類的工具主要是透過整合 K8s Admission Controllers,讓違反規則的請求被拒絕,例如:Kyverno OPA Gatekeeper:

Hard Multi-Tenancy Kubernetes

雖然像上面提到利用第三方工具來加強 Multi-Tenancy 的功能,不過並無法讓 K8s 達成 Hard Multi-Tenancy,所以是不是沒救了?其實 K8s 社群已經注意到大家有這一塊的需求,所以成立了 Kubernetes Working Group for Multi-Tenancy,裡面有很豐富的資訊給大家參考:

  • Benchmarks: 裡面有 K8s 要如何達成 Multi-Tenancy 的 Guideline,而且還有 kubectl plugin kubectl-mtb,可用他來檢驗目前 K8s 的設定是否符合 Multi-Tenancy
  • Hierararchical namespaces (aka HNC): 有階層從屬關係的進階版 Namespace,例如可以建立一個 Namespace 給團隊 A 使用,然後在這個 Namespace 再建立 Child Namespace 給團隊 A 的應用程式使用;換言之,團隊 A 不需具有 Cluster Admin 也能夠在自己團隊的 Namespace 底下建立 Namespace 給應用服務使用
  • Tenant Operator: 用來管理 Tenant 的一系列 CRD
  • Virtual clusters: 在單一個 K8s Cluster 裡面運行多個虛擬的 K8s Cluster

K8s Virtual Cluster 概念的提出應該是上面最有亮點的一個,不知道未來是不是真的會往這個方向發展就是了,但有興趣的人可以參考下面兩個專案

  • Multi-Tenancy SIG Virtual Cluster: 由 K8s 官方社群所開發的專案,去年在 Kubecon EU 有 Talk Demo 這個功能,他可以讓每個 Tenant 擁有自己的 K8s Control Plane 進而達成 Hard Multi-Tenancy,也有使用
  • loft vClusters: 由 loft.sh 推出的 Virtual Cluster 實作方案,本來是付費服務 (三個人以下免費),不過在這幾天 Open Source 出來了,底層是使用 K3s,目前對於 Hard Multi-Tenancy 有急迫性的人可以參考看看

Single-Tenancy K8s

看完上面的分析之後,就可以發現目前是無法在 K8s 達成 Hard Multi-Tenancy 的,所以要是想提供最安全,可用性最高的 K8s 環境,理所當然就是讓每個應用服務甚至是每個人自己一座 K8s Cluster 就沒問題了!不過大家應該馬上可以想到這樣做的話會有一些缺點:

  • 多座 K8s Cluster 的安裝,設定,升級,備份,還原…等,不只常常需要升級,功能還常常大改動
  • 多座 K8s Cluster 跟各種基礎元件的整合,例如儲存空間,網路,安全工具…等,在不同的環境架設都會有不同的事情需要做
  • 如何讓使用者安全的存取多座 K8s Cluster (Authentication 和 Authorization),且每一座的存取權限設定都不同,又要如何控制應用服務間的連線或是存取
  • 如何集中化管理這些 K8s Cluster 的 Log 和 Metric 跟各種 Tracing 資料
  • 資源使用效能不彰是一定的,除了會花比較多錢之外,其實上面列的管理成本比花費在 Cloud Provider 或是 Data Center 的金錢都來得高

顯而易見地不會有人選擇 Single-Tenancy 模式架設 N 個 K8s Cluster 給 N 個使用者或是應用服務使用,為了安全性和可用性也不會選擇將所有的使用者和應用服務放在同一座 K8s Cluster 中,真正可行的作法是決定可控且合理的 Cluster 數量,然後再依據需求選擇要比較偏向 Soft Multi-Tenancy 或是 Hard Multi-Tenancy 的維運模式;讓多座 K8s Cluster 運行在 Multi-Tenancy 模式下已經是負責維運 K8s 的人一定要面對的問題,不過礙於篇幅問題,維運多座 K8s Cluster 的解決方案就不在此一一細談比較,僅列上目前比較主流的解決方案供有興趣的人參考:

Conclusion

因此可以知道目前 K8s Multi-Tenancy 的狀況,除非 K8s Virtual Cluster 變得越來越成熟,不然就一定需要依靠多座 K8s Cluster 才能達成比較好的隔離性還可用性,就如同上圖所示,當需要越往 Hard Multi-Tenancy 方向走時,所需要的 K8s Cluster 就會越多,維運人員的痛苦指數也就會越高;而在下一篇系列文章,會就這樣的情況繼續深入探討,什麼樣的工具可以同時滿足 Multi-Cluster & Multi-Tenancy 的需求,讓維運人員可以事半功倍!

Reference

--

--

smalltown
Starbugs Weekly 星巴哥技術專欄

原來只是一介草 QA,但開始研究自動化維運雲端服務後,便一頭栽進 DevOps 的世界裏,熱愛鑽研各種可以提升雲端服務品質及增進團隊開發效率的開源技術