3. RBAC 权限模型:核心对象与多租户权限设计

RBAC(Role-Based Access Control)是 Kubernetes 中默认且唯一的授权机制。它通过将“权限”与“角色”绑定,再将“角色”与“用户/服务账户”绑定,实现了权限与主体的解耦。在多租户场景下,RBAC 是构建租户隔离的第一道防线。

3.1 RBAC 四大核心对象

Kubernetes RBAC 由四个 API 对象构成,分为两类:角色定义(Role / ClusterRole)和角色绑定(RoleBinding / ClusterRoleBinding)。

对象 作用域 核心字段 典型用途
Role 命名空间级 rules: apiGroups, resources, verbs 授予某 Namespace 内 Pod、Service 等资源的操作权限
ClusterRole 集群级 rules: apiGroups, resources, verbs 授予 Node、PV、ClusterRole 等集群范围资源的权限
RoleBinding 命名空间级 subjects: kind, name; roleRef: kind, name 将 Role 或 ClusterRole 绑定到某 Namespace 内的用户/SA
ClusterRoleBinding 集群级 subjects: kind, name; roleRef: kind, name 将 ClusterRole 绑定到集群范围的用户/SA
关键区别:RoleBinding 引用 ClusterRole 时,仅授予该 ClusterRole 中命名空间内资源的权限,不会授予集群范围资源权限。这是多租户共享集群角色但隔离权限的核心机制。

3.2 最小权限原则(PoLP)

最小权限原则要求每个主体只拥有完成其任务所必需的最小权限集合。在 Kubernetes 中落地 PoLP 需要遵循以下步骤:

  1. 拒绝所有,显式允许:RBAC 默认拒绝所有请求,只需定义允许的规则。
  2. 按需分配 verbs:避免使用通配符 *,优先使用 get、list、watch、create、update、patch、delete 中的具体动词。
  3. 资源粒度控制:使用 resourceNames 字段将权限限制到特定资源实例。
  4. 非资源 URL 单独授权:通过 ClusterRole 的 nonResourceURLs 字段控制 /api、/healthz 等路径的访问。
  5. 聚合角色:使用 aggregationRule 动态组合多个 ClusterRole,避免手动维护庞大规则集。
实战建议:在压测沙盘中,为每个租户的 CI/CD 服务账户仅授予 get、list、watch 权限,部署操作由平台管理员通过 Webhook 审批后执行,避免租户越权操作影响沙盘稳定性。

3.3 多租户权限设计模式

多租户场景下,RBAC 设计通常采用“租户管理员 → 租户开发者 → 租户只读用户”三层模型。以下是一个典型的多租户权限设计示例:

# 1. 创建租户只读 Role(命名空间级)
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: tenant-alpha
  name: tenant-reader
rules:
- apiGroups: [""]
  resources: ["pods", "services", "configmaps", "secrets"]
  verbs: ["get", "list", "watch"]
---
# 2. 创建租户开发者 Role(命名空间级)
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: tenant-alpha
  name: tenant-developer
rules:
- apiGroups: [""]
  resources: ["pods", "services", "configmaps"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- apiGroups: ["apps"]
  resources: ["deployments", "statefulsets"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
---
# 3. 创建租户管理员 RoleBinding(绑定集群管理员下放的 ClusterRole)
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  namespace: tenant-alpha
  name: tenant-admin-binding
subjects:
- kind: User
  name: "admin@tenant-alpha.com"
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: admin
  apiGroup: rbac.authorization.k8s.io
避坑指南:不要将 cluster-admin ClusterRole 直接绑定给租户管理员。应创建一个受限的 tenant-admin ClusterRole,仅包含 namespaces、resourcequotas、limitranges 等租户管理所需权限,并配合 RoleBinding 限定到具体 Namespace。

3.4 RBAC 权限模型架构图

下图展示了多租户场景下 RBAC 对象之间的绑定关系与权限流向:

多租户 RBAC 权限模型架构 User / ServiceAccount Group RoleBinding ClusterRoleBinding Role (命名空间级) ClusterRole (集群级) 权限规则(rules) apiGroups: [""] resources: ["pods"] verbs: ["get", "list", "watch"] resourceNames: ["my-pod"] → 将权限限定到特定资源实例 租户 A Namespace: tenant-alpha RoleBinding → Role (tenant-developer) 仅可操作 tenant-alpha 内资源 租户 B Namespace: tenant-beta RoleBinding → ClusterRole (view) 仅可查看 tenant-beta 内资源

3.5 多租户权限设计检查清单

在压测沙盘中部署多租户 RBAC 时,建议按以下清单逐项验证:

  • 命名空间隔离:每个租户拥有独立 Namespace,所有 RoleBinding 限定在该 Namespace 内。
  • ClusterRole 复用:将通用权限(如只读、日志查看)定义为 ClusterRole,通过 RoleBinding 引用,避免重复定义。
  • 禁止通配符:检查所有 Role/ClusterRole 的 verbs 字段,确保没有使用 ["*"]。
  • 资源配额绑定:RBAC 与 ResourceQuota、LimitRange 配合使用,防止租户资源滥用。
  • 审计日志:启用 Kubernetes 审计日志,记录所有 RBAC 相关的 create、update、delete 操作。
  • 定期复审:使用 kubectl auth can-i --list --as=system:serviceaccount:tenant-alpha:sa-name 验证实际权限。
容量预测关联:在压测沙盘中,RBAC 的鉴权请求会消耗 API Server 的 CPU 和内存资源。当租户数量超过 50 个时,建议将 RBAC 缓存(--authorization-webhook-cache-ttl)从默认 5 分钟调整为 10 分钟,减少 API Server 的鉴权压力。