本文目录导读:

- 从“完全拒绝”开始,只做“加法”
- 使用特定的 API 组和资源
- 使用动词的精确性
- 合理选择 Role 还是 ClusterRole
- 使用 Aggregated ClusterRole
- 特别注意 Secret 的权限
- 使用 SubjectAccessReview(SAR)进行审计
- 避免使用默认的 Cluster-Admin 和 Edit 角色
- 针对 ServiceAccount 的特殊管理
- 定期审计与自动化
- 实际示例:给 CI/CD 工具(如 Jenkins)最小权限
- 总结核心检查清单
Kubernetes RBAC(基于角色的访问控制)的最小权限原则核心是只授予一个身份(用户/ServiceAccount)完成其特定工作所需的最精确的操作(verbs)和资源(resources)。
实现这个原则需要从角色定义、角色绑定、资源范围以及治理四个维度入手,以下是具体的最佳实践步骤:
从“完全拒绝”开始,只做“加法”
永远不要一开始就使用 通配符,不要给角色授予 (所有操作)或 get, list, watch, create, update, patch, delete 的全集。
-
错误示例:
rules: - apiGroups: [“”] resources: [“pods”] verbs: [“*”]
-
正确做法: 只列出必须的操作,如果某个组件只需要看日志(
get和logs),就不要给delete或create。
使用特定的 API 组和资源
避免使用 apiGroups: [“*”](匹配所有 API 组)。
- 规则: 明确指定
apiGroups。- 核心组:
- Apps:
“apps” - 批处理:
“batch”
- 子资源限制: 对于某些操作,需要指定子资源。
- 查看日志:
resources: [“pods/log”],而不仅仅是“pods”。 - 执行命令:
resources: [“pods/exec”] - 端口转发:
resources: [“pods/portforward”]
- 查看日志:
使用动词的精确性
动词的粒度决定了你能做什么,常见动词的权限范围如下:
| 动词 | 权限范围(结合get/list) | 潜在风险 |
|---|---|---|
get, list, watch |
读取 | 泄露敏感信息(如 Secret 内容) |
update, patch |
修改 | 修改资源状态,如更改镜像、副本数 |
create |
创建 | 创建新的 Pod/Service/Deployment |
delete |
删除 | 删除生产资源导致宕机 |
deletecollection |
批量删除 | 毁灭性操作,通常应禁用 |
最小实践:
- 监控工具: 只需要
get,list,watch。 - CI/CD 部署工具: 对于 Deployment 需要
get,list,update,patch;对于 Pod 可能只需要get,list。 - 开发者调试: 只给
get日志和exec进入容器的权限,不给delete。
合理选择 Role 还是 ClusterRole
- Role(命名空间级别): 优先使用,绝大多数工作负载(如部署到某个 namespace 的应用)都应该使用
Role+RoleBinding。 - ClusterRole(集群级别): 仅在必要时使用。
- 场景: 集群管理员、集群级别的监控(如查看所有 Node)、持久化卷(PV)管理、自定义资源定义(CRD)管理。
- 注意: 即使使用
ClusterRole,也可以通过RoleBinding将其限制在特定 namespace 内(仅授予该 namespace 内资源的权限)。
使用 Aggregated ClusterRole
不要手动拼凑一堆权限,对于需要跨多个 API 组(如 apps/v1, batch/v1, networking.k8s.io/v1)的复杂角色(如“查看者”),使用聚合 ClusterRole(aggregationRule)。
- 原理: 通过 Label Selector 自动组合多个 ClusterRole 的权限。
- 示例:
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: custom-viewer labels: rbac.example.com/aggregate-to-custom-viewer: “true” # 关键标签 rules: [] # 空规则,由聚合器填充 --- # 其他 ClusterRole 添加该标签后会自动加入 apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: pod-viewer labels: rbac.example.com/aggregate-to-custom-viewer: “true” rules: - apiGroups: [“”] resources: [“pods”] verbs: [“get”, “list”]
特别注意 Secret 的权限
Secret 是 Kubernetes 中最敏感的数据,任何能 get 或 list Secret 的角色,实际上都等于拥有了该 Secret 中所有明文密码和 Token。
- 最小原则: 除非绝对必要,否则不要在角色中包含对
secrets资源的get,list,watch权限。 - 替代方案: 如果应用需要读取挂载的 Secret,使用 Volume 挂载或环境变量注入(由 Kubelet 自动完成,不需要 RBAC 权限)。
使用 SubjectAccessReview(SAR)进行审计
在将新权限授予生产集群之前,可以使用 kubectl auth can-i 命令模拟检查。
# 检查用户 “dev-user” 能否在 namespace “prod” 中删除 Pod kubectl auth can-i delete pods --as=dev-user --namespace=prod # 检查 ServiceAccount “my-sa” 能否创建 Deployment kubectl auth can-i create deployments --as=system:serviceaccount:my-ns:my-sa
避免使用默认的 Cluster-Admin 和 Edit 角色
cluster-admin: 永远不要直接绑定到用户或 ServiceAccount,除非是全职集群管理员。edit: 不要直接绑定给开发者,因为它包含创建/修改 Secret、RBAC 规则的能力。view: 相对安全,但会暴露所有 Pod 内的环境变量(可能含敏感信息)。
针对 ServiceAccount 的特殊管理
- Docker 镜像拉取: 如果使用
imagePullSecrets,通常不需要给 ServiceAccount 额外权限(权限在 Secret 中)。 - 自动化工具(如 Helm、ArgoCD): 为每个应用或每个环境独立创建 ServiceAccount,不要共享一个“万能” Account。
- 自动挂载: 对于不需要与 API Server 通信的 Pod,显式设置
automountServiceAccountToken: false。
定期审计与自动化
- 工具:
kubectl describe clusterrolebinding <name>:查看谁拥有什么权限。- 通用工具:
kubectl audit(Beta 功能)、kubectl rbac-lookup(第三方)或kubectl neat导出资源。 - 策略引擎: OPA(Open Policy Agent)或 Kyverno,可以强制要求 RBAC 必须遵循最小权限(禁止使用通配符动词)。
实际示例:给 CI/CD 工具(如 Jenkins)最小权限
目标: 允许在 namespace app-team 中创建 Deployment、管理 Pod,但不能删除资源或修改 Secret。
创建 Role:
apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: namespace: app-team name: deployer rules: # 管理 Deployment - apiGroups: [“apps”] resources: [“deployments”, “deployments/scale”] verbs: [“get”, “list”, “watch”, “update”, “patch”] # 没有 delete 和 create(除非需要) # 查看 Pod 状态和日志(便于调试) - apiGroups: [“”] resources: [“pods”, “pods/log”] verbs: [“get”, “list”, “watch”] # 允许更新 Service(但最好不要创建) - apiGroups: [“”] resources: [“services”] verbs: [“get”, “list”, “watch”, “update”, “patch”] # **没有 secrets 权限** - Jenkins 需要读取 Secret,使用 Volume 挂载或通过其他更安全的方式
绑定 ServiceAccount:
apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: jenkins-deployer namespace: app-team roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: deployer subjects: - kind: ServiceAccount name: jenkins-sa namespace: app-team
总结核心检查清单
| 检查项 | 行为 | 理由 |
|---|---|---|
| 1 | 避免 verbs: [“*”] |
你是业务组件,不是管理员。 |
| 2 | 避免 apiGroups: [“*”] |
不需要接触 autoscaling, batch 或 networking。 |
| 3 | 避免 resources: [“*”] |
不需要影响 Secrets, Endpoints 或 Events。 |
| 4 | 必须显式定义 namespaced 的 Role |
永远优先用 Role 而不是 ClusterRole。 |
| 5 | 针对敏感资源 | 对 Secret, ConfigMap 的 delete 和 create 需特别审批。 |
| 6 | 定期审计 | 使用 kubectl describe role <role> 查看实际权限。 |
按这套方法实施,可以显著降低因 RBAC 配置不当导致的安全风险(如 Pod 被创建恶意容器、Secret 泄露、或横向移动权限提升)。