作者:任静思,火山引擎云原生工程师
本文整理自火山引擎开发者社区 Meetup 第八期演讲,主要介绍了字节跳动轻量级 Kubernetes 多租户方案 KubeZoo 的适用场景和实现原理。
Kubernetes多租户模型
其次,Cluster 或 Control plane 的隔离方案引入了过多的额外开销,比如每个租户需要建立独立的控制面组件,这样就降低了资源利用率;同时大量租户集群的建立,也会带来运维方面的负担。
另外,无论是公有云还是私有云,都存在大量小租户并存的场景。在这些场景下,每个租户的资源需求量比较小,同时租户又希望在创建集群之后,能够立即使用集群。
轻量级多租户方案Kubezoo
针对这种海量小租户并存的场景,我们就提出了一种轻量级的多租户方案——KubeZoo。
KubeZoo 作为一个网关服务,部署在 API Server 的前端。它会抓取所有来自租户的 API 请求,然后注入租户的相关信息,最后把请求转发给 API Server,同时也会处理 API Server 的响应,把响应再返回给租户。
KubeZoo 的核心功能是对租户的请求进行协议转换,使得每个租户看到的都是独占的 Kubernetes 集群。对于后端集群来说,多个租户实际上是利用了 Namespace 的原生隔离性机制而共享了同一个集群的资源。
通过上面的架构图可以看出,KubeZoo 作为一种多租户的方案,有一些独特的特性。
同时它又能够提供比较完整的 Kubernetes API,租户既能使用 Namespace 级别的资源,又能使用集群级别的资源。每个租户的体验都可以认为是自己独占了完整的 Kubernetes 集群。
其次,KubeZoo 是高效率的:每次添加一个新的租户之后,不必再为该租户初始化新的集群控制面,只需要在 KubeZoo 这个网关层面建立一个 Tenant 对象即可。这样就能达到租户集群的秒级创建和即刻使用的效果。
最后,KubeZoo 是一种非常轻量级的多租户方案。因为所有的租户共享同一个后端集群的控制面,所以它拥有非常高的资源利用率,当然运营成本也非常低。
资源利用率:Namespace 隔离和 KubeZoo 都是共享后端集群,二者的资源利用率都是最高的;Virtual Cluster 方案需要为每个租户搭建独立的控制面,资源利用率中等;独立集群方案的资源利用率是最低的。
运维成本:Namespace 隔离和 KubeZoo 方案都只需要维护一个后端集群,所以运维成本最低;Virtual Cluster 方案通过 controller 维护租户控制面,运维成本较低;独立集群方案运维成本最高。
集群创建时间:Namespace 隔离和 KubeZoo 的租户集群创建都只需要一次 API 调用,集群创建时间最短;Virtual Cluster 方案需要启动租户控制面组件,集群创建时间中等;独立集群方案集群创建时间最长。
API 兼容性:Namespace 隔离方案下,租户无法任意创建和使用集群级别的资源,API 兼容性是最低的;KubeZoo 和 Virtual Cluster 方案中,除了 Node, Daemonset 等节点相关的资源外,租户可以使用任意的 Namespace 级别或集群级别的资源,API 兼容性中等;独立集群方案 API 兼容性最高。
隔离性:Namespace 方案下的租户隔离性最低;KubeZoo 和 Virtual Cluster 方案中,租户请求会经过网关或独立的 Apiserver,隔离性中等;独立集群方案的隔离性最高。
以上各维度综合对比来看,KubeZoo 能在租户体验、集群的资源效率和运维效率之间达到平衡,尤其是在大量小租户共享资源池的情况下,具有显著的优势。
KubeZoo关键技术细节
租户管理
KubeZoo 本身可以理解成一种特殊的 API Server,也需要自己的元数据存储服务,比如典型的我们会使用 Etcd 来存储租户相关的信息。对租户对象的管理方式和 Kubernetes 管理原生资源对象的方式是一致的。
当管理员创建一个租户对象之后,该 TenantController 会为租户签发一个证书,证书里携带了该租户的 ID,同时也会为该租户生成对应的 Kubeconfig,写入这个 Tenant 对象的 annotation 字段中。
租户请求转换
KubeZoo 本身会同时处理两种请求:一种是来自管理员的请求,另一种是来自租户的请求。所以当一个请求到来之后,KubeZoo 会首先判断该请求是否为租户相关对象:API 对象转换
Kubernetes 的资源可以分为两类:Namespace 级别和 Cluster 级别。这两种资源对象的协议转换方式也是有所区别的:
Namespace 级别对象:需要对资源对象的 Namespace 做转换,保证不同租户的资源在后端集群中映射到不同的 Namespace, 巧妙利用了 Kubernetes 原生的 Namespace 隔离机制,实现不同租户的 API 视图隔离。
Cluster 级别对象:需要对资源的对象的 name 做转换,保证不同租户的 Cluster 级别对象在后端集群没有命名冲突。
由于所有的租户请求都会经过 KubeZoo 的统一网关,所以要避免某个租户发送的大量请求把网关或者集群资源占满,进而影响其他租户请求的发送。这种情况下我们沿用了 API Server 的 priority and fairness 机制,具体来说会为每一个租户创建 Flow Schema(用来匹配租户的流量),另一方面会为每一个 Flow Schema 对象创建 Priority Level(用来代表租户的权重)。最后通过配置流量策略来保证不同租户之间请求的公平性。
在网络隔离方面可以细分为两个场景:
第一种场景是所有的租户都来自同一个公司的内部。在这种场景下信任度比较高,安全和审计也比较完善。这时后端集群通常可以采用一种扁平的网络,即不同租户的 Pod 之间的网络是可以互通的。
总结
KubeZoo 是一种基于协议转换的 Kubernetes 的多租户网关方案。与现有的多租户方案对比,它有三方面的特点:
轻量级:主要体现在跟 Cluster as a Service 和 Control planes as a Service 对比,它的资源率利用率是非常高的,因为它只需要一个网关,无需为每一个租户起一个独立的控制面集群。相对应的,因为控制面集群的数量只有一个,其运维成本非常低。
高效率:主要体现在租户的集群创建方面。租户的集群创建相当于创建一个 Tenant 对象,一次 API 调用,所以租户的集群其实是秒级拉起,拉起之后可即刻使用。
租户隔离:KubeZoo 在租户隔离性方面也做得非常优秀。因为每个租户可以拥有独立且完整的 Kubernetes 集群视图,它既可以使用这个 namespace scope 的资源,又可以使用集群级别的资源。
KubeZoo 方案有几种典型的适用场景:
第一种是对集群的资源利用率和租户体验有极致要求。
第二种是海量的小租户共享一个大的资源池,每一个租户要求的资源量不多,但租户的总体数量比较多,KubeZoo 可以使其达到非常高效的共享资源池的效果。
Q&A
Q:除了 DS 还有一些其他的限制吗?Q:不同租户创建的 CRD 能共用吗?
A:关于 CRD 可以介绍一下细节。我们在方案设计上是把 CRD 分为两类:
另一种是在公有云场景下提供系统级别的 CRD,在后端集群上会由同一个 Controller 进行处理。系统级别的 CRD 可以配置为一种特殊的策略,保证它对于某一个或某一些租户是开放的,这些租户可以创建系统级别的 CRD 的对象。
Kubernetes CKA实战培训,线下三天(北京,上海,深圳)
扫码加我微信,进群和大佬们零距离