02.28 多租戶Kubernetes

假設

  1. 租戶間互不信任,對方是惡意的,會造成攻擊或資源搶佔
  2. 內部用戶和外部用戶一樣有威脅 (即使是內部用戶也更偏好 hard multi-tenancy model)

與運營多個單租戶集群相比,運營多租戶集群有幾個優點:

  • 減少管理開銷
  • 減少資源碎片
  • 新租戶無需等待集群創建

關於什麼是租戶,以及為什麼要多租戶,可以參考這篇,和這篇

解決辦法

Kubernetes Multitenancy WG Deep Dive KubeCon EU 2019 (last updated 5/22/2019) 描述了4種解決方案,並做了對比:

多租戶Kubernetes

image

多租戶Kubernetes

image

這篇文章將介紹其中的 B 和C 方案

使用 namespace 隔離

一種常見的設計方案時使用 namespace隔離, 讓 namespace 成為多租戶隔離的邊界。

這種設計裡面的推薦做法是:

  • Host OS 必須是安全的,應該是 reduced operating system, minimal distribution,比如 CoreOS Container Linux/Container Optimized OS/Intel Clear Linux
  • Container Runtime: 隔離性強,比如 Katacontainers
  • Network: 支持 network policy,在 namespace 之間做網絡隔離
  • DNS: 每個租戶都有自己的 dns 應用
  • Authorization: RBAC 解決
  • Master/System Node 上不調度
  • Encryption of etcd at rest
  • Node authorizer and admission plugin
  • Restrict access to host/node resources via PodSecurityPolicy:需要拒絕以下使用場景hostPath for volumesnodePort via hostPortshostIPChostPIDhostNetworkprivilegedallowedHostPaths -> none
  • 資源使用都需要設置 Limit/Request,即使用 Quota, 和 LimitRange
  • 環境變量問題:kubernetes 未fixkubernetes/community/pull/176, kubernetes/community/pull/1249
  • 考慮 監控日誌的多租戶

為了支持這種方案,社區設計了一套 CRD

這種通過 Namespace 隔離的存在問題,

namespace 是 kubernetes 的概念,並非所有資源在 kubernetes 都能通過 namespace 隔離,比如:

  • 不同的用戶會共享 kube-proxy (儘管 network policy 能夠給網絡訪問增加一些邊界), api-server, etcd, scheduler, controller ...
  • 不同到用戶可能會共享 node, 而對於不同到 cri 實現, 隔離能力不同。例如 PodSecurityPolicy 和 NetworkPolicy,以及更高級別隔離性的 cri 實現(比如katacontainers)正在發展以增強這種隔離能力。但是即使 cri 有等價於 vm 的隔離能力,當用戶需要使用 node 的一些資源時,這種隔離性時常被打破。

虛擬 kubernetes

這張圖來自 https://blog.jessfraz.com/post/hard-multi-tenancy-in-kubernetes/

多租戶Kubernetes

image

如果我們使用嵌套都 kubernetes apiserver(以及其他控制組件),那麼我們要關心都事情就變得簡單了:kubernetes 相關的核心組建,以及資源視圖已經做了隔離,那麼我們需要做的事情就是:讓不同的虛擬kubernetes 共享同一個 ring 0 kubernetes 資源池. 如果我們能做到 虛擬kubernetes 綁定到其中幾個 kubelet 就可以做到按照上圖所示的按節點的隔離。

然後這種做法似乎和新建多個 kubernetes 集群並無大的區別。記得嗎,當我們考慮在同一個kubernetes 上追求多租戶,我們首先考慮的在保證安全的前提下,是否能提高資源利用率。我們可能追求的如下圖所示方案:

多租戶Kubernetes

image

這種方案的帶來的問題是 node 視圖被混淆了。當然我們有幾種做法,比如在 虛擬kubernetes api 層做一些修改,以過濾掉不適合 用戶空間的信息,或者使用 一套有趣的方案 virtural node, 其中一種開源等實現為:virtual-kubelet, virtual-node 成為 node 的上一層封裝,對於 虛擬kubernetes來講,所有的節點可以都是 virtual-node,而 virtual-node 再通過其他方式,比如調用 ring0 kubernetes API, 完成 pod的創建,以及同步 pod 的狀態信息。

多租戶Kubernetes

image

多租戶Kubernetes

image

在這篇提案中描述了類似設計.

更為具體等工作流程為

  • 某租戶創建 pod => 虛擬kubernetes
  • sync manager( 或virtual-node ) 將 虛擬kubernetes 中的 pod 拷貝到 super master,即上文提的 ring0 kubernetes
  • Unified scheduler 進行調度
  • kubelet 創建 pod
  • sync manager ( 或virtual-node )創建出node和同步 pod 狀態

這種方案的好處是:

  • kubernetes 層無需修改
  • 靈活方便,能解決多種問題比如:名字衝突,一個租戶多個 namespace 等 (在就等方案中只能用 Hierarchical Namespace來解決)
  • 隔離更強: api等組件獨立

這種方案需要解決的問題:

  • Kubelet and CNI-plugin:需要 tenant-aware,支持隔離
  • Kube-proxy/Kube-dns: 需要 tenant-aware to make cluster-IP type of tenant services work
  • Tools:比如 監控日誌等組件需要 tenant-aware

甚至:

  • super master 不一定是一個,可以是多個,這樣 tenent master 和 super master 變成一個多對多的關係,這樣就降低了 super master 無法無限擴展的問題
  • virtual node 同步,創建 pod 狀態,不一定需要是通過 super master 創建,可以映射到其他資源,比如 virtual-kubelet 支持的 AWS Fargate, Azure Container Instance 等等

當然 上述的兩種場景在解決 網絡,監控等問題時會變得更為複雜的問題。

參考

  • Kubernetes - Multi-Tenancy Design Scratch Space
  • 如何解決 Kubernetes 的多租戶難題
  • Kubernetes 多租戶集群實踐
  • Hard Multi-Tenancy in Kubernetes
  • kubernetes-sigs/multi-tenancy/
  • Virtual Cluster – Extending Namespace Based Multi-tenancy with a Cluster View
  • Kubernetes Multitenancy WG Deep Dive KubeCon EU 2019 (last updated 5/22/2019)


分享到:


相關文章: