3. RBAC 基础:Role 与 ClusterRole、RoleBinding 与 ClusterRoleBinding、ServiceAccount 与用户映射

3.1 为什么容量调优需要 RBAC?

在 K8s 平台容量调优场景中,RBAC(基于角色的访问控制)决定了谁可以查看节点资源、调整 Pod 副本数、修改 HPA 配置或执行 kubectl top。错误的权限配置会导致运维人员无法及时扩容,或非授权人员误操作引发集群过载。理解 RBAC 的四个核心对象——Role、ClusterRole、RoleBinding、ClusterRoleBinding——以及 ServiceAccount 与用户映射机制,是构建安全、可审计的容量调优体系的第一步。

核心原则:RBAC 遵循“最小权限”原则。容量调优脚本或自动化工具应仅授予读取节点指标、更新 Deployment/StatefulSet 副本数、管理 HPA 的权限,避免授予集群管理员级别的全部权限。

3.2 Role 与 ClusterRole:定义权限集合

Role 和 ClusterRole 都是权限规则的集合,区别在于作用范围:

  • Role 作用于特定命名空间(Namespace),只能授权该命名空间内的资源。
  • ClusterRole 作用于整个集群,可以授权集群范围的资源(如 Node、PersistentVolume、ClusterRole 本身)或跨命名空间的资源。
对比维度 Role ClusterRole
作用范围 单个 Namespace 整个集群 / 所有 Namespace
可授权资源 Namespace 内资源(Pod、Service、Deployment 等) 集群级资源(Node、PV、CSIDriver)+ 所有 Namespace 资源
典型容量调优用途 授权某团队管理 production 命名空间的 HPA 授权 SRE 查看所有节点的 kubectl top node
YAML 示例 kind: Role kind: ClusterRole

容量调优场景示例:创建一个 ClusterRole,允许读取节点指标和 Pod 资源使用情况:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: capacity-viewer
rules:
- apiGroups: [""]
  resources: ["nodes", "nodes/stats", "pods", "pods/log"]
  verbs: ["get", "list", "watch"]
- apiGroups: ["metrics.k8s.io"]
  resources: ["nodes", "pods"]
  verbs: ["get", "list"]

3.3 RoleBinding 与 ClusterRoleBinding:将权限绑定到主体

权限定义(Role/ClusterRole)本身不生效,必须通过 RoleBinding 或 ClusterRoleBinding 绑定到用户、组或 ServiceAccount 上。

  • RoleBinding:将 Role 或 ClusterRole 绑定到同一命名空间内的主体。如果绑定的是 ClusterRole,则只授予该命名空间内的权限(权限范围被“裁剪”)。
  • ClusterRoleBinding:将 ClusterRole 绑定到集群级别的主体,授予跨所有命名空间的权限。
绑定类型 绑定的 Role 类型 权限作用范围 典型场景
RoleBinding Role 仅该 Namespace 给 team-a 授权管理 ns-team-a 的 HPA
RoleBinding ClusterRole 仅该 Namespace(权限被裁剪) 复用 capacity-viewer ClusterRole,但只给 ns-prod 使用
ClusterRoleBinding ClusterRole 整个集群 给 SRE 团队授权查看所有 Namespace 的节点和 Pod 指标

示例:将上面创建的 capacity-viewer ClusterRole 通过 ClusterRoleBinding 授予 SRE 团队:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: sre-capacity-viewer
subjects:
- kind: User
  name: "sre-team@company.com"
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: capacity-viewer
  apiGroup: rbac.authorization.k8s.io
常见陷阱:使用 RoleBinding 绑定 ClusterRole 时,权限会被限制在 RoleBinding 所在的 Namespace 内。例如,即使 ClusterRole 定义了读取所有 Namespace Pod 的权限,通过 RoleBinding 绑定后,只能读取该 Namespace 的 Pod。如果需要跨 Namespace 权限,必须使用 ClusterRoleBinding。

3.4 ServiceAccount 与用户映射

在 K8s 中,ServiceAccount 是 Pod 内进程用来与 API Server 交互的身份标识。容量调优自动化工具(如自定义调度器、HPA 控制器、资源预测脚本)通常以 ServiceAccount 运行。

  • ServiceAccount 是命名空间级别的资源,每个 Pod 必须关联一个 ServiceAccount(默认是 default)。
  • 通过 RoleBinding 或 ClusterRoleBinding 将权限授予 ServiceAccount,Pod 即可自动获得这些权限。
  • 用户映射:外部用户(如 SRE 工程师)通过 kubeconfig 中的证书或 映射到 K8s 的 User 类型;自动化工具通过 ServiceAccount 的 映射到 ServiceAccount 类型。两者都是 RBAC 的 subjects。
主体类型 典型来源 认证方式 容量调优场景
User 外部身份提供商(LDAP、OIDC)、证书 X.509 证书 / Bearer SRE 工程师手动执行 kubectl top node
Group 身份提供商中的用户组 证书中的组织字段 / OIDC 组声明 将整个 SRE 团队授权为容量查看者
ServiceAccount K8s API 创建 自动挂载的 JWT 自动化扩缩容脚本、Prometheus 指标采集器

创建 ServiceAccount 并授权的完整示例:

# 1. 创建 ServiceAccount
apiVersion: v1
kind: ServiceAccount
metadata:
  name: capacity-autoscaler
  namespace: production

# 2. 创建 Role(授权管理 HPA 和 Deployment)
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: hpa-manager
  namespace: production
rules:
- apiGroups: ["autoscaling"]
  resources: ["horizontalpodautoscalers"]
  verbs: ["get", "list", "watch", "update", "patch"]
- apiGroups: ["apps"]
  resources: ["deployments/scale"]
  verbs: ["get", "update", "patch"]

# 3. 绑定 Role 到 ServiceAccount
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: capacity-autoscaler-binding
  namespace: production
subjects:
- kind: ServiceAccount
  name: capacity-autoscaler
  namespace: production
roleRef:
  kind: Role
  name: hpa-manager
  apiGroup: rbac.authorization.k8s.io

3.5 RBAC 对象关系全景图

下图展示了 Role、ClusterRole、RoleBinding、ClusterRoleBinding 与 User、Group、ServiceAccount 之间的完整映射关系:

RBAC 对象关系与权限映射 RBAC 核心对象关系图 User Group ServiceAccount 主体 (Subjects) RoleBinding 作用范围:单个 Namespace ClusterRoleBinding 作用范围:整个集群 Role ClusterRole 权限定义 (Rules) 关键说明: 1. RoleBinding 只能引用同一 Namespace 的 Role,或引用 ClusterRole(此时权限被裁剪到该 Namespace)。 2. ClusterRoleBinding 只能引用 ClusterRole,且权限作用于整个集群。 3. ServiceAccount 通常用于自动化工具(如容量调优脚本),User/Group 用于人工操作。 4. 容量调优场景中,建议为每个自动化组件创建独立的 ServiceAccount,并授予最小必要权限。

3.6 容量调优 RBAC 最佳实践

  • 为自动化组件创建专用 ServiceAccount:不要使用 default ServiceAccount,避免权限扩散。例如,为 HPA 控制器创建 hpa-controller,为资源预测器创建 capacity-predictor。
  • 使用 ClusterRole 定义通用权限,通过 RoleBinding 限制范围:例如,定义一个 capacity-viewer ClusterRole,然后在不同 Namespace 通过 RoleBinding 授予不同团队,实现权限复用。
  • 定期审计权限绑定:使用 kubectl get rolebindings --all-namespaces 和 kubectl get clusterrolebindings 检查是否有过度授权的绑定。
  • 避免使用 cluster-admin 权限:容量调优工具通常不需要集群管理员权限。如果某个工具需要 cluster-admin,应重新评估其设计。
实战检查清单:
  1. 确认每个自动化组件(Prometheus、自定义调度器、HPA 控制器)都有独立的 ServiceAccount。
  2. 验证 ServiceAccount 的权限是否仅包含必要的 verbs(get/list/watch/update/patch),避免使用 *。
  3. 使用 kubectl auth can-i --list --as=system:serviceaccount:<ns>:<sa-name> 测试权限是否按预期生效。
  4. 对于跨 Namespace 的容量查看需求,优先使用 ClusterRoleBinding + ClusterRole,而非在每个 Namespace 重复创建 RoleBinding。