RBAC 的两个对象
RBAC 把授权拆成两半:角色声明「可以对哪些资源做哪些动作」,绑定把角色授予主体(用户、用户组或 ServiceAccount)。Role 与 RoleBinding 是命名空间级的,ClusterRole 是集群级的;RoleBinding 也能引用 ClusterRole,这样就能把一个集群级角色限制在单个命名空间内生效。授权结果是「允许」的并集,没有拒绝规则,因此排查权限问题的关键是找出到底哪条绑定授予了它。
四类对象对照
| 对象 | 作用范围 | 常见用法 |
|---|---|---|
| Role | 命名空间 | 授予本命名空间内资源的读写权限 |
| RoleBinding | 命名空间 | 把 Role 或 ClusterRole 授予命名空间内的主体 |
| ClusterRole | 集群 | 定义可复用的权限集合,或授予集群级资源权限 |
| ClusterRoleBinding | 集群 | 把权限授予主体,作用于全部命名空间 |
典型使用场景
- 应用只读访问:给 ServiceAccount 授予 pods 与 pods/log 的 get、list、watch,够用即可
- 平台组件:监控、日志采集需要跨命名空间读取,用 ClusterRole 加 ClusterRoleBinding 集中授权
- 团队隔离:每个团队一个命名空间,只在本命名空间内绑定角色,避免越界
- 复用权限定义:把常用权限收敛成 ClusterRole,再用 RoleBinding 逐命名空间授予
- 权限审计:定期列出各主体的绑定关系与规则,找出范围过宽的授权
只读 Role 与绑定
只读 Role 与绑定
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: prod
name: pod-reader
rules:
- apiGroups: [''] # 空字符串表示核心 API 组
resources: ['pods', 'pods/log']
verbs: ['get', 'list', 'watch']
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
namespace: prod
name: read-pods
subjects:
- kind: ServiceAccount
name: app-sa
namespace: prod
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io验证授权是否生效
验证授权是否生效
kubectl auth can-i list pods --as=system:serviceaccount:prod:app-sa -n prod
kubectl auth can-i --list --as=system:serviceaccount:prod:app-sa -n prod # 列出该身份的全部规则
kubectl get role,rolebinding -n prod -o wide # 命名空间内的角色与绑定
kubectl get clusterrolebinding -o wide | grep -i app-sa # 是否存在范围过宽的集群绑定规则字段读法
| 字段 | 含义 | 注意 |
|---|---|---|
| apiGroups | 资源所属 API 组 | 核心组写空字符串,写错会导致规则不匹配 |
| resources | 资源名,可带子资源 | pods/log 这类子资源要单独列出 |
| verbs | 允许的动作 | get、list、watch 与 create、update、delete 需分别声明 |
| resourceNames | 限定具体对象名 | 只能用于 get、update、delete 等少量动词 |
| roleRef | 绑定的角色引用 | 创建后不可修改,换角色只能重建绑定 |
Subresource 是常见遗漏:读日志要 pods/log,看指标要看对应的自定义资源,进入容器要 pods/exec,端口转发要 pods/portforward。只给 pods 的权限时,这些操作仍会报 403。
roleRef 在绑定创建后不可修改,属于设计约束。需要更换角色时只能删除并重建绑定,期间权限会短暂中断,建议在变更窗口内进行并提前验证新角色的权限集合。