K8sRBAC最小权限-4类授权检查

当集群权限越用越乱,K8sRBAC最小权限问题常藏在跨命名空间绑定、默认ServiceAccount和通配符动词里。本篇用检查清单梳理核对路径,帮助你判断哪些授权需要收敛、哪些变更应先验证。

本文定位:面向平台团队和安全审计场景,按K8sRBAC最小权限的对象关系、授权范围和收敛顺序给出可核对的检查路径。

K8sRBAC最小权限不是把所有权限都删到最少,而是让每个Role、Binding和ServiceAccount都能解释“谁在什么范围内做什么操作”。在生产集群里,权限过宽往往不是一次配置错误,而是多次临时授权、跨命名空间复用和自动化账号沉淀后的结果。下面先用4类检查建立对象关系,再按命令和风险信号逐项收敛。

K8sRBAC最小权限先看这4类对象关系

RBAC检查要先把对象关系理清:权限规则定义在Role或ClusterRole里,授权关系落在RoleBinding或ClusterRoleBinding里,真正被工作负载使用的身份通常是ServiceAccount。如果只检查其中一个对象,很容易遗漏“权限定义没问题,但绑定范围过大”的情况。

K8sRBAC最小权限的Role、Binding和ServiceAccount检查关系图

图1:K8sRBAC最小权限检查对象关系

建议先按这个顺序看:

  1. Role和ClusterRole:确认规则授予了哪些资源、动词和API组。
  2. RoleBinding和ClusterRoleBinding:确认权限绑定给了谁、作用在哪个命名空间或集群范围。
  3. ServiceAccount:确认工作负载是否复用默认账号或共享账号。
  4. 危险动词和通配符:确认是否出现`*`、`create pods/exec`、`bind`、`escalate`等高风险授权。

如果你的集群正在做安全基线建设,RBAC只是其中一层。更完整的镜像、网络、供应链和运行时治理,可以继续参考 云原生安全专题 中的相关内容。

第一类检查:Role和ClusterRole范围是否过大

Role通常作用于单个命名空间,ClusterRole可以作用于集群级资源,也可以被绑定到多个命名空间。最小权限检查的第一步,是确认“集群级权限是否真的需要集群级范围”。

可以先列出集群内的ClusterRole,并关注自定义角色和被业务账号使用的角色:

kubectl get clusterrole
kubectl get role -A
kubectl describe clusterrole <clusterrole-name>
kubectl describe role <role-name> -n <namespace>

重点看三类字段:

  • `resources`:是否包含`pods`、`secrets`、`configmaps`、`nodes`、`roles`、`clusterroles`等敏感对象。
  • `verbs`:是否出现`*`、`create`、`update`、`patch`、`delete`、`impersonate`、`bind`、`escalate`等高风险动作。
  • `apiGroups`:是否把多个API组混在同一个角色里,导致角色职责不清。

一个常见问题是把只读查询、发布变更和权限管理放进同一个ClusterRole。短期看配置方便,长期会让审计变困难:当某个ServiceAccount出问题时,你无法判断它到底是为了读取日志、滚动发布,还是为了管理权限而获得这些动词。

角色边界要按职责拆开

如果某个角色同时拥有只读、变更和权限管理能力,建议先拆成多个职责更清晰的角色。例如只读观察者只保留`get`、`list`、`watch`,发布账号只保留特定资源的`create`、`update`、`patch`,权限管理账号则单独纳入审批和审计。

下面是一个更容易审计的命名空间只读Role示例:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: workload-readonly
  namespace: app-prod
rules:
  - apiGroups: [""]
    resources: ["pods", "services", "configmaps"]
    verbs: ["get", "list", "watch"]
  - apiGroups: ["apps"]
    resources: ["deployments", "replicasets"]
    verbs: ["get", "list", "watch"]

这个示例不代表所有生产环境都应照抄,而是展示一个原则:权限规则应围绕明确职责组织,不把未来可能用到的动作提前放进去。

第二类检查:Binding是否把权限给错对象

RoleBinding和ClusterRoleBinding决定权限最终落到谁身上。很多RBAC问题不是角色本身过宽,而是绑定对象过多、绑定范围过大,或者把临时账号留在了生产环境。

可以用下面命令先建立绑定清单:

kubectl get rolebinding -A
kubectl get clusterrolebinding
kubectl describe rolebinding <binding-name> -n <namespace>
kubectl describe clusterrolebinding <binding-name>

检查时要重点看`subjects`和`roleRef`。`subjects`里可能是User、Group或ServiceAccount,`roleRef`则指向Role或ClusterRole。两者组合起来,才是真正的授权事实。

检查项 风险信号 建议处理
ClusterRoleBinding 普通业务账号绑定到集群级管理员角色 改为命名空间RoleBinding,或拆出更小ClusterRole
Group绑定 大范围用户组绑定到变更权限 缩小用户组,区分只读、发布、运维角色
临时账号 排障账号长期保留高权限 设置回收流程,记录到变更审计
roleRef复用 多个命名空间共用同一宽权限角色 拆分角色职责,按命名空间逐步收敛

绑定范围比对象数量更重要

不要只看Binding数量。一个ClusterRoleBinding可能比十几个命名空间RoleBinding风险更高,因为它把权限直接提升到集群范围。相反,多个命名空间RoleBinding如果职责清楚、对象明确,反而更便于审计和回收。

对于平台团队来说,RBAC检查应纳入日常的K8s平台运维基线,而不是只在安全审计前临时处理。更多Kubernetes平台运行与治理内容,可以从 K8s容器 分类继续延伸阅读。

第三类检查:ServiceAccount是否被复用过度

ServiceAccount是工作负载实际使用RBAC权限的常见身份。权限收敛时,最容易被忽略的是“多个应用共用同一个ServiceAccount”,尤其是默认ServiceAccount被长期复用。

可以先检查工作负载使用的ServiceAccount:

kubectl get deploy,statefulset,daemonset -A -o custom-columns='NAMESPACE:.metadata.namespace,NAME:.metadata.name,SA:.spec.template.spec.serviceAccountName'
kubectl get serviceaccount -A
kubectl describe serviceaccount <serviceaccount-name> -n <namespace>

如果`serviceAccountName`为空,很多工作负载会使用命名空间下的`default`账号。默认账号本身不一定危险,危险在于团队可能后来给它绑定了权限,导致所有未显式指定账号的工作负载一起获得授权。

需要优先核对这些情况:

  • 多个高低敏感度不同的应用共用同一个ServiceAccount。
  • 默认ServiceAccount被绑定到Role或ClusterRole。
  • CI/CD、Job、CronJob和长期在线服务使用同一个账号。
  • 一个ServiceAccount同时拥有读取Secret、变更Deployment和访问多命名空间资源的能力。

账号拆分要跟工作负载生命周期匹配

ServiceAccount不要按团队或命名空间粗粒度复用,而应尽量按工作负载职责拆分。在线服务、定时任务、部署流水线、控制器和排障账号的生命周期不同,权限回收方式也不同。

例如发布流水线可能需要更新Deployment,但业务Pod运行时并不一定需要这类权限。把两者共用一个账号,会让运行时权限长期超过实际需要。

第四类检查:危险动词和通配符是否可解释

RBAC规则里的危险动词并不一定都要删除,但每一项都需要有明确使用场景、审批来源和验证方式。最小权限关注的是“权限能否解释”,而不是机械地禁止所有高权限动作。

可以用审计命令先筛选敏感规则:

kubectl get clusterrole -o yaml | grep -E 'verbs:|resources:|*|escalate|bind|impersonate'
kubectl get role -A -o yaml | grep -E 'verbs:|resources:|*|secrets|pods/exec'

在人工复核时,尤其要关注这些组合:

  • `resources: ["*"]`配合`verbs: ["*"]`。
  • 对`secrets`拥有`get`、`list`或`watch`。
  • 对`pods/exec`、`pods/attach`拥有`create`。
  • 对RBAC对象拥有`bind`、`escalate`、`update`或`patch`。
  • 对`nodes`、`persistentvolumes`等集群级资源拥有写权限。

K8sRBAC权限过宽的4类授权检查清单

图2:RBAC权限过宽的4类检查清单

危险权限要有例外记录

如果某个控制器确实需要较高权限,建议把例外写清楚:用途是什么、绑定给哪个ServiceAccount、涉及哪些命名空间、谁批准、多久复核一次。没有例外记录的高权限角色,应该进入收敛队列。

收敛顺序:先止住新增,再处理历史授权

权限收敛不建议一次性大规模删除。更稳妥的做法是先控制新增,再处理高风险历史授权,最后建立持续检查机制。

  1. 建立当前授权基线,导出Role、ClusterRole、Binding和ServiceAccount清单。
  2. 先冻结新的通配符权限、集群级管理员绑定和默认ServiceAccount授权。
  3. 从生产命名空间、高权限账号、跨命名空间绑定开始收敛。
  4. 对每次收敛设置验证窗口,观察应用是否出现权限拒绝事件。
  5. 把例外授权纳入周期复核,而不是长期默认放行。

生产环境中,最小权限回收要和业务验证一起做。直接删除看似明显过宽的权限,可能导致控制器、运维脚本或发布流水线在下一次执行时失败。建议先在低风险命名空间验证,再逐步扩大范围。

小结

K8sRBAC最小权限检查可以从4类对象入手:Role/ClusterRole定义权限范围,Binding决定权限给谁,ServiceAccount体现工作负载身份,危险动词和通配符暴露高风险边界。真正有效的权限治理不是一次性删权限,而是让每个授权都能被解释、被验证、被复核。

如果只能先做一件事,建议优先检查ClusterRoleBinding、默认ServiceAccount绑定和`*`通配符规则。这三类问题最容易把局部权限扩大为集群级风险,也最适合作为平台安全基线的起点。

常见问题

1. K8sRBAC最小权限是不是权限越少越好?

不是。最小权限的重点是权限与职责匹配,而不是盲目减少权限。一个控制器可能确实需要较高权限,但它应该绑定到明确的ServiceAccount,并有用途说明、审批来源和复核周期。没有业务解释的权限,才是优先收敛对象。

2. Role和ClusterRole应该怎么选?

如果权限只作用于单个命名空间,优先使用Role;如果需要访问节点、PV、Namespace等集群级资源,或同一套规则要被多个命名空间复用,再考虑ClusterRole。即使使用ClusterRole,也可以通过RoleBinding把它限制在某个命名空间使用。

3. 为什么默认ServiceAccount会成为风险点?

默认ServiceAccount常被忽略,因为很多工作负载没有显式指定`serviceAccountName`。一旦默认账号被绑定了宽权限,同一命名空间里未显式指定账号的Pod都可能获得这些权限。因此生产工作负载建议显式指定专用ServiceAccount。

4. 收敛RBAC权限时如何降低业务影响?

建议先做只读审计和基线导出,再按命名空间、账号和角色分批收敛。每次变更后观察应用日志、事件和发布流水线结果。如果出现权限拒绝,不要直接恢复大权限,而要确认缺失的资源和动词,再补最小范围的规则。

原创声明:本文为 CNBPA 云原生社区原创技术内容,非商业转载须注明出处:https://www.cloudnative-tech.com/p/9734/。文中原创图示、架构图和文章内容未经许可不得用于商业转载、培训课件、营销材料或二次分发。
(0)
上一篇 3小时前
下一篇 2026年5月12日 下午1:59

相关推荐