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 权限边界的完整模型,包括角色定义、绑定关系和作用域隔离:
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 部署后,应使用
1. ServiceAccount 是否属于正确的命名空间
2. roleRef 引用的 ClusterRole 是否具有最小权限
3. 是否存在意外的 ClusterRoleBinding 将集群权限授予租户
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 出现在租户命名空间中。