4. 权限边界模型:RBAC 基础、Role/ClusterRole、RoleBinding/ClusterRoleBinding

在多租户隔离集群中,权限边界是安全的第一道防线。Kubernetes 原生基于角色的访问控制(RBAC)提供了细粒度的权限管理能力,而 Helm Chart 在渲染和安装过程中必须严格遵守这些权限模型。本节将系统讲解 RBAC 的核心概念、资源对象及其在 Helm 多租户场景下的最佳实践。

4.1 RBAC 基础与核心概念

RBAC(Role-Based Access Control)是 Kubernetes 默认的授权机制,通过“角色”和“绑定”两个核心概念实现权限管理。其基本原理是:谁(Subject)能对哪些资源(Resource)执行什么操作(Verb)。

概念 说明 多租户场景意义
Subject 权限的请求主体,包括 User、Group、ServiceAccount 每个租户使用独立的 ServiceAccount 隔离身份
Resource Kubernetes API 资源对象,如 Pod、Service、Secret 限制租户只能操作命名空间内的特定资源
Verb 操作动词,如 get、list、create、update、delete 按需授予最小权限,禁止越权操作
Role / ClusterRole 定义一组权限规则的资源对象 Role 作用于命名空间,ClusterRole 作用于集群范围
RoleBinding / ClusterRoleBinding 将角色绑定到主体的桥梁 控制权限的作用域和生效范围
关键原则:在多租户 Helm 部署中,每个租户的 ServiceAccount 必须通过 RoleBinding 绑定到特定命名空间的 Role,禁止使用 ClusterRoleBinding 将集群级权限授予租户。

4.2 Role 与 ClusterRole:权限定义的核心

Role 和 ClusterRole 都包含一组规则(rules),每条规则由 apiGroups、resources、verbs 三个字段组成。两者的区别在于作用域:Role 仅作用于特定命名空间,而 ClusterRole 作用于整个集群(包括所有命名空间和非命名空间资源)。

4.2.1 Role 示例:命名空间级权限

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: tenant-alpha
  name: pod-reader
rules:
- apiGroups: [""]               # 核心 API 组
  resources: ["pods"]           # 资源类型
  verbs: ["get", "list", "watch"]  # 只读操作
- apiGroups: ["apps"]
  resources: ["deployments"]
  verbs: ["get", "list"]

4.2.2 ClusterRole 示例:集群级权限

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: cluster-reader
rules:
- apiGroups: [""]
  resources: ["nodes", "persistentvolumes"]  # 集群范围资源
  verbs: ["get", "list"]
- apiGroups: ["rbac.authorization.k8s.io"]
  resources: ["clusterroles", "clusterrolebindings"]
  verbs: ["get", "list"]
安全警告:Helm Chart 中如果定义了 ClusterRole,必须严格审查其权限范围。在多租户环境中,禁止将 ClusterRole 通过 ClusterRoleBinding 直接绑定到租户的 ServiceAccount,否则会导致租户获得集群级越权。

4.3 RoleBinding 与 ClusterRoleBinding:权限绑定的桥梁

RoleBinding 和 ClusterRoleBinding 将角色(Role/ClusterRole)与主体(User/Group/ServiceAccount)关联起来。绑定决定了权限的生效范围:

  • RoleBinding:将 Role 绑定到主体,权限作用域为 Role 所在的命名空间。
  • ClusterRoleBinding:将 ClusterRole 绑定到主体,权限作用域为整个集群。
  • RoleBinding 引用 ClusterRole:将 ClusterRole 绑定到主体,但权限作用域限制在 RoleBinding 所在的命名空间(常用模式)。

4.3.1 三种绑定模式对比

绑定模式 角色类型 绑定类型 权限作用域 多租户适用性
命名空间内绑定 Role RoleBinding 同一命名空间 ✅ 推荐,租户隔离最严格
集群角色命名空间绑定 ClusterRole RoleBinding RoleBinding 所在命名空间 ✅ 常用,复用集群级角色模板
集群级绑定 ClusterRole ClusterRoleBinding 整个集群 ❌ 禁止用于租户

4.3.2 推荐的多租户绑定模式

# 1. 定义集群级只读角色(模板)
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: tenant-readonly
rules:
- apiGroups: [""]
  resources: ["pods", "services", "configmaps", "secrets"]
  verbs: ["get", "list", "watch"]
---
# 2. 在每个租户命名空间内创建 RoleBinding,引用 ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  namespace: tenant-alpha
  name: alpha-readonly-binding
subjects:
- kind: ServiceAccount
  name: alpha-sa
  namespace: tenant-alpha
roleRef:
  kind: ClusterRole
  name: tenant-readonly
  apiGroup: rbac.authorization.k8s.io
最佳实践:在 Helm Chart 中,将 ClusterRole 定义为公共模板,通过 templates/_helpers.tpl 复用;RoleBinding 则在每个租户的 values.yaml 中动态生成,确保命名空间隔离。

4.4 权限边界模型 SVG 架构图

下图展示了多租户 Helm 部署中 RBAC 权限边界的完整模型,包括角色定义、绑定关系和作用域隔离:

多租户 Helm RBAC 权限边界模型 Kubernetes 集群边界 集群级角色(ClusterRole) tenant-readonly get/list/watch pods,svc,cm,secret tenant-operator create/update/delete deployments cluster-admin * (所有资源所有操作) 租户命名空间 A tenant-alpha 租户命名空间 B tenant-beta 系统命名空间 kube-system RoleBinding: alpha-readonly ServiceAccount: alpha-sa RoleBinding: alpha-operator ServiceAccount: alpha-operator-sa Pod Service ConfigMap Secret RoleBinding: beta-readonly ServiceAccount: beta-sa RoleBinding: beta-operator ServiceAccount: beta-operator-sa Pod Service ConfigMap Secret ClusterRoleBinding admin-user → cluster-admin 仅系统管理员可访问 租户无权访问此命名空间 🔒 权限边界:每个租户的 RoleBinding 只能引用其所在命名空间内的资源,ClusterRoleBinding 仅用于系统管理员,租户 ServiceAccount 无权跨命名空间访问

4.5 Helm Chart 中的 RBAC 模板化实践

在 Helm Chart 中,RBAC 资源应该通过模板动态生成,以适应多租户场景。以下是推荐的模板化策略:

4.5.1 模板文件结构

charts/tenant-app/
├── templates/
│   ├── _helpers.tpl          # 公共模板函数
│   ├── clusterrole.yaml      # 集群级角色定义(可选)
│   ├── role.yaml             # 命名空间角色定义
│   ├── rolebinding.yaml      # 角色绑定
│   └── serviceaccount.yaml   # 服务账户
└── values.yaml               # 租户配置

4.5.2 动态生成 RoleBinding 的模板示例

{{- /* templates/rolebinding.yaml */ -}}
{{- range .Values.tenants }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: {{ .name }}-{{ $.Values.roleName }}
  namespace: {{ .namespace }}
  labels:
    tenant: {{ .name }}
    app.kubernetes.io/managed-by: {{ $.Release.Service }}
subjects:
- kind: ServiceAccount
  name: {{ .serviceAccountName }}
  namespace: {{ .namespace }}
roleRef:
  kind: ClusterRole
  name: {{ $.Values.roleName }}
  apiGroup: rbac.authorization.k8s.io
{{- end }}

4.5.3 values.yaml 配置示例

# 公共角色名称
roleName: tenant-readonly

# 租户列表
tenants:
  - name: alpha
    namespace: tenant-alpha
    serviceAccountName: alpha-sa
  - name: beta
    namespace: tenant-beta
    serviceAccountName: beta-sa
  - name: gamma
    namespace: tenant-gamma
    serviceAccountName: gamma-sa
审计要点:在 Helm 部署后,应使用 kubectl describe rolebinding -n <namespace> 验证每个租户的绑定关系是否正确。重点关注:
1. ServiceAccount 是否属于正确的命名空间
2. roleRef 引用的 ClusterRole 是否具有最小权限
3. 是否存在意外的 ClusterRoleBinding 将集群权限授予租户

4.6 权限边界检查清单

检查项 合规要求 违规风险
租户 ServiceAccount 绑定 必须使用 RoleBinding,禁止使用 ClusterRoleBinding 租户获得集群级权限,可访问其他租户资源
ClusterRole 定义 仅包含必要的 API 组和资源,禁止使用 * 通配符 权限过度授予,可能泄露敏感资源
RoleBinding 命名空间 必须与租户命名空间一致 权限作用域错误,导致跨命名空间访问
Verb 最小化 按需授予 get/list/watch/create/update/delete 租户可能删除或修改非授权资源
Helm 模板变量 使用 .Values.tenants 循环生成,避免硬编码 配置管理混乱,新增租户时容易遗漏
自动化验证:建议在 CI/CD 流水线中集成 kube-score 或 conftest 工具,自动检查 Helm 渲染后的 RBAC 资源是否符合多租户隔离策略。例如,使用 OPA 策略禁止 ClusterRoleBinding 出现在租户命名空间中。