4. RBAC 深度解析(上):Role 与 ClusterRole 的定义、规则编写、资源与动词的匹配逻辑
RBAC(Role-Based Access Control)是 Kubernetes 生产环境中最常用的鉴权模式。理解 Role 与 ClusterRole 的本质区别,以及如何编写精确的规则(Rule),是掌握 RBAC 的第一步。本节将深入拆解这两个核心资源对象的定义结构、规则字段的编写方法,以及资源与动词的匹配逻辑。
4.1 Role 与 ClusterRole:作用域决定一切
Role 和 ClusterRole 在结构上几乎完全相同,唯一的区别在于 作用域(Scope)。这个区别决定了它们能授权哪些资源。
| 对比维度 | Role | ClusterRole |
|---|---|---|
| 作用域 | 特定 Namespace | 集群级别(所有 Namespace 或非 Namespace 资源) |
| 可授权的资源 | 仅限该 Namespace 内的资源(Pods、Services、Deployments 等) | 集群级别资源(Nodes、PersistentVolumes、ClusterRoles 等)+ 所有 Namespace 下的资源 |
| 典型使用场景 | 限制某个团队只能操作其所属 Namespace 的资源 | 集群管理员权限、跨 Namespace 的只读访问、授权给所有 Namespace 的公共角色 |
| 绑定对象 | RoleBinding(仅限同一 Namespace) | RoleBinding(授权特定 Namespace 资源)或 ClusterRoleBinding(授权集群资源) |
关键原则: 如果你需要授权访问
Nodes、PersistentVolumes 等集群级别资源,或者需要跨 Namespace 访问资源,必须使用 ClusterRole。如果权限只局限在一个 Namespace 内,优先使用 Role 以遵循最小权限原则。
4.2 规则(Rule)的结构与编写
无论是 Role 还是 ClusterRole,其核心都是 rules 字段。一个规则由三个关键部分组成:apiGroups、resources、verbs。理解这三者的组合逻辑,是编写正确权限的基础。
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: production
name: pod-reader
rules:
- apiGroups: [""] # 核心 API 组,对应 v1 版本
resources: ["pods"] # 资源类型
verbs: ["get", "list", "watch"] # 允许的操作
4.2.1 apiGroups:指定 API 组
- 核心组(Core Group):使用空字符串
"",代表v1API 版本下的资源,如 Pods、Services、ConfigMaps、Secrets、Nodes 等。 - 命名组(Named Group):如
"apps"(Deployments、StatefulSets)、"batch"(Jobs、CronJobs)、"networking.k8s.io"(Ingresses、NetworkPolicies)。 - 通配符:使用
"*"匹配所有 API 组,但生产环境应尽量避免。
4.2.2 resources:指定资源类型
- 标准资源名:使用资源的复数形式,如
pods、deployments、services。 - 子资源(Subresource):使用
资源名/子资源名格式,如pods/log、pods/exec、deployments/status。 - 资源组(Resource Group):部分资源属于同一逻辑组,如
pods、pods/log、pods/status可以统一授权。 - 通配符:使用
"*"匹配所有资源类型。
4.2.3 verbs:指定操作动词
动词对应 Kubernetes API 的 HTTP 方法。常见的动词及其映射关系如下:
| 动词 | 对应 HTTP 方法 | 说明 |
|---|---|---|
get |
GET | 获取单个资源详情 |
list |
GET(带集合路径) | 获取资源列表 |
watch |
GET(带 watch 参数) | 监听资源变化 |
create |
POST | 创建新资源 |
update |
PUT | 全量更新资源 |
patch |
PATCH | 部分更新资源 |
delete |
DELETE | 删除单个资源 |
deletecollection |
DELETE(带集合路径) | 批量删除资源 |
* |
所有方法 | 通配符,代表所有动词 |
常见误区: 很多初学者认为
get 权限就足够查看 Pod 日志,但实际上 pods/log 是一个独立的子资源,需要额外授权 get 动词到 pods/log 资源上。
4.3 资源与动词的匹配逻辑
Kubernetes 的鉴权引擎在匹配规则时,遵循 “与(AND)”逻辑:一个请求必须同时满足 apiGroups、resources、verbs 三个条件,才会被允许。如果规则中某个字段使用了通配符 "*",则视为匹配所有可能的值。
下面通过一个 SVG 流程图来展示鉴权引擎的匹配决策过程:
4.4 实战:编写一个精确的 ClusterRole
假设我们需要为集群审计员创建一个 ClusterRole,允许其读取所有 Namespace 下的 Pod 和 Service 信息,以及查看集群级别的 Node 状态。同时,不允许其进行任何写操作。
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: cluster-auditor
rules:
# 规则 1:读取所有 Namespace 下的 Pods 和 Services
- apiGroups: [""]
resources: ["pods", "services"]
verbs: ["get", "list", "watch"]
# 规则 2:读取 Nodes(集群级别资源)
- apiGroups: [""]
resources: ["nodes"]
verbs: ["get", "list", "watch"]
# 规则 3:读取 Pod 日志(子资源)
- apiGroups: [""]
resources: ["pods/log"]
verbs: ["get"]
# 规则 4:读取 Deployments(apps 组)
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "list", "watch"]
安全提醒: 即使只授予
get、list、watch 权限,也要注意 list 和 watch 可能会暴露资源名称和元数据。对于敏感环境,可以考虑只授予 get 权限,并要求用户知道具体的资源名称。
4.5 常见陷阱与最佳实践
- 陷阱 1:忘记授权子资源 —— 授权
pods的get权限,并不包含pods/log或pods/exec。需要显式添加子资源规则。 - 陷阱 2:混淆核心组与命名组 ——
Deployments属于apps组,不是核心组。如果规则中apiGroups: [""],则无法匹配deployments。 - 陷阱 3:过度使用通配符 ——
apiGroups: ["*"]和resources: ["*"]会授权所有未来可能新增的 API 组和资源,违背最小权限原则。 - 最佳实践: 始终从最小权限开始,逐步添加规则。使用
kubectl auth can-i --list命令验证当前用户的权限。