企业主要使用两种模型与多个租户共享Kubernetes集群:基于命名空间的多租户和基于集群的多租户。
第一种常见的多租户模型基于命名空间隔离,其中单个租户(比如开发微服务的团队)只能使用集群中的一个或某几个命名空间。虽然这种模型适用于某些团队,但也存在缺陷。
首先,限制团队成员只能访问命名空间中的资源意味着他们无法管理集群中的全局对象,比如自定义资源定义(CRD)。对于直接或间接处理CRD(比如在Kubeflow或Argo Pipelines上构建)的团队来说,这是大问题。
其次,一个更大的长期维护问题是需要不断向命名空间隔离规则添加例外。比如说,使用网络策略锁定单个命名空间时,管理员可能发现一些团队最终需要运行多个相互联系的微服务。集群管理员需要为这些情况添加异常,跟踪它们,并管理所有这些特殊情况。而且,随着时间的推移和更多的团队开始使用Kubernetes,复杂性也将随之增大。
另一种标准的多租户模型是在集群层面使用隔离,问题来得更大。在这种情况下,每个团队都有自己的集群,甚至可能有多个集群(开发、测试、UAT和登台等)。
使用集群隔离的直接问题是最终需要管理许多集群,这个问题可能很棘手。所有这些集群都需要昂贵的云计算资源,即使是使用它们的低峰时段,比如在晚上或周末。
正如Holly Cummins在KubeCon 2021主题演讲中指出,这种集群激增给环境带来的影响很危险。
就在不久前,集群管理员还只好在这两种令人不满意的模型之间做出选择,选择更适合其用例和预算的模型。然而,Kubernetes中有一个比较新的概念:虚拟集群,它更适合许多用例。
虚拟集群简介
虚拟集群是一个共享的Kubernetes集群,在租户看来是专用集群。2020年,Loft Labs团队发布了vcluster,这是虚拟Kubernetes集群的开源实现方法。
有了vcluster,工程师可以在共享的Kubernetes集群上配置虚拟集群。这些虚拟集群在底层集群的常规命名空间内运行。因此,管理员可以启动虚拟集群并将它们分发给租户。
如果组织已经在使用基于命名空间的多租户,但用户被限制在单个命名空间中,租户用户还可以在命名空间内自行启动这些虚拟集群。
这结合了上述两种多租户方法的优点:租户被限制在单个命名空间中,不需要例外,因为他们在虚拟集群内部拥有完全控制权,但虚拟集群外面的访问非常有限。
与集群管理员一样,用户在虚拟集群内拥有完全控制权。这让他们可以在虚拟集群内执行任何操作,而不影响底层共享主机集群上的其他租户。
在幕后,vcluster通过在主机集群上的命名空间内的pod中运行Kubernetes API服务器及其他一些组件来实现这一点。用户将请求发送到命名空间内的虚拟集群API服务器,而不是底层集群的API服务器。虚拟集群的集群状态也完全独立于底层集群。虚拟集群内创建的Deployment或Ingress等资源仅存在于虚拟集群的数据存储中,并不持久保存在底层集群的etcd中。
与命名空间隔离模型和集群隔离模型相比,这种架构有显著的优势:
1. 由于用户是虚拟集群中的管理员,他们可以管理整个集群的对象(比如CRD),从而克服了命名空间隔离的一大限制。
2. 由于用户与各自的API服务器进行联系,其流量比平常的共享集群更孤立。这还提供了联合机制,有助于在高流量集群中扩展API请求。
3. 虚拟集群配置和拆卸起来很快,因此用户可以得益于使用真正临时的环境,并可能在需要时启动许多临时环境。
如何使用虚拟集群?
虚拟集群有很多用例,下面介绍大多数vcluster用户采用的几个用例。
•开发环境
配置和管理开发环境是目前vcluster最流行的用例。如果开发人员编写Kubernetes集群中运行的服务,开发过程中需要在某个地方运行应用程序。虽然可以使用Docker Compose等工具为开发环境编排容器,但针对Kubernetes集群编写代码的开发人员将获得更接近其服务在生产环境中运行方式的体验。
本地开发的另一个选择是使用Minikube或Docker Desktop之类的工具来配置Kubernetes集群,但有几个缺点。
开发人员必须拥有并维护这本地集群架构,这并非易事,且耗费时间。
此外,那些本地集群可能需要大量的计算能力,这在本地开发机器上很难做到。我们都知道笔记本电脑在开发过程中会变得多热,再添加Kubernetes可能不是好主意。
在共享开发集群中将虚拟集群作为开发环境来运行可以解决这些问题。而且,如上所述,vcluster可以快速配置和删除。
管理员可以使用单个kubetctl命令来删除底层主机命名空间或运行命令行界面工具提供的vcluster delete命令,从而删除vcluster。开发工作流程中基础设施和工具的速度至关重要,因为缩短开发人员的周期时间可以提高其生产力和幸福感。
•CI/CD 管道
持续集成/持续开发(CI/CD)是虚拟集群的另一大用例。管道通常配置受测系统(SUT),从而运行测试套件。团队常常希望那些是新系统,没有可能干扰测试的包袱。
如果团队运行有许多测试的长管道,可能会在测试运行中多次配置和销毁SUT。如果用户花费大量时间配置集群,可能已注意到启动Kubernetes集群常常很耗时。即使在最先进的公共云中,也可能需要20多分钟。
使用vcluster可以快速轻松地配置虚拟集群。运行vcluster create命令来配置新的虚拟集群时,幕后只需要运行Helm图表,并安装几个pod。这番操作通常只需几秒钟。任何运行长时间测试套件的人都知道,缩短流程的时间对QA团队和工程师收到反馈的速度都会带来显著提升。
此外,企业可以利用vcluster的速度来改进配置大量集群的任何其他流程,比如为研讨会或客户培训创建环境。
•测试不同的Kubernetes版本
如前所述,vcluster在底层主机命名空间中运行Kubernetes API服务器。它默认使用K3s(轻量级Kubernetes)API服务器,但用户也可以使用k0s、Amazon Elastic Kubernetes Service 或常规的上游Kubernetes API服务器。
配置vcluster 时,用户可以指定运行它的Kubernetes版本,这带来了诸多可能性。用户可以:
•在虚拟集群中运行较新的Kubernetes版本,以查看应用程序面对较新的API服务器将如何运行。
•在开发或端到端测试期间,使用不同版本的Kubernetes运行多个虚拟集群,以便在一组不同的Kubernetes发行版和版本中测试operator。
补充
Kubernetes多租户可能没有完美的解决方案,但虚拟集群解决了当前租户模型的许多问题。如果用户希望使用共享集群,但又希望为用户提供管理集群的灵活性,vcluster的速度和易用性使其成为许多场景的理想选择。除了本文描述的用例外,vcluster还支持许多用例。
想了解更多信息,请访问vcluster.com,或者如果想深入了解代码,可从GitHub代码库(https://github.com/loft-sh/vcluster)下载。
原文Virtual Kubernetes clusters: A new model for multitenancy,作者:Lukas Gentele