在这篇文章中,CNCF 官方博客报道了阿里云 Kubernetes 团队如何利用一组名为“Virtual Cluster”的插件对社区中的租户设计进行扩展,并分享了他们如何以此来基于上游 Kubernetes 代码构建“强多租户“能力。目前,阿里云 Kubernetes 团队正在开源这些 K8s 插件,并在即将到来的 KuberCon 大会上将其贡献给 Kubernetes 社区。
内容简介
在阿里云,他们的 Kubernetes 团队正利用一套互联网级规模的集群向作为最终用户(阿里巴巴的众多业务部门)提供服务。在这种情况下,每个部门(最终用户),实际上都成为该 K8s 集群的“租户”,而巨大的需求量也使 K8s 原本的弱租户机制难以应对。
所以,阿里云的 Kubernetes 团队给自己提出了一项挑战:要试图在不修改任何 Kubernetes 代码的前提下构建“Virtual Cluster”多租户试图,并且缓解 Kubernetes APIServer 与资源模型的工作压力。利用这套架构,每个租户都将分配一个专用的 K8s 控制平面(kube-apiserver + kube-controller-manager)外加几个“Virtual Node”(纯节点 API 对象,但没有相应的 kubelet)。通过这种方式, Kubernetes 集群管理员不仅不需要担心命名或者节点冲突,同时也能保证来自不同租户的工作负载仍然运行在同一个底层“Super Cluster”当中,从而实现理想的资源利用率。这种设计在阿里云 Kubernetes 团队几个月前向社区提交的《Virtual Cluster 提案(virtual cluster proposal)》中已有详尽介绍,并收到了大量反馈。
需要指出的是,虽然该设计中引入的“租户 Master 节点(tenant master)”是一个新概念,但虚拟集群(Virtual Cluster)本身实际上是对 K8s 社区中现有的、基于命名空间(Namespace) 机制的多租户设计的一种架构扩展,在下文中我们将称后者为“命名空间组(namespace group)设计”。 此外,虚拟集群的完全实现,同样依赖于命名空间组下层的资源隔离机制(比如网络和资源隔离能力),我们期待着这一问题能够在 Kubernetes WG-multitenancy 中得到进一步解决。
如果大家希望了解关于 Virtual Cluster 设计的更多细节信息,请参阅之前的《Virtual Cluster 提案》。而在本文,我们将重点关注虚拟集群背后的更高层次设计理念,并详尽说明如何利用“租户集群”视图来对命名空间组进行扩展,以及为何这一扩展将对 Kubernetes 多租户场景产生重要价值。
背景介绍
本节将简要回顾命名空间组多租户提案的基本架构。
下图摘自 Kubernetes 社区早期的《K8s 多租户兴趣小组的工作介绍(K8s Multi-tenancy WG Deep Dive)》,如图一所示,其解释了如何利用命名空间(Namespace)这一概念来组织 K8s 租户的资源。
图一:命名空间组多租户架构
在上述基于命名空间组的多租设计中,所有租户共享相同的 K8s 访问入口,即 K8s apiserver,来使用租户的资源。他们的账户、被分配的命名空间以及资源隔离策略,都在一个称作 租户 CRD 的对象中进行指定,而各 CRD 对象则由租户管理员负责管理。租户用户视图被限制在各个租户持有的命名空间之内。租户资源隔离策略的基本定义为,禁止租户之间进行直接通信,并保护租户 Pod 免受攻击影响。这些策略通过 Kubernetes 的原生资源隔离机制实现,包括 RBAC、Pod 安全策略、网络策略、准入控制以及沙箱运行时等。我们可以配置多个安全配置文件以实现不同级别的隔离要求。此外,资源配额、退费以及计费等都在租户层级上实现。
虚拟集群如何扩展视图层
从概念上讲,虚拟集群在命名空间组之上提供了一个重要的视图层扩展。大家可以参考[virtual cluster]中的技术细节说明。在这个设计中,租户管理员仍然需要使用命名空间组中的同一租户 CRD 来指定租户资源供应方(即真实集群)的账户、命名空间以及资源隔离策略。
图二:由虚拟集群提供的视图层扩展
如图二所示,由于有了新的虚拟集群视图层,现在租户用户可以拥有不同的访问点与租户资源视图。租户不再需要直接访问真实集群以查看租户的命名空间,而是同专属的租户 Master 节点(tenant master)进行交互以使用租户的资源,同时持有专属的、完整的 K8s 视图。所有租户请求皆由 sync-manager(Syncer) 自动同步至真实集群,并由后者根据租户 CRD 中设置对应的资源隔离策略,根据租户用户的行为创建相应的自定义资源。所以说,虚拟集群的核心设计,在于它主要将来自分租户看到的视图从命名空间变更为真实的、租户专属的 APIserver。而从真实集群的角度来看,租户控制器在响应租户 CRD 时触发的也是完全相同的工作流程。
虚拟集群视图扩展的优势
在租户用户的现有命名空间视图之上使用虚拟集群视图,能够带来以下助益:
为租户用户提供灵活便捷的租户资源管理机制。例如,嵌套命名空间层级(如图三(a)所示)能够轻松解决命名冲突、命名空间可见性、以及命名空间组解决方案[Tenant Concept]中的子分区租户资源等问题。通常情况下,我们很难在不修改 K8s 代码的前提下支持嵌套命名空间。而利用虚拟集群视图,我们可以在租户集群中创建命名空间,同时在真实集群中建立对应的命名空间组,从而提供与嵌套命名空间一致的用户体验。
如上图(b)所示,租户用户可以在租户主节点中创建自助命名空间,而无需担心与其他租户的命名产生冲突。在将租户命名空间添加到真实集群的命名空间组时,sync-manager 将负责解决这类冲突。租户 A 的用户永远无法查看租户 B 用户的命名空间,因为他们访问的实际上是不同的主节点。这种方式还能够为租户轻松提供不同的用户定制策略,且此类策略仅在租户集群中生效。
带来更强的租户隔离性与安全性。这是因为新机制避免了因多租户用户共享同一 K8s 主节点而导致的某些问题。例如 DoS 攻击、各租户间 API 访问速率控制、以及租户控制器隔离等等。
允许租户用户在租户主节点当中创建集群范围对象,且不会影响到其他租户。例如,租户用户现在可以在租户主机中自由创建 CRD、ClusterRole/ClusterRoleBinding、PersistentVolume、ResourceQuota、ServiceAccount 以及 NetworkPolicy,而不必担心与其他租户发生冲突。
减轻了真实集群主节点(Super Master)的可扩展性压力。首先,RBAC 规则、策略、以及真实集群所管理的用户账户,都可以被转移至租户主节点,进而实现各自独立扩展。第二,租户控制器与操作器将访问多个租户主节点,而非单一真实集群,这同样使得独立扩展成为可能。
降低为租户用户创建用户的难度。以往,如果租户用户希望将一部分租户资源公开给其他用户(例如,团队负责人希望添加新成员并为其分配对应团队资源),那么租户管理员必须重新创建所有用户。一旦租户管理员面对的是大型组织当中多达数百个类似团队的同类要求,那么租户用户的创建工作可能成为沉重的负担。虚拟集群将这种负担从租户管理员处完全转移至租户用户处。
局限性
由于虚拟集群的诉求在于扩展多租户视图选项,同时防止因共享服务器而引发的相关问题,因此其也继承了命名空间组解决方案在租户 Kubernetes 节点组件感知方面存在的相同局限和挑战。目前需要增强的节点组件包括但不限于:
Kubelet 与 CNI-plugin。二者需要实现租户感知能力,从而支持与 VPC 类似的强大网络隔离能力。
例如,如果某个 pod 在另一 VPC 中与节点隔离开来,那么该如何实现 ReadinessProbe 和 LivenessProve?目前,我们已经就这个问题与 SIG-Node 开展上游合作。
Kube-proxy/Kube-dns。二者需要实现租户感知能力,从而实现租户服务的集群-IP 类型。
工具。例如,监控工具应具备租户感知能力,从而避免泄露租户信息。性能调优工具应具备租户感知能力,以避免在不同租户之间产生意外的性能干扰。
当然,虚拟集群还需要额外资源以允许每个租户运行自己的租户主节点。目前,某些用例还无法支持这种需求。
总结
虚拟集群利用一种用户友好 的”集群视图“对命名空间组进行了扩展,并利用 K8s 自身的底层资源隔离机制以及社区中的现有租户 CRD 与控制器,希望借此有针对性地提升多租户群体的使用体验。
总体来讲,我们认为虚拟集群与基于命名空间的多租户机制相结合,能够为生产集群中的各类 Kubernetes 多租户用例提供全面的解决方案。我们也在积极努力,希望将这款插件贡献给上游社区。
原文作者:
郭飞,阿里云容器平台资深技术专家。
张磊,阿里云容器平台高级技术专家
原文链接:
评论