k8s多租户实现与优化
小军的求知笔记
小军的求知笔记
微信号
Golang_Porter
功能介绍
分享个人成长笔记,勇敢做自己。
多数情况下,Kubernetes用户为了满足多个团队和多个客户的需求会共享集群,这通常用术语多租户来描述。多租户节省成本并简化管理。虽然Kubernetes没有终端用户或租户的概念,但它提供了几个功能来帮助管理不同的租户需求。基于这些特性,Kubernetes社区出现了多租户项目。
在本文中,我们将讨论Kubernetes中的多租户问题。特别是,我们将彻底研究多租户的两种实现方式:集群共享和多集群—并为陷入这方面困惑的企业提供建议。
控制面隔离
Kubernetes提供了三种实现控制平面隔离的机制,即命名空间、RBAC和配额。
几乎每个Kubernetes用户都熟知的概念,命名空间用于提供一个单独的名称空间。不同命名空间中的对象名称可以相同。此外,RBAC和配额的作用域也仅限于名称空间。
基于角色的访问控制(RBAC)通常用于在Kubernetes控制平面对用户和工作负载(服务帐户)强制授权。通过设置适当的RBAC规则,可以实现对API资源的隔离访问。
ResourceQuota可用于对命名空间的资源使用设置上限。这确保了租户不能垄断集群的资源或超过其控制平面,从而最小化“干扰其他命名空间资源”问题。使用ResourceQuota的一个限制是,当向命名空间应用配额时,Kubernetes还要求用户为该名命名间中的每个容器指定资源请求和限制。
这三种机制虽然在一定程度上可以实现控制平面隔离,但不能一劳永逸地解决问题。集群范围内的资源(如CRD)不能用这些机制很好地隔离。
数据面隔离
数据平面隔离通常涉及三个方面:容器运行时、存储和网络。
由于内核由容器和主机共享,因此攻击者可以利用应用程序和系统层中未打补丁的漏洞进行容器突破和远程代码执行,从而允许访问主机资源或其他容器。这可以通过在隔离的环境中运行容器来解决,例如vm(Kata容器)和用户模式内核(例如,gVisor)。
存储隔离应该确保卷不被跨租户访问。因为StorageClass是集群范围的资源,所以reclaimPolicy应该指定为Delete,以防止跨租户访问pv。此外,还应禁止使用hostPath等卷,以避免滥用节点的本地存储。
网络隔离通常通过设置NetworkPolicy来实现。默认情况下,所有pod都可以相互通信。使用NetworkPolicy可以限制pods之间的网络通信,减少意外的网络访问。高级网络隔离可以通过服务网格实现。
实现多租户
上面提到的控制面隔离和数据面隔离只是Kubernetes提供的单独功能。在将这些特性作为集成的多租户解决方案交付之前,还有很长的路要走。幸运的是,Kubernetes社区有许多专门解决多租户问题的开源项目。这些项目分为两类,一类通过命名空间划分租户,另一类为租户提供虚拟控制平面。
每个租户一个命名空间
在Kubernetes的控制面隔离中,RBAC和ResourceQuota都受到命名空间的限制。虽然按命名空间划分租户似乎很容易,但规定每个租户一个命名空间有很大的局限性。例如,单个租户或应用团队再划分,这种细粒度级别几乎无法完成,这增加了管理难度。有鉴于此,Kubernetes正式提供了一种支持分层命名空间的控制器。像Capsule和kiosk这样的第三方开源项目也提供了更复杂的多租户支持。
虚拟控制面
另一种选择是为每个租户提供单独的虚拟控制面,以便完全隔离租户的资源。虚拟控制面通常是通过为每个租户运行一组单独的apiserver来实现的,同时使用控制器将资源从租户apiserver同步到原有的Kubernetes集群。每个租户只能访问其相应的apiserver,而原始Kubernetes集群的apiserver通常不能从外部访问。
虚拟控制面的完全隔离通常需要较高的资源消耗。但与数据面隔离技术结合使用,它是一个更彻底和安全的多租户解决方案。其中一个例子是vcluster项目。
两种方案的对比
是使用“每个租户一个命名空间”还是使用虚拟控制面实现多租户,基本取决于应用场景。一般来说,通过命名空间划分租户减少了隔离性和灵活性,同时适用于轻量级场景,例如在多个团队之间共享集群。而在多个客户的场景中,虚拟控制平面通常可以提供更安全的隔离。
多集群解决方案
从上面的讨论可以看出,共享Kubernetes集群不是一件容易的事情;多租户不是Kubernetes的内置特性,只能在其他项目的支持下在控制和数据平面上的租户隔离中实现。这为整个解决方案带来了相当大的学习和适应成本。因此,我们看到越来越多的用户转而采用多集群解决方案。
与集群共享解决方案相比,多集群解决方案有利有弊,优点是隔离程度高、边界清晰,缺点是开销和运维成本高。由于每个集群都需要独立的控制面和工作节点,Kubernetes集群通常构建在虚拟机上,以提高物理集群的利用率。然而,传统的虚拟化产品往往又大又重,因为它们需要处理广泛的场景。这使得它们过于昂贵,无法成为支持虚拟化Kubernetes集群的最佳选择。
基于此,我们认为一个理想的虚拟化Kubernetes集群的虚拟化平台应该具备以下特征:
轻量化:不是解决所有的场景(例如,VDI),它应该专注于服务器虚拟化,同时消除所有不必要的功能和开销。
高效:广泛使用virtio等半虚拟化I/O技术来提高效率。
安全:最小化宿主机的攻击面。
kubernetes-native:虚拟化平台本身应该是一个Kubernetes集群,这样可以减少学习和运维成本。
而这些特性正是Virtink虚拟化引擎所具有的。Virtink是SmartX为Kubernetes发布的开源轻量级虚拟化插件。基于Cloud Hypervisor项目,Virtink能够在Kubernetes上编排轻量级vm。
Virtink尽可能地使用virtio来提高I/O效率。在安全性方面,用Rust语言编写的Cloud Hypervisor项目的内存管理更加安全。此外,不支持遗留的和不必要的硬件,以减少虚拟机暴露的攻击面,提高主机安全性。
总的来说,Virtink更加轻量级、高效和安全,为Kubernetes中的Kubernetes提供了更理想的虚拟化支持,同时降低了虚拟化层的开销。
此外,为了满足在Virtink上创建、操作和维护虚拟化Kubernetes集群的需求,社区开发了knest命令行工具,帮助用户一键式创建和操作集群。特别是,要在Virtink集群上创建一个虚拟化的Kubernetes集群,用户只需运行knest create 。还支持一键扩展。
总结
尽管Kubernetes没有内置的多租户,但它提供了一些细粒度的特性支持。多租户集群共享可以通过这些特性和一些第三方工具实现,但这需要额外的学习和运维成本。从这个角度来看,多集群解决方案更合适,已经被很多用户采用。但是,用户可能会遇到传统虚拟化平台效率低、成本高等问题。
基于高效和安全的Cloud Hypervisor项目,开源虚拟化引擎Virtink在Kubernetes上编排轻量级vm方面进行了优化。还提供了一个knest命令行工具,允许用户通过简单的单击就可以创建和管理集群,降低了多个集群的整体运维成本。
参考文献
[virink] https://www.smartx.com/blog/2022/07/virtink-for-k8s-en/
[vcluster] https://github.com/loft-sh/vcluster
[capsule] https://github.com/clastix/capsule
[kiosk] https://github.com/loft-sh/kiosk
预览时标签不可点
微信扫一扫
关注该公众号
继续滑动看下一个
轻触阅读原文
小军的求知笔记
向上滑动看下一个
知道了
微信扫一扫
使用小程序
取消
允许
取消
允许
:
,
。
视频
小程序
赞
,轻点两下取消赞
在看
,轻点两下取消在看
分享
留言