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)


分享到:


相關文章: