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):使用空字符串 "",代表 v1 API 版本下的资源,如 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 流程图来展示鉴权引擎的匹配决策过程:

RBAC 规则匹配逻辑流程图 RBAC 规则匹配逻辑 收到 API 请求 检查 apiGroups 是否匹配 检查 resources 是否匹配 检查 verbs 是否匹配 全部匹配? 允许请求 拒绝请求 匹配规则:apiGroups、resources、verbs 三者必须同时满足 任一字段使用 "*" 通配符时,视为匹配所有可能值

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 命令验证当前用户的权限。