多租户指标监控的核心挑战在于:多个团队或客户共享同一套监控基础设施,却需要互不干扰地访问各自的指标数据。如果权限与数据隔离设计不当,轻则数据泄露,重则影响整个监控系统的稳定性。本文从权限模型与数据隔离两个维度,基于 OWASP、Kubernetes RBAC 和 NIST 的权威资料,逐步分析隔离方案的设计要点、常见误区与失败条件。
权限隔离:从认证到授权的边界
OWASP 授权速查表明确指出,授权是“验证请求的动作或服务是否被特定实体批准的过程”,它与认证截然不同。在多租户指标监控中,认证确认“你是谁”,授权决定“你能看哪些指标”。一个常见的错误是:用户登录成功后,便默认其可以访问所有监控数据。正确的做法是,在认证之后,必须通过独立的授权层,基于租户身份和角色,对每个 API 请求进行细粒度的权限校验。
例如,Prometheus 的联邦集群或 Thanos 的查询组件,通常需要在前端接入一个授权代理(如 OAuth2 Proxy 或自定义中间件),将租户信息注入到查询上下文中,并限制其只能访问特定标签(如 tenant=”acme”)的数据。这一步不能省略,因为监控系统本身的 API 往往不具备多租户意识。
RBAC:权限模型的标准答案
NIST 的 RBAC 项目资料显示,基于角色的访问控制(RBAC)自 1992 年由 Ferraiolo 和 Kuhn 正式提出以来,已成为高级访问控制的主流模型,其核心价值在于降低安全管理成本。在多租户指标监控中,RBAC 模型同样适用:为每个租户定义角色(如 “tenant-admin”、“tenant-viewer”),再将角色绑定到用户或服务账号。
Kubernetes 的 RBAC 实现提供了具体的操作范式。其 API 声明了四种对象:Role、ClusterRole、RoleBinding 和 ClusterRoleBinding。Role 总是设置在特定命名空间内,而 ClusterRole 是非命名空间资源。在监控系统中,我们可以将每个租户映射到一个 Kubernetes 命名空间,然后使用 Role 限制该租户只能访问其命名空间内的监控资源(如 ServiceMonitor、PodMonitor 等)。ClusterRole 则用于定义跨租户的全局操作,例如集群管理员查看所有指标。
需要注意的是,RBAC 权限是纯加性的,没有“拒绝”规则。这意味着,如果某个角色被授予了过宽的权限,无法通过另一个角色来“否定”它。因此,在设计角色时,应遵循最小权限原则:只授予完成工作所必需的最小权限集合。例如,“tenant-viewer”角色只应包含读取指标和告警的权限,而不应包含修改配置的权限。
数据隔离:标签、命名空间与查询路由
权限隔离解决了“谁能访问”的问题,但数据隔离还要解决“能访问哪些数据”的问题。在指标监控中,数据隔离通常通过以下三种机制实现:
1. 标签(Label)强制
最直接的方式是在写入指标时强制注入租户标签(如 tenant_id),并在查询时通过标签选择器限制访问范围。例如,在 Prometheus 的 recording rule 或 remote write 配置中,使用 relabeling 强制添加租户标签,确保每个指标都带有归属信息。查询端则通过 Proxy 或中间件,自动将租户标签注入到 PromQL 查询中,如 up{tenant="acme"}。这种方式的优点是实现简单,但需要保证标签的不可篡改性——如果租户可以自行写入数据,就可能伪造标签越权访问。
2. 命名空间隔离
对于基于 Kubernetes 的监控系统,命名空间天然提供了隔离边界。每个租户拥有独立的命名空间,其中的监控对象(如 Pod、Service)只能被该命名空间内的角色访问。这种方式的隔离性更强,但需要监控组件(如 Prometheus Operator)支持按命名空间配置数据采集范围,并且查询时需要跨命名空间路由。
3. 查询路由与视图
在查询层,可以通过多租户网关(如 Thanos Query、Cortex)实现租户感知的路由。网关根据请求中的租户标识,将查询分发到对应的数据分片,并过滤掉其他租户的数据。这种方式适合大规模多集群场景,但增加了架构复杂度。
常见误区与失败条件
在实际落地中,以下误区经常导致隔离方案失效:
- 仅依赖前端隐藏:只在前端 UI 隐藏无关数据,而后端 API 仍返回全量数据。攻击者可以通过直接调用 API 绕过限制,因此必须在服务端实施强制授权。
- 标签可被覆盖:如果租户的数据写入链路允许自定义标签,就可能通过覆盖租户标签来访问其他租户的数据。必须通过配置管理工具(如 Prometheus 的 relabeling)强制注入且不可覆盖。
- RBAC 角色过粗:将所有租户管理员绑定到同一个 ClusterRole,导致租户间权限越界。应为每个租户创建独立的 Role,并通过 RoleBinding 绑定到特定命名空间。
- 忽略服务账号:除了用户,监控系统还涉及服务账号(如 CI/CD 流水线)。如果服务账号权限过大,同样会造成数据泄露。应遵循最小权限原则,为不同用途创建独立的服务账号。
实施步骤与取舍
结合以上分析,一个典型的多租户指标监控隔离方案可按以下步骤实施:
- 定义租户模型:确定租户的标识方式(如租户 ID),以及租户与团队、项目的关系。
- 设计 RBAC 角色:基于 NIST RBAC 模型,定义全局角色(如 admin、viewer)和租户级角色,并映射到 Kubernetes RBAC 对象。
- 强制标签注入:在指标采集链路上,通过 relabeling 强制添加租户标签,并确保标签不可被下游覆盖。
- 部署授权代理:在查询 API 前部署代理,执行认证和授权,并根据租户上下文过滤查询。
- 验证与审计:定期使用不同租户的凭证测试数据访问范围,并审计授权日志,确保策略生效。
在取舍方面,基于标签的方案实现成本低,但隔离强度依赖于标签的完整性;基于命名空间的方案隔离性更强,但需要监控组件支持多租户;基于查询路由的方案适合大规模场景,但引入额外组件,运维复杂度上升。应根据实际业务规模和安全要求选择。
适用条件与不确定性
以上方案并非万能。对于单机版 Prometheus,由于本身不支持多租户,通常需要依赖外部代理或迁移到 Thanos、Cortex 等支持多租户的系统。此外,RBAC 和标签策略的效果还依赖于监控组件的实现细节,例如 Prometheus 的 relabeling 是否支持强制注入,查询 API 是否支持标签过滤。在实施前,应充分验证所选技术栈的能力,并在文档中明确限制条件。
参考资料
延伸阅读
