前言
Kubernetes RBAC(基于角色的访问控制)是集群安全的核心机制。本文通过”剧场模型”和”公司架构”两个类比,深入剖析 RBAC 的设计逻辑和实现原理。
一、RBAC 的核心模型:剧场类比
1.1 三要素关系
在 RBAC 中,权限控制由三个核心要素构成:
1 2 3
| 角色(Role/ClusterRole)= 剧本(定义可执行的操作) 绑定(RoleBinding/ClusterRoleBinding)= 选角(建立身份与角色的映射) 主体(User/ServiceAccount)= 演员(实际执行操作的身份)
|
设计哲学:
- 角色与身份分离:剧本(Role)独立于演员(Subject),实现权限复用
- 声明式授权:通过绑定(Binding)声明”谁拥有什么权限”
- 最小权限原则:精细化定义每个角色的操作范围
1.2 权限授予的完整链路
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: operator namespace: production rules: - apiGroups: [""] resources: ["pods", "pods/log"] verbs: ["get", "list", "delete"]
---
apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: zhang-san-operator namespace: production subjects: - kind: User name: zhang-san roleRef: kind: Role name: operator
|
请求处理流程:
1 2 3 4 5 6 7 8 9 10 11
| 张三执行: kubectl delete pod my-app -n production ↓ API Server 认证: 证书CN=zhang-san ↓ RBAC 授权引擎: 1. 查找 subjects 包含 "zhang-san" 的所有 Binding 2. 找到 zhang-san-operator (namespace: production) 3. 解析绑定的 Role: operator 4. 检查 rules: delete pods ✅ ↓ 执行操作
|
二、权限边界:公司架构类比
2.1 多维度权限隔离
将 Kubernetes 集群类比为企业组织:
1 2 3 4 5 6 7 8 9 10 11 12 13
| 集群(公司) ├── Namespace(部门) │ ├── dev(研发部) │ ├── test(测试部) │ └── production(运维部) │ ├── Role(岗位职责) │ ├── developer(只能部署,不能删除) │ └── operator(可以重启服务) │ └── RoleBinding(任命书) ├── 张三 → dev 部门的 developer └── 李四 → production 部门的 operator
|
2.2 权限的三个维度
| 维度 |
实现方式 |
作用 |
| 权限划分 |
Role/ClusterRole 的 rules |
定义操作范围(增删改查) |
| 空间隔离 |
Namespace + RoleBinding |
限制可访问的资源范围 |
| 级别控制 |
Role vs ClusterRole |
区分部门权限和公司权限 |
实例:
1 2 3 4 5 6 7 8 9 10 11 12
| apiVersion: rbac. authorization.k8s.io/v1 kind: RoleBinding metadata: name: dev-team namespace: dev subjects: - kind: Group name: developers roleRef: kind: Role name: app-deployer
|
三、角色复用与组合:四种授权模式
3.1 授权模式矩阵
| 模式 |
角色类型 |
绑定类型 |
权限范围 |
典型场景 |
| 模式1 |
Role |
RoleBinding |
单命名空间 |
开发者在特定项目 |
| 模式2 |
ClusterRole |
RoleBinding |
单命名空间(复用角色) |
多项目使用统一权限模板 |
| 模式3 |
ClusterRole |
ClusterRoleBinding |
全集群 |
集群管理员、监控系统 |
| 模式4 |
Role |
ClusterRoleBinding |
❌ 不支持 |
- |
3.2 模式2详解:角色复用
业务场景:10个项目都需要”只读Pod”权限,避免重复定义10次Role
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: pod-reader-template rules: - apiGroups: [""] resources: ["pods"] verbs: ["get", "list"]
---
apiVersion: rbac.authorization. k8s.io/v1 kind: RoleBinding metadata: name: project-a-readers namespace: project-a subjects: - kind: User name: alice roleRef: kind: ClusterRole name: pod-reader-template
---
apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: project-b-readers namespace: project-b subjects: - kind: User name: bob roleRef: kind: ClusterRole name: pod-reader-template
|
优势:
- 一处定义,多处使用
- 统一权限管理(修改 ClusterRole 影响所有绑定)
- alice 和 bob 权限相同,但范围隔离
四、双重身份系统:User vs ServiceAccount
4.1 设计分层
Kubernetes 设计了两种完全独立的身份体系:
1 2 3 4 5 6 7 8 9 10 11 12
| ┌─────────────────────┐ ┌──────────────────────┐ │ User(人类用户) │ │ ServiceAccount(程序)│ ├─────────────────────┤ ├──────────────────────┤ │ 不存储在K8s中 │ │ 存储为K8s资源 │ │ 外部认证(证书/OIDC)│ │ 自动生成Token │ │ kubectl操作集群 │ │ Pod内程序调用API │ └─────────────────────┘ └──────────────────────┘ │ │ └──────────┬───────────────────┘ ▼ RoleBinding. subjects (统一授权入口)
|
4.2 User 的认证与授权分离
认证阶段(集群外部):
1 2 3 4
| openssl req -new -key user.key -out user.csr -subj "/CN=zhang-san/O=developers"
|
授权阶段(集群内部):
1 2 3 4 5
| apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding subjects: - kind: User name: zhang-san
|
关键理解:
- User 的身份由外部系统提供(CA证书、OIDC、LDAP)
- RoleBinding 中的
name: zhang-san 是字符串匹配,不是对象引用
- 认证通过后,RBAC 仅关心用户名和组名
4.3 ServiceAccount 的生命周期
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| apiVersion: v1 kind: ServiceAccount metadata: name: app-backend namespace: production
---
apiVersion: rbac.authorization. k8s.io/v1 kind: RoleBinding subjects: - kind: ServiceAccount name: app-backend namespace: production roleRef: kind: Role name: db-accessor
---
apiVersion: v1 kind: Pod spec: serviceAccountName: app-backend containers: - name: backend
|
Token 使用示例:
1 2 3 4 5 6 7
| TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
curl -H "Authorization: Bearer $TOKEN" \ --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt \ https://kubernetes.default.svc/api/v1/namespaces/production/pods
|
五、权限计算引擎:RBAC 授权算法
5.1 请求处理流程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| ┌──────────────────┐ │ 1. 认证阶段 │ │ 提取身份信息: │ │ - 用户名 │ │ - 用户组 │ │ - ServiceAccount │ └────────┬─────────┘ │ ▼ ┌──────────────────────────────┐ │ 2. 授权阶段(RBAC) │ │ 遍历所有 RoleBinding/ │ │ ClusterRoleBinding: │ │ │ │ FOR EACH Binding: │ │ IF subjects匹配当前身份: │ │ 解析 roleRef │ │ FOR EACH rule IN Role: │ │ IF 资源+动作匹配请求: │ │ ✅ 允许 │ │ RETURN │ │ │ │ ❌ 拒绝(未找到匹配规则) │ └──────────────────────────────┘
|
5.2 权限叠加规则
只有允许,没有拒绝:
- RBAC 是白名单模式(默认拒绝所有)
- 多个 RoleBinding 的权限叠加(取并集)
- 不支持显式拒绝(与 AWS IAM 不同)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
|
apiVersion: rbac.authorization. k8s.io/v1 kind: RoleBinding metadata: name: zhang-san-reader subjects: - kind: User name: zhang-san roleRef: kind: Role name: pod-reader
---
apiVersion: rbac.authorization.k8s. io/v1 kind: RoleBinding metadata: name: zhang-san-operator subjects: - kind: User name: zhang-san roleRef: kind: Role name: pod-deleter
|
5.3 命名空间边界
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
|
apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: dev-admin namespace: dev subjects: - kind: User name: zhang-san roleRef: kind: ClusterRole name: admin
---
apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: prod-viewer namespace: production subjects: - kind: User name: zhang-san roleRef: kind: ClusterRole name: view
|
权限结果:
1 2 3
| kubectl delete pod xxx -n dev kubectl delete pod xxx -n production kubectl get pods -n test
|
六、实战模式:典型权限架构
6.1 多租户隔离架构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| apiVersion: v1 kind: Namespace metadata: name: tenant-a
---
apiVersion: rbac.authorization. k8s.io/v1 kind: RoleBinding metadata: name: tenant-a-admin namespace: tenant-a subjects: - kind: Group name: tenant-a-admins roleRef: kind: ClusterRole name: admin
---
apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: tenant-a-developer namespace: tenant-a rules: - apiGroups: ["", "apps"] resources: ["pods", "deployments", "services"] verbs: ["get", "list", "create", "update"] - apiGroups: [""] resources: ["pods/log", "pods/exec"] verbs: ["get"]
--- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: tenant-a-devs namespace: tenant-a subjects: - kind: Group name: tenant-a-developers roleRef: kind: Role name: tenant-a-developer
|
6.2 CI/CD 权限最小化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| apiVersion: v1 kind: ServiceAccount metadata: name: gitlab-ci namespace: ci-system
--- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: deployer rules: - apiGroups: ["apps"] resources: ["deployments"] verbs: ["get", "list", "create", "update", "patch"] - apiGroups: [""] resources: ["services", "configmaps"] verbs: ["get", "list", "create", "update"] - apiGroups: [""] resources: ["pods"] verbs: ["get", "list"]
---
apiVersion: rbac. authorization.k8s.io/v1 kind: RoleBinding metadata: name: ci-deploy-project-a namespace: project-a subjects: - kind: ServiceAccount name: gitlab-ci namespace: ci-system roleRef: kind: ClusterRole name: deployer
|
6.3 监控系统只读权限
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| apiVersion: v1 kind: ServiceAccount metadata: name: prometheus namespace: monitoring
--- apiVersion: rbac.authorization. k8s.io/v1 kind: ClusterRole metadata: name: prometheus-reader rules: - apiGroups: [""] resources: ["nodes", "nodes/metrics", "pods", "services", "endpoints"] verbs: ["get", "list", "watch"] - nonResourceURLs: ["/metrics", "/metrics/cadvisor"] verbs: ["get"]
--- apiVersion: rbac. authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: prometheus-global subjects: - kind: ServiceAccount name: prometheus namespace: monitoring roleRef: kind: ClusterRole name: prometheus-reader
|
七、安全最佳实践
7.1 权限设计原则
- 最小权限原则:只授予完成任务的最小权限集
- 命名空间隔离:不同环境/租户使用独立命名空间
- 禁用 default SA:为每个应用创建专用 ServiceAccount
- 定期审计:检查过度授权和长期未使用的权限
7.2 危险权限清单
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
|
rules: - apiGroups: ["*"] resources: ["*"] verbs: ["*"]
rules: - apiGroups: ["rbac.authorization.k8s. io"] resources: ["roles", "rolebindings"] verbs: ["create", "update"]
rules: - apiGroups: [""] resources: ["pods"] verbs: ["create"] - apiGroups: ["policy"] resources: ["podsecuritypolicies"] verbs: ["use"] resourceNames: ["privileged"]
rules: - apiGroups: [""] resources: ["secrets"] verbs: ["get", "list"]
|
7.3 权限审计命令
1 2 3 4 5 6 7 8 9 10
| kubectl auth can-i --list --as=zhang-san -n production
kubectl get rolebindings,clusterrolebindings --all-namespaces -o json | \ jq -r '.items[] | select(.roleRef.name=="cluster-admin") | .metadata.name'
kubectl auth can-i delete pods \ --as=system:serviceaccount:default:my-app -n production
|
八、总结
核心概念关系图
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| ┌─────────────────────────────────────────────────┐ │ Kubernetes 集群 │ │ │ │ ┌──────────────┐ ┌──────────────┐ │ │ │ Namespace A │ │ Namespace B │ │ │ │ │ │ │ │ │ │ ┌────────┐ │ │ ┌────────┐ │ │ │ │ │ Role │ │ │ │ Role │ │ │ │ │ └───┬────┘ │ │ └───┬────┘ │ │ │ │ │ │ │ │ │ │ │ │ ┌───▼──────┐│ │ ┌───▼──────┐│ │ │ │ │RoleBinding││ │ │RoleBinding││ │ │ │ └───┬───────┘ │ └───┬───────┘ │ │ └──────┼──────┘ └──────┼──────┘ │ │ │ │ │ │ ┌──────▼──────────────────────▼──────┐ │ │ │ ClusterRole (全局权限模板) │ │ │ └──────┬──────────────────────┬──────┘ │ │ │ │ │ │ ┌──────▼─────────┐ ┌───────▼──────────┐ │ │ │ClusterRoleBinding│ │ RoleBinding (复用)│ │ │ └──────┬─────────┘ └───────┬──────────┘ │ └─────────┼─────────────────────┼───────────────┘ │ │ ┌─────▼─────┐ ┌─────▼──────┐ │ User │ │ServiceAccount│ │(外部认证) │ │(K8s内部管理) │ └───────────┘ └────────────┘
|
权限设计决策树
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| 需要授权? │ ├─ 谁需要权限? │ ├─ 人类操作 → User (证书/OIDC) │ └─ Pod内程序 → ServiceAccount (kubectl create sa) │ ├─ 权限范围? │ ├─ 单个命名空间 → Role + RoleBinding │ ├─ 多个命名空间 → ClusterRole + RoleBinding (复用) │ └─ 整个集群 → ClusterRole + ClusterRoleBinding │ └─ 权限内容? ├─ 资源类型 → rules. resources ├─ 操作类型 → rules.verbs └─ API组 → rules.apiGroups
|
记忆口诀
1 2 3 4 5
| Role 定义权限,Binding 建立关系 User 由外部认证,SA 存储在集群 Namespace 实现隔离,Cluster 跨越边界 权限只能叠加,默认全部拒绝 最小权限原则,定期审计清理
|
RBAC 不是门槛,而是保障集群安全的基石。理解其设计逻辑,才能构建健壮的权限体系。