前言

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
# 1. 定义剧本(Role):运维工程师能做什么
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: operator
namespace: production
rules:
- apiGroups: [""]
resources: ["pods", "pods/log"]
verbs: ["get", "list", "delete"]

---
# 2. 选角(RoleBinding):张三扮演运维工程师
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
# 开发团队:只能在 dev 命名空间部署应用
apiVersion: rbac. authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: dev-team
namespace: dev # ← 空间隔离:限制在 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"]

---
# 在项目A中使用
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

---
# 在项目B中复用同一个角色
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
# 1. 创建 ServiceAccount(在K8s中)
apiVersion: v1
kind: ServiceAccount
metadata:
name: app-backend
namespace: production

---
# 2. 授权
apiVersion: rbac.authorization. k8s.io/v1
kind: RoleBinding
subjects:
- kind: ServiceAccount
name: app-backend
namespace: production # ← 必须指定命名空间
roleRef:
kind: Role
name: db-accessor

---
# 3. Pod 使用
apiVersion: v1
kind: Pod
spec:
serviceAccountName: app-backend
containers:
- name: backend
# 自动挂载:
# /var/run/secrets/kubernetes. io/serviceaccount/token
# /var/run/secrets/kubernetes. io/serviceaccount/ca. crt
# /var/run/secrets/kubernetes.io/serviceaccount/namespace

Token 使用示例

1
2
3
4
5
6
7
# Pod 内程序自动获取身份
TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)

# 调用 K8s API
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
# 张三有两个 RoleBinding

# Binding 1: 可以读取 Pod
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 # 可以 get, list pods

---
# Binding 2: 可以删除 Pod
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 # 可以 delete pods

# 最终权限 = pod-reader ∪ pod-deleter
# 张三可以:get, list, delete pods

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
# 场景:张三在 dev 和 production 都有 RoleBinding

# dev 命名空间
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 # 完全控制权限

---
# production 命名空间
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         # ✅ 允许(admin权限)
kubectl delete pod xxx -n production # ❌ 拒绝(只有view权限)
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
# 租户A:创建独立命名空间
apiVersion: v1
kind: Namespace
metadata:
name: tenant-a

---
# 租户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 # 使用内置角色

---
# 租户A的开发者(受限权限)
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"]
# 禁止:delete、修改 RBAC、访问 secrets

---
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
# CI 系统只需要部署权限
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"] # 只读,用于查看部署状态
# 禁止:delete pods、修改 secrets、访问其他命名空间

---
# 在多个项目命名空间中授权
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 权限设计原则

  1. 最小权限原则:只授予完成任务的最小权限集
  2. 命名空间隔离:不同环境/租户使用独立命名空间
  3. 禁用 default SA:为每个应用创建专用 ServiceAccount
  4. 定期审计:检查过度授权和长期未使用的权限

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
# ⚠️ 避免授予这些权限组合

# 1. 通配符权限
rules:
- apiGroups: ["*"]
resources: ["*"]
verbs: ["*"] # ← 相当于集群管理员

# 2. 修改 RBAC 的权限
rules:
- apiGroups: ["rbac.authorization.k8s. io"]
resources: ["roles", "rolebindings"]
verbs: ["create", "update"] # ← 可以提升自己的权限

# 3. 创建特权 Pod
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["create"]
- apiGroups: ["policy"]
resources: ["podsecuritypolicies"]
verbs: ["use"]
resourceNames: ["privileged"] # ← 可以逃逸容器

# 4. 访问所有 Secret
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'

# 检查 ServiceAccount 权限
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 不是门槛,而是保障集群安全的基石。理解其设计逻辑,才能构建健壮的权限体系。