17.10.4 RBAC与多租户隔离策略

RBAC与多租户隔离在Prometheus生态中通常通过“入口控制+数据隔离+操作审计”共同实现。Prometheus本身缺少内置细粒度RBAC,需要借助反向代理、授权网关或多实例拆分来满足多租户需求。多租户隔离的目标包括:查询与可视化隔离、告警规则隔离、写入与远程存储隔离,以及对元数据与目标发现的控制。

原理草图(入口鉴权 + 多租户查询)#

文章图片

RBAC实现路径#

  • 反向代理授权:在Prometheus与Grafana前端通过Nginx/Envoy接入OIDC/LDAP,基于用户组映射到读/写/管理员角色。
  • 查询层控制:使用Thanos Query Frontend、Cortex/Mimir或自建API网关,在查询请求中注入租户标识(如X-Scope-OrgID),并基于租户策略限制PromQL与时间范围。
  • 规则管理控制:将告警规则、记录规则存储在Git仓库,使用GitOps与CI审批流程控制变更权限,运行时由不同租户的Ruler实例加载。

多租户隔离策略#

  • 物理隔离:每个租户独立Prometheus与Alertmanager实例,资源与数据完全隔离,适合合规要求高的场景。
  • 逻辑隔离:共享后端存储,通过租户ID或标签进行隔离,依赖Cortex/Mimir/Thanos等组件实现。
  • 标签隔离约束:统一约定tenant/team等标签,强制在采集配置和告警规则中注入,配合网关进行标签强制校验与重写。

告警与通知隔离#

  • Alertmanager多实例或路由隔离:按租户维度设置接收器与路由,禁止跨租户的告警转发与合并。
  • Webhook权限控制:为每个租户配置独立的Webhook密钥与回调地址,限制告警模板可访问的标签范围。

安全边界与运维规范#

  • 最小权限原则:读写分离,限制查询时间范围与高基数标签查询,防止资源滥用。
  • 变更审计:所有RBAC策略与规则变更必须有审计记录,包含操作者、时间、变更内容与回滚方案。
  • 配额与限流:对每租户的查询频率、并发、告警数量设定配额,防止单租户影响整体稳定性。

典型落地方案示例#

  • 入口使用OIDC登录,映射viewer/editor/admin角色。
  • Prometheus通过反向代理统一鉴权,Grafana使用组织与文件夹隔离视图。
  • 远程存储采用Mimir,按租户ID隔离指标,Alertmanager路由按租户分组。

示例:Nginx反向代理实现基础RBAC + 租户头注入#

目标:为不同用户注入X-Scope-OrgID,限制访问Prometheus与Thanos Query Frontend。

安装Nginx(示例)#

# Ubuntu/Debian
sudo apt-get update
sudo apt-get install -y nginx apache2-utils

# CentOS/RHEL
sudo yum install -y nginx httpd-tools

创建用户与租户映射文件#

# 生成基础认证用户
sudo htpasswd -c /etc/nginx/htpasswd prom_viewer
sudo htpasswd /etc/nginx/htpasswd prom_admin

Nginx配置(/etc/nginx/conf.d/prometheus_rbac.conf)#

map $remote_user $tenant_id {
  default             "public";
  prom_viewer         "team-a";
  prom_admin          "team-admin";
}

server {
  listen 80;
  server_name prom.example.com;

  # 基础认证
  auth_basic "Prometheus RBAC";
  auth_basic_user_file /etc/nginx/htpasswd;

  # Prometheus只读
  location / {
    proxy_pass http://prometheus:9090;
    proxy_set_header X-Scope-OrgID $tenant_id;
    proxy_set_header X-Forwarded-User $remote_user;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  }

  # Thanos Query Frontend
  location /thanos/ {
    proxy_pass http://thanos-query-frontend:10902/;
    proxy_set_header X-Scope-OrgID $tenant_id;
    proxy_set_header X-Forwarded-User $remote_user;
  }
}

生效与验证#

sudo nginx -t
sudo systemctl reload nginx

# 验证用户访问与头注入
curl -u prom_viewer:密码 -I http://prom.example.com/
curl -u prom_admin:密码 -H "X-Scope-OrgID:team-admin" -I http://prom.example.com/thanos/

关键参数说明
- auth_basic_user_file: 指定账号密码文件。
- map $remote_user $tenant_id: 将用户映射为租户ID。
- X-Scope-OrgID: 多租户查询头,Cortex/Mimir/Thanos支持。


示例:Grafana组织与文件夹隔离#

目标:不同租户只看到自己的仪表盘与告警规则。

Grafana组织与权限(命令行或API)#

# 创建组织
curl -X POST -H "Content-Type: application/json" \
  -u admin:admin \
  -d '{"name":"team-a"}' \
  http://grafana:3000/api/orgs

# 为组织添加用户
curl -X POST -H "Content-Type: application/json" \
  -u admin:admin \
  -d '{"loginOrEmail":"user_a","role":"Viewer"}' \
  http://grafana:3000/api/orgs/2/users

预期效果team-a 用户只能访问自己的组织、文件夹与仪表盘。


示例:Prometheus采集强制租户标签#

目标:所有采集目标自动注入tenant标签,便于规则与查询隔离。

prometheus.yml#

global:
  scrape_interval: 15s

scrape_configs:
  - job_name: "node"
    static_configs:
      - targets: ["node1:9100", "node2:9100"]
        labels:
          tenant: "team-a"

验证(PromQL)#

up{tenant="team-a"}

预期效果:查询仅返回team-a租户的目标。


示例:Alertmanager按租户路由#

目标:不同租户告警只发到自己接收器。

alertmanager.yml#

route:
  group_by: ["alertname", "tenant"]
  receiver: "default"
  routes:
    - match:
        tenant: "team-a"
      receiver: "team-a-webhook"
    - match:
        tenant: "team-b"
      receiver: "team-b-webhook"

receivers:
  - name: "default"
  - name: "team-a-webhook"
    webhook_configs:
      - url: "https://webhook.example.com/team-a?token=xxx"
  - name: "team-b-webhook"
    webhook_configs:
      - url: "https://webhook.example.com/team-b?token=yyy"

预期效果tenant=team-a的告警不会发送到team-b


排错清单(常见问题与定位)#

  1. 访问被拒绝(401/403)
    - 检查/etc/nginx/htpasswd是否包含用户
    - nginx -t是否通过,查看/var/log/nginx/error.log

  2. 租户隔离失效(看到其他租户数据)
    - 检查是否注入X-Scope-OrgID
    - 检查后端是否启用多租户模式(Cortex/Mimir)

  3. Grafana看到其他组织仪表盘
    - 检查用户角色(Viewer/Editor/Admin)
    - 确认组织切换权限和文件夹权限

  4. 告警跨租户发送
    - 检查告警规则是否写入tenant标签
    - Alertmanagergroup_by是否包含tenant


练习#

  1. 反向代理练习:新增用户prom_team_b,映射tenant_idteam-b,验证X-Scope-OrgID是否生效。
  2. 规则隔离练习:为team-a编写一条告警规则,只匹配tenant="team-a"的目标。
  3. Grafana隔离练习:创建team-b组织和文件夹,验证team-a用户无法访问。
  4. 故障注入:临时移除tenant标签,观察告警路由是否出现跨租户发送并恢复配置。