3. RBAC 策略设计原则

RBAC 策略设计是 Kubernetes 权限治理的基石。在生产环境中,错误的策略配置往往导致权限泄露或运维阻塞。本章围绕四大核心原则展开:最小权限、职责分离、权限分层、默认拒绝。每个原则都配有实战案例与可视化结构图,帮助你在集群中落地可审计、可追溯的权限体系。

3.1 最小权限原则

最小权限原则要求每个主体(用户、ServiceAccount、Pod)只获得完成其任务所必需的最小权限集合。在 Kubernetes 中,这意味着:

  • 不授予集群级别的权限,除非明确需要跨 Namespace 操作。
  • 优先使用 Role + RoleBinding,而非 ClusterRole + ClusterRoleBinding。
  • 限制资源操作动词:只给 get、list、watch,不给 create、update、delete。
  • 资源粒度细化:按 Deployment、Pod、ConfigMap 等具体资源类型授权。
实战案例: 某 CI/CD 流水线 ServiceAccount 只需要在 dev Namespace 中创建和更新 Deployment,不应拥有删除 Pod 或访问 Secret 的权限。错误配置会允许流水线意外删除生产环境资源。
场景 推荐权限 常见过度授权
只读监控 get, list, watch 作用于 Pod、Service 授予 cluster-admin 或 * 动词
应用部署 create, update 作用于 Deployment 授予 delete 或 patch 权限
日志查看 get 作用于 Pod/log 子资源 授予 pods/exec 权限
Secret 管理 get, create 作用于 Secret 授予 list 或 watch 所有 Secret

3.2 职责分离原则

职责分离确保没有单个主体能同时拥有冲突的权限组合。在 RBAC 策略中,典型冲突包括:

  • 创建资源 + 删除资源:防止恶意或误操作导致数据丢失。
  • 写入资源 + 读取 Secret:避免通过修改 Deployment 注入恶意镜像并窃取凭证。
  • 绑定 Role + 拥有高权限 Role:防止权限提升攻击。
设计建议: 将权限拆分为“操作角色”和“审计角色”。操作角色负责日常变更,审计角色只拥有只读权限,用于合规审查。两个角色由不同人员持有。

以下表格展示了常见的职责分离策略:

角色 A 角色 B 冲突原因
Deployment 创建者 Deployment 删除者 可创建后立即删除,导致服务中断且无法追溯
Secret 读取者 Pod 创建者 可读取数据库密码并注入恶意 Pod 窃取数据
RoleBinding 管理员 Cluster-admin 持有者 可将自己绑定到 cluster-admin,实现权限提升

3.3 权限分层原则

权限分层将集群权限按层级组织,形成清晰的授权树。Kubernetes 天然支持三层结构:

  1. 集群层:ClusterRole + ClusterRoleBinding,影响所有 Namespace。
  2. Namespace 层:Role + RoleBinding,限定在单个 Namespace 内。
  3. 资源实例层:通过 resourceNames 字段精确到具体资源名称。

分层设计的好处:

  • 权限范围逐层收窄,降低爆炸半径。
  • 审计日志可清晰定位授权层级。
  • 便于继承与覆盖:Namespace 层可覆盖集群层的默认策略。
注意: 避免在集群层授予过于宽泛的权限,例如 verbs: ["*"] 或 resources: ["*"]。即使使用 ClusterRole,也应尽量通过 resourceNames 限制到具体资源。
RBAC 权限分层结构 集群层(ClusterRole + ClusterRoleBinding) 影响所有 Namespace,通常用于基础设施组件(监控、Ingress Controller) 示例:cluster-admin, view, edit Namespace 层(Role + RoleBinding) 限定在单个 Namespace 内,适用于应用团队、项目隔离 示例:dev-team-role, prod-reader 资源实例层(resourceNames) 精确到具体资源名称,如特定 Secret、特定 Deployment 示例:resourceNames: ["db-secret", "api-deployment"]

3.4 默认拒绝策略

默认拒绝是 Kubernetes RBAC 的底层安全模型:任何未显式授权的操作都会被拒绝。这意味着:

  • 新创建的 ServiceAccount 默认没有任何权限。
  • 必须通过 RoleBinding 或 ClusterRoleBinding 显式授予权限。
  • 删除 RoleBinding 后,对应主体立即失去权限。
关键理解: Kubernetes 没有“隐式允许”机制。即使你创建了 Role,如果不绑定到主体,该 Role 不会生效。这天然支持了“白名单”安全模型。

默认拒绝策略的落地检查清单:

检查项 操作 预期结果
新建 ServiceAccount kubectl get pods Forbidden(默认拒绝)
删除 RoleBinding 原绑定主体再次请求 Forbidden(权限立即回收)
未绑定 ClusterRole 跨 Namespace 操作 Forbidden(无集群权限)
资源名不匹配 请求未授权的资源实例 Forbidden(resourceNames 过滤)

以下 SVG 展示了默认拒绝策略的请求处理流程:

默认拒绝策略请求处理流程 API 请求到达 认证(Authentication) 授权检查(Authorization) 拒绝(403 Forbidden) 允许(请求继续)

3.5 原则综合应用示例

以下是一个综合应用四大原则的 RBAC 配置示例:

---
# 1. 最小权限:只授予 get/list/watch 权限
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: production
  name: prod-reader
rules:
- apiGroups: [""]
  resources: ["pods", "services", "endpoints"]
  verbs: ["get", "list", "watch"]
---
# 2. 职责分离:只读角色与读写角色分离
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: production
  name: prod-deployer
rules:
- apiGroups: ["apps"]
  resources: ["deployments"]
  verbs: ["get", "list", "watch", "create", "update"]
  resourceNames: ["api-server", "web-frontend"]
---
# 3. 权限分层:使用 RoleBinding 限定 Namespace
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  namespace: production
  name: prod-reader-binding
subjects:
- kind: User
  name: "auditor@company.com"
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: prod-reader
  apiGroup: rbac.authorization.k8s.io
---
# 4. 默认拒绝:未显式绑定的主体无任何权限
# 无需额外配置,Kubernetes 默认拒绝所有未授权请求
最佳实践: 每次创建 Role 或 ClusterRole 后,使用 kubectl auth can-i --as=system:serviceaccount:namespace:sa-name --list 验证权限是否符合预期。定期审计所有 RoleBinding,移除不再使用的绑定。