2. Kubernetes RBAC 基础:Role 与 ClusterRole、RoleBinding 与 ClusterBinding、ServiceAccount 与用户映射

在云原生安全权限工程中,Kubernetes 原生的 RBAC(基于角色的访问控制) 是权限治理的基石。无论是 Kyverno 策略引擎的触发动作,还是 IDP 内部开发者平台的自助服务操作,最终都会映射到 Kubernetes API Server 的鉴权层。理解 RBAC 的四类核心资源及其与 ServiceAccount 的映射关系,是构建安全权限拓扑的前提。

2.1 核心概念:Role 与 ClusterRole

Role 和 ClusterRole 定义了“能做什么”的规则集合,包含一组 verbs(操作动词)和 resources(资源对象)。两者的核心区别在于作用域:

对比维度 Role ClusterRole
作用域 单个 Namespace 整个集群(所有 Namespace + 集群级资源)
适用资源 Namespaced 资源(Pod、Service、Deployment 等) Namespaced 资源 + 集群级资源(Node、PV、ClusterRole、CRD 等)
典型场景 开发团队只能操作 dev-ns 下的 Pod 集群管理员可查看所有 Node;策略引擎可读取所有 Namespace 的 Secret
创建命令 kubectl create role kubectl create clusterrole
设计原则: 在 IDP 拓扑中,优先使用 Role + RoleBinding 实现租户隔离;仅在需要跨 Namespace 或操作集群级资源时,才使用 ClusterRole + ClusterRoleBinding。Kyverno 的 generate 和 mutate 策略通常需要 ClusterRole 权限来创建或修改跨 Namespace 的资源。

以下是一个典型的 Role YAML 示例,允许在 team-a Namespace 下对 Pod 执行 get/watch/list 操作:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: team-a
  name: pod-reader
rules:
- apiGroups: [""]          # 核心 API 组
  resources: ["pods"]
  verbs: ["get", "watch", "list"]

对应的 ClusterRole 示例,允许读取所有 Namespace 的 Pod 以及集群级别的 Node 信息:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: cluster-pod-reader
rules:
- apiGroups: [""]
  resources: ["pods", "nodes"]
  verbs: ["get", "watch", "list"]

2.2 绑定机制:RoleBinding 与 ClusterRoleBinding

Role/ClusterRole 只是权限模板,必须通过 Binding(绑定) 将其授予具体的 Subject(主体)。Subject 可以是 User、Group 或 ServiceAccount。

绑定类型 绑定的 Role 类型 作用范围 典型用法
RoleBinding Role(推荐)或 ClusterRole 仅限绑定时指定的 Namespace 将 pod-reader Role 授予 team-a 的 ServiceAccount
ClusterRoleBinding 仅限 ClusterRole 整个集群 将 cluster-admin ClusterRole 授予运维组
常见陷阱: RoleBinding 可以引用 ClusterRole,但此时权限仍被限制在 RoleBinding 所在的 Namespace 内。例如,将 cluster-pod-reader ClusterRole 通过 RoleBinding 绑定到 team-a,则该主体只能读取 team-a 下的 Pod,无法读取其他 Namespace 的 Pod。这种“降级绑定”常用于复用集群级权限模板,同时保持租户隔离。

RoleBinding 示例(绑定到 ServiceAccount):

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: pod-reader-binding
  namespace: team-a
subjects:
- kind: ServiceAccount
  name: app-sa
  namespace: team-a
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

ClusterRoleBinding 示例(绑定到用户组):

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: cluster-admin-binding
subjects:
- kind: Group
  name: ops-team
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: cluster-admin
  apiGroup: rbac.authorization.k8s.io

2.3 ServiceAccount 与用户映射

在 Kubernetes 中,ServiceAccount 是 Pod 内进程用于与 API Server 交互的身份凭证。与普通用户不同,ServiceAccount 由 Kubernetes 自动管理 Secret(或通过 TokenRequest API 获取 ),是 IDP 和策略引擎最常用的身份类型。

  • 自动挂载: 每个 Namespace 默认有一个 default ServiceAccount;Pod 若不指定 spec.serviceAccountName,则自动使用 default SA。
  • 生命周期: 自 Kubernetes v1.24 起,不再自动生成 Secret 类型的 ,推荐使用 TokenRequest API 获取绑定 Pod 生命周期的投射卷 。
  • 用户映射: 外部身份系统(如 LDAP、OIDC)通过 kube-apiserver 的 --oidc-* 参数映射为 Kubernetes 用户;ServiceAccount 则通过 system:serviceaccount:<namespace>:<name> 格式被识别。
IDP 集成要点: 内部开发者平台通常为每个开发者或 CI/CD 流水线创建独立的 ServiceAccount,并通过 RoleBinding 授予最小权限。Kyverno 策略引擎本身也以 ServiceAccount 身份运行,需要 ClusterRole 来执行跨 Namespace 的策略生成和资源修改。
Kubernetes RBAC 核心资源关系图 Kubernetes RBAC 核心资源关系图 Role (Namespace 级别) ClusterRole (集群级别) RoleBinding (绑定到 Namespace) ClusterRoleBinding (绑定到整个集群) ServiceAccount (Pod 身份) User / Group (外部身份映射) RoleBinding 可引用 ClusterRole(降级) 关键规则: • RoleBinding 只能引用同一 Namespace 的 Role,或引用 ClusterRole(此时权限降级到 Namespace 级别)。 • ClusterRoleBinding 只能引用 ClusterRole,且权限作用于整个集群。

2.4 权限聚合与默认 ClusterRole

Kubernetes 内置了一组 默认 ClusterRole,用于常见的聚合场景。理解这些默认角色有助于在 IDP 中设计权限基线:

默认 ClusterRole 权限范围 IDP 使用建议
cluster-admin 所有资源的完全控制权 仅限平台运维团队;IDP 自身不应使用此角色
admin Namespaced 资源完全控制权(含 RBAC) 可授予 IDP 租户管理员,允许其管理本 Namespace 下的子用户
edit Namespaced 资源读写(不含 RBAC) 适合开发者日常操作,可创建/更新/删除应用资源
view Namespaced 资源只读 适合只读监控、审计场景
聚合策略: 在 IDP 中,建议使用 聚合 ClusterRole(通过 aggregationRule 字段)将多个细粒度 ClusterRole 组合成业务角色。Kyverno 的 generate 策略也支持自动创建 RoleBinding,将聚合后的权限绑定到新创建的 Namespace。

2.5 最小权限实践:从 ServiceAccount 到策略引擎

在 Kyverno 与 IDP 集成的场景中,ServiceAccount 的权限设计直接影响策略执行的安全性。以下是推荐的最小权限实践步骤:

  1. 创建专用 ServiceAccount: 为每个 IDP 组件(如策略控制器、自助服务 API、CI/CD 流水线)创建独立的 ServiceAccount,避免共享 default SA。
  2. 使用 Role 而非 ClusterRole: 除非必须跨 Namespace 操作,否则优先使用 Role 限定权限范围。
  3. 精确 verbs: 只授予必要的操作动词(如 get、list、watch),避免使用通配符 *。
  4. 资源字段限制: 对于敏感资源(如 Secret),使用 resourceNames 字段限制可访问的具体实例。
  5. 定期审计: 使用 kubectl auth can-i --list --as=system:serviceaccount:<ns>:<name> 验证实际权限。
ServiceAccount 权限映射与最小权限流程 ServiceAccount 权限映射与最小权限流程 Pod spec.serviceAccountName ServiceAccount TokenRequest API 投射卷 API Server 鉴权 Role / ClusterRole RoleBinding 最小权限策略 最小权限检查清单: ① 使用专用 SA ② 优先 Role 而非 ClusterRole ③ 精确 verbs ④ 限制 resourceNames ⑤ 定期审计权限

2.6 本章小结

  • Role vs ClusterRole: 作用域是核心区别;IDP 中优先使用 Role 实现租户隔离。
  • RoleBinding vs ClusterRoleBinding: RoleBinding 可引用 ClusterRole 实现权限降级复用;ClusterRoleBinding 仅限 ClusterRole。
  • ServiceAccount 映射: 是 Pod 与 API Server 之间的身份桥梁;外部用户通过 OIDC/LDAP 映射为 User/Group。
  • 最小权限: 从专用 SA、精确 verbs、资源限制到定期审计,形成闭环权限治理。