云原生可观测性在多租户环境中的实现方式有哪些

在多租户环境中实现云原生可观测性主要涉及到资源隔离、数据隔离和访问控制等方面。以下是一些常见的实现方式:
1. 资源隔离
CPU资源隔离:
例如在PolarDB MySQL版中,可以通过创建不同的资源配置信息来限制租户的CPU使用量。如创建资源配置`r1`,设置`min_cpu 0 max_cpu 1`,然后在创建租户`tenant_1`时绑定该资源配置,这样`tenant_1`的CPU资源限制`min_cpu`为0(不保证最小限额),最大额度为1 CPU。
内存资源隔离:
类似CPU资源隔离,也可以通过资源配置来限制租户的内存使用量,防止某个租户过度占用内存资源影响其他租户。
2. 数据隔离
存储隔离:
在Kubernetes中,为防止`PV`(持久卷)被跨租户访问,应指定其`reclaimPolicy`为`Delete`。并且应禁止使用例如`hostPath`这样的`volume`,以避免节点的本地存储被滥用。
网络隔离:
Kubernetes提供了`NetworkPolicy`,支持按`Namespace`级别的网络隔离。需要注意的是,使用`NetworkPolicy`需要特定的网络解决方案,如果不启用,即使配置了`NetworkPolicy`也无济于事,生产环境中可以`Calico`配合`NetworkPolicy`实现业务需要的安全组策略。
3. 访问控制
控制面隔离:
Kubernetes提供了三个机制来实现控制平面的隔离:`namespace`、`RBAC`(基于角色的访问控制)和`quota`(资源配额)。
`namespace`:可以将包含很多组件的系统分成不同的组,并且限定`RBAC`以及`quota`的作用范围。
`RBAC`:被用来限定用户或者负载对`API`的访问权限。通过设定合适的`RBAC`规则,可以实现对`API`资源的隔离访问。
`ResourceQuota`:可以被用来限制`namespace`下各类资源的使用上限,以防止某个`namespace`占据过多的集群资源而影响其他`namespace`下的应用。不过使用`ResourceQuota`有一个限制条件,即要求`namespace`下的每个容器都指定`resource request`和`limit`。
数据面隔离:
数据平面的隔离主要分为三个方面:容器运行时、存储和网络。
容器运行时隔离:由于容器和宿主机共享内核,应用程序或者主机系统上的漏洞可能被攻击者所利用,从而突破容器边界而攻击到主机或者其他容器。解决方法通常是将容器放到一个隔离的环境中运行,例如虚拟机或者是用户态`kernel`。前者以`Kata Containers`为代表,后者的代表则是`gVisor`。
4. 多租户解决方案
按`namespace`划分租户:
Kubernetes的控制平面隔离中的`RBAC`和`ResourceQuota`均以`namespace`为边界,因此以`namespace`来划分租户是比较自然的想法。在现实中,限定一个租户只能使用一个命名空间存在较大局限性。例如无法进一步以团队,或者以应用为粒度进行细分,造成一定的管理难度。因此Kubernetes官方提供了支持层级化`namespace`的`controller`。第三方开源项目例如`Capsule`和`kiosk`提供了更为丰富的多租户支持。
虚拟控制平面:
另一种多租户的实现方案是为每个租户提供一个独立的虚拟控制平面,以彻底隔离租户的资源。虚拟控制平面的实现方式通常是为每个租户运行一套独立的`apiserver`,同时利用`controller`将租户`apiserver`中的资源同步到原Kubernetes集群中。每个租户只能访问自己对应的`apiserver`,而原Kubernetes集群的`apiserver`则通常不对外访问。这类方案的代价是额外的`apiserver`的开销,但能够获得更为彻底的控制平面隔离。结合数据平面的隔离技术,虚拟控制平面可以实现更为彻底和安全的多租户方案。此类方案以`vcluster`项目为代表。
Lei
April 26, 2025
技术探讨