K8s RBAC 进阶避坑指南(下集)
K8s RBAC 进阶避坑指南(下集)
上集搞懂了四个核心概念,中集手把手搭建了开发组 + 运维组权限体系。这一集收尾:进阶要点、6 条排坑经验、落地清单——把 RBAC 的最后一公里走完。
一、进阶要点
1. 最小权限原则:从 deny 到 allow
K8s RBAC 是白名单模式——默认拒绝一切,只有显式授权才能操作。这意味着你不需要写"拒绝规则",只需要写"允许规则"。
正确做法:
# ✅ 精确指定 apiGroups、resources、verbs
rules:
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get"]
resourceNames: ["app-config"] # 甚至精确到某个 ConfigMap!
错误做法:
# ❌ 通配符——等于没做权限管控
rules:
- apiGroups: ["*"]
resources: ["*"]
verbs: ["*"]
2. 聚合 ClusterRole:自动继承
2.1 先认识四个内置 ClusterRole
K8s 装好就自带四个 ClusterRole,生产环境直接引用,不用自己写:
| 角色 | 权限范围 | 不能做 | 典型用途 |
|---|---|---|---|
view |
只读(get/list/watch),不含 Secret | create/update/delete、读 Secret | 开发人员日常查看 |
edit |
读写,但不能改 RBAC、不能读 Secret | 修改 Role/RoleBinding/Secret | 开发人员日常部署 |
admin |
命名空间内完全控制(含 RBAC Binding) | 跨命名空间操作 | 命名空间管理员 |
cluster-admin |
全集群超级权限 | 无 | 平台运维团队 |
注意:
view和edit都不能读 Secret,这是刻意的——防止开发人员通过只读权限拿到数据库密码、API Key 等敏感信息。
view 能访问的核心资源(只读):
✅ Pods、Deployments、Services、ConfigMaps
ReplicaSets、DaemonSets、StatefulSets
Ingress、PVC、Nodes(只读)
Events、Endpoints、ServiceAccounts(只读)
❌ Secrets(即使是只读也不行)
❌ 任何资源的 create/update/delete
验证某个角色包含什么权限:
kubectl describe clusterrole view # 查看 view 的所有 rules
kubectl describe clusterrole edit # 查看 edit 的所有 rules


2.2 聚合机制:给内置角色"追加"权限
场景:公司部署了一个 CRD 叫 myresources,所有开发人员(已绑定 view)也应该能 get/list 它。但开发人员有几十个,不可能每人都加一条 Binding。
解决方法:创建一个带聚合标签的 ClusterRole,K8s 自动把它的 rules 合并进目标角色:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: myresources-view
labels:
rbac.authorization.k8s.io/aggregate-to-view: "true" # ← 这个标签是关键
rules:
- apiGroups: ["example.com"]
resources: ["myresources"]
verbs: ["get", "list", "watch"]
kubectl apply 之后,所有已经绑定了 view 的用户,不需要任何 Binding 变更,立刻自动获得 myresources 的只读权限。
三个支持聚合的内置角色,对应标签如下:
| 目标角色 | 聚合标签 |
|---|---|
view |
aggregate-to-view: "true" |
edit |
aggregate-to-edit: "true" |
admin |
aggregate-to-admin: "true" |
什么时候用:部署了 CRD(Operator、自定义资源)之后,用聚合 ClusterRole 统一给现有角色补权限,比批量修改 Binding 效率高得多。
2.3 ⚠️ ClusterRole ≠ 全集群权限
很多人以为 ClusterRole 一定能访问全集群,这是错的。ClusterRole 只是「权限规则的定义」,实际范围由 Binding 决定:
| 绑定方式 | 效果 |
|---|---|
ClusterRoleBinding + ClusterRole |
✅ 全集群生效 |
RoleBinding(某命名空间)+ ClusterRole |
✅ 只在这一个命名空间生效 |
# 场景:zhangsan 只能在 dev 命名空间只读
# 用的是 ClusterRole view,但绑定方式是 RoleBinding(只在 dev)
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding # ← RoleBinding,不是 ClusterRoleBinding
metadata:
name: zhangsan-view
namespace: dev # ← 只在 dev 这个命名空间
subjects:
- kind: User
name: zhangsan
roleRef:
kind: ClusterRole
name: view # ← 引用 ClusterRole,但范围被 RoleBinding 限制住了
为什么这么设计:ClusterRole 的规则写一次,可以在多个命名空间复用。比如
dev和staging都要开发组只读,写一个 ClusterRole,然后在两个命名空间各建一个 RoleBinding 引用它,规则不用维护两份。
3. 安全审计:定期巡检 + 权限验证
RBAC 不是配完就不管了——权限会随着人员流动、项目变更逐渐腐化。养成定期审计的习惯:
# === 巡检 1:找出所有 cluster-admin 绑定的用户 ===
kubectl get clusterrolebinding -o json | \
jq '.items[] | select(.roleRef.name=="cluster-admin") | .subjects[]'
# === 巡检 2:检查谁有 delete 权限(高风险管理) ===
kubectl get clusterroles --all-namespaces -o json | \
jq '.items[] | select(.rules[].verbs[] | contains("delete")) | .metadata.name'
# === 巡检 3:验证某个用户的真实权限 ===
kubectl auth can-i delete pods --as=lisi -n default
kubectl auth can-i create namespaces --as=lisi
# === 巡检 4:列出某个 ClusterRole 的完整规则 ===
kubectl describe clusterrole system:aggregate-to-admin
# === 巡检 5:删除高风险绑定(如意外公开的只读绑定) ===
kubectl delete clusterrolebinding dangerous-public-binding
建议:把巡检命令写成 CronJob 或用 kubectl-who-can 这类工具自动扫描,发现异常权限绑定发告警。
4. apiGroups 填错导致权限无效
这是最常见的排错场景——权限配了但不生效,99% 是因为 apiGroups 写错了:
注意:resources 字段必须写资源的全称,不能用缩写。比如
deployments不能写成deploy,services不能写成svc。
| 资源类型 | 正确的 apiGroup |
|---|---|
| Pod、Service、ConfigMap、Secret | ""(核心组,空字符串) |
| Deployment、StatefulSet、DaemonSet | apps |
| Ingress | networking.k8s.io |
| HPA | autoscaling |
| RBAC 自身(Role、RoleBinding) | rbac.authorization.k8s.io |
| CRD 自定义资源 | 看 CRD 定义里的 spec.group |
# 不知道一个资源的 apiGroup?用这个查
kubectl api-resources | grep -i deployment
# deployments apps/v1 true Deployment
# ↑ 这就是 apiGroup

二、RBAC 排坑指南
1. 配了权限不生效?先查这三项
# 1. 检查 Binding 是否正确绑定
kubectl get rolebinding -n prod log-collector -o yaml
# 2. 检查 Role 规则是否正确
kubectl describe role log-reader -n prod
# 3. 用 can-i 模拟验证
kubectl auth can-i get pods -n prod \
--as system:serviceaccount:prod:log-collector
kubectl auth can-i create pods -n prod \
--as system:serviceaccount:prod:log-collector


2. ServiceAccount 的 namespace 要跟 Binding 一致
# ❌ 错误:SA 在 prod,Binding 在 staging
subjects:
- kind: ServiceAccount
name: log-collector
namespace: prod # ← SA 所在 namespace
# RoleBinding 在 staging namespace → 这个 SA 读不到 staging 的资源

规则:ServiceAccount 只能通过自己 namespace 下的 RoleBinding 获取权限。如果你要跨 namespace 授权,用 ClusterRole + ClusterRoleBinding。
3. 忘记给 list 但给了 watch
kubectl get pods 同时需要 list + watch 权限——很多 Controller 只给了 watch 忘了 list,导致启动失败。
4. kubectl 子命令的权限要求
# kubectl exec → 需要 pods/exec 子资源权限
rules:
- apiGroups: [""]
resources: ["pods/exec"]
verbs: ["create"]
# kubectl logs → 需要 pods/log 子资源权限
rules:
- apiGroups: [""]
resources: ["pods/log"]
verbs: ["get"]
5. --as 不携带 Group,验证 Group 权限要用 KUBECONFIG
# ❌ 错误——只模拟了 User "lisi",没带上证书里的 Group "ops-team"
kubectl auth can-i get pods -n prod --as lisi # → no
# ✅ 正确——用 lisi 自己的 kubeconfig(CN + O 都在)
KUBECONFIG=lisi.kubeconfig kubectl auth can-i get pods -n prod # → yes
# ✅ 或者显式指定 --as-group
kubectl auth can-i get pods -n prod --as lisi --as-group ops-team # → yes

6. 用 describe 而不是 get 排查 RBAC
# kubectl describe 会自动展示 RBAC 的绑定关系和规则
kubectl describe clusterrole read-only

三、总结
1. RBAC三元组
RBAC 的核心就一个三元组:身份(谁)× 权限(能做什么)× 绑定(怎么关联)。
| 需要做的事 | 用什么 | 示例 |
|---|---|---|
| 给人(开发)分配权限 | User + RoleBinding + Role | 开发在 dev ns 只读 |
| 给 Pod 分配权限 | ServiceAccount + RoleBinding + Role | CI/CD 部署更新 Deployment |
| 给 Pod 全集群权限 | ServiceAccount + ClusterRoleBinding + ClusterRole | 日志采集读全集群 Pod |
| 给一组人统一权限 | Group + RoleBinding + Role | dev-team 组在 staging ns 只读 |
| 复用权限规则到多个 ns | RoleBinding + ClusterRole | 只读规则复用到 dev/staging/prod |
| 限制单个资源 | resourceNames 字段 | 只允许读 app-config 这个 ConfigMap |
2. 落地清单:
- 所有 Namespace 禁用
defaultServiceAccount(或不给它任何权限) - CI/CD 用的 ServiceAccount 只给必要的 verbs(不给
*/delete除非确实需要) - 开发人员通过 Group 分配权限,不要逐个 User 绑定
apiGroups填对——核心资源"",apps 组apps- resources 写全称不能缩写——
deployments不是deploy,services不是svc - 上线前用
kubectl auth can-i --list验证 SA 权限 - 不要创建
subjects: [{kind: ServiceAccount, name: default}]— 这是给所有 Pod 的 - 用
kubectl describe role/clusterrole排查,比get -o yaml直观得多 - 定期安全巡检:扫描 cluster-admin 绑定、delete 权限、异常公开绑定
记住这个等式:RBAC = Subject(谁)+ Role(能做啥)+ Binding(绑在一起)。搞混四个概念就回来看上集那张图。
更多推荐
所有评论(0)