K8s RBAC 四个概念一图搞懂(上集)
每个运维都经历过这个场景:Pod 报 403 Forbidden,日志里没有任何有用信息,最后发现是 ServiceAccount 权限没给够。RBAC 真不复杂,但四个概念一旦搞混,排查直接干到凌晨三点。
本系列共 3 集:上集拆解四个核心概念 → 中集手把手搭建权限体系 → 下集进阶要点 + 排坑指南。建议按顺序阅读。
一、开篇
1. 经典场景:403 Forbidden
$ kubectl get pods

这是 K8s 运维最常见的报错之一。给开发开了集群权限,他随手 kubectl delete pod 干掉了生产数据库——然后你就成了那个"把权限管好"的人。
2. RBAC 三元组:谁 + 什么 + 怎么做
K8s 的权限管理就一个核心问题:谁(Subject)能对什么东西(Resource)做什么操作(Verb)。RBAC 用四个概念把这个三元组组织起来:
- User / ServiceAccount:谁(主体)
- Role / ClusterRole:能做啥操作 + 操作哪些资源(权限规则)
- RoleBinding / ClusterRoleBinding:把主体和权限绑在一起(绑定关系)
3. 概念关系图
一眼看穿全貌——权限就是 Subject 经过 Binding 拿到 Role 的过程:
┌──────────────┐ ┌──────────────────┐ ┌──────────────┐
│ Subject │────▶│ Binding │────▶│ Role │
│ (Who) │ │ (How) │ │ (What) │
├──────────────┤ ├──────────────────┤ ├──────────────┤
│ User │ │ RoleBinding │ │ Role │
│ (自然人) │ │ (命名空间级绑定) │ │ (命名空间级) │
│ │ │ │ │ │
│ ServiceAccount│ │ ClusterRoleBinding│ │ ClusterRole │
│ (Pod/程序身份) │ │ (集群级绑定) │ │ (集群级) │
└──────────────┘ └──────────────────┘ └──────────────┘
4. 权限校验完整链路
一个 kubectl 请求到达 API Server 后,要过三道关卡——RBAC 在第二关:
kubectl 请求
│
▼
┌─────────────┐
│ Authentication │ ← 我是谁?(证书/OIDC/Token 验证身份)
│ (认证) │ X509 证书 → CN=用户, O=组
└──────┬──────┘
│ 通过,拿到 User/Group 身份
▼
┌─────────────┐
│ Authorization │ ← 我能做什么?(RBAC 检查)
│ (授权) │ 遍历所有 RoleBinding/ClusterRoleBinding
└──────┬──────┘ 匹配到规则 → 允许,匹配不到 → 403
│ 通过
▼
┌─────────────┐
│ Admission │ ← 请求合不合规?(Webhook 校验,可选)
│ (准入控制) │
└──────┬──────┘
│ 通过
▼
┌────────┐
│ API Server │ → 执行操作
└────────┘
RBAC 处于 授权(Authorization) 这一环。认证不归 RBAC 管,但认证产出的 User/Group 身份是 RBAC 的输入。
二、四个核心概念,逐个拆解
1. User:人的身份
1.1 概念
K8s 不管理 User 对象——也就是没有 kubectl create user 这个命令。User 由集群外部的认证系统管理:
| 认证方式 | 身份来源 | 例子 |
|---|---|---|
| X509 客户端证书 | 证书 CN = 用户名,O = 组 | CN=zhangsan,O=dev-team → User zhangsan,组 dev-team |
| OIDC / OAuth2 | ID Token 中的 sub/email |
接入企业 LDAP、GitHub OAuth |
| Webhook Token | 自定义认证服务 | 自建 Token 验证服务 |
| Static Token File | 静态 CSV 文件 | --token-auth-file=/etc/kubernetes/tokens.csv |
关键认知:User 是给人用的。平时 kubectl 操作集群,身份就是一个 User(通常来自 kubeconfig 里的客户端证书)。
1.2 生产实战:从零给一个用户签发证书并授权
这是最常用的场景——给一个新同事开通集群访问权限。完整流程分 5 步走。
第 1 步:找到集群 CA 证书
签发客户端证书需要集群的 CA 公钥和私钥。如果不记得放在哪了,可以通过下面方式查:
# 方式 1:kubeadm 默认路径(最常用)
ls /etc/kubernetes/pki/
# → ca.crt(公钥) ca.key(私钥)
# 部分发行版在 /etc/kubernetes/ssl/,文件名为 ca.pem / ca-key.pem
# 方式 2:从 kube-apiserver 进程参数反查(最靠谱)
ps aux | grep kube-apiserver | grep -o '\-\-client-ca-file=[^ ]*'
# 输出示例:
# --client-ca-file=/etc/kubernetes/pki/ca.crt
# --client-ca-file=/etc/kubernetes/ssl/ca.pem
# 私钥通常在同目录,命名为 ca.key / ca-key.pem
CA 文件路径和扩展名(
.crt/.pem)因发行版而异,以方式 2 查到的为准。私钥是高权限文件(root 只读),签发时需要 root 身份。

第 2 步:编写证书签名请求(CSR)
CSR 里有两个关键字段:CN = 用户名,O = 组名(后面 RBAC 授权就靠这个组)。
cat > zhangsan-csr.json <<EOF
{
"CN": "zhangsan",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "dev-team",
"OU": "System"
}
]
}
EOF
第 3 步:用集群 CA 签发客户端证书
签发需要 ca-config.json(cfssl 签发策略配置),集群不自带,自己建一个:
# 3a. 创建签发策略文件(如果还没有)
cat > ca-config.json <<EOF
{
"signing": {
"default": { "expiry": "87600h" },
"profiles": {
"kubernetes": {
"usages": ["signing", "key encipherment", "server auth", "client auth"],
"expiry": "87600h"
}
}
}
}
EOF
# 3b. 用集群 CA 签发客户端证书
# 注意:-ca 和 -ca-key 路径用上一步查到的实际路径
cfssl gencert \
-ca=/etc/kubernetes/ssl/ca.pem \
-ca-key=/etc/kubernetes/ssl/ca-key.pem \
-config=ca-config.json \
-profile=kubernetes zhangsan-csr.json | cfssljson -bare zhangsan
# → 产出三个文件:
# zhangsan.pem 客户端证书(公钥)
# zhangsan-key.pem 客户端私钥
# zhangsan.csr 证书签名请求(可删)

第 4 步:生成 kubeconfig 文件
分四小步:写集群信息 → 写用户凭证 → 创建上下文 → 设为默认。
#查找集群地址
[root@master-1 rbac]# kubectl config view --raw | grep server
server: https://192.168.91.254:6443
# 4a. 写入集群信息
# ca 路径和 --server 地址替换为你的集群实际值
kubectl config set-cluster kubernetes \
--certificate-authority=/etc/kubernetes/ssl/ca.pem \
--embed-certs=true \
--server=https://192.168.91.254:6443 \
--kubeconfig=zhangsan.kubeconfig
# 4b. 写入用户凭证
kubectl config set-credentials zhangsan \
--client-certificate=zhangsan.pem \
--client-key=zhangsan-key.pem \
--embed-certs=true \
--kubeconfig=zhangsan.kubeconfig
# 4c. 创建上下文(关联用户 + 集群)
kubectl config set-context zhangsan@kubernetes \
--cluster=kubernetes \
--user=zhangsan \
--kubeconfig=zhangsan.kubeconfig
# 4d. 设为默认上下文
kubectl config use-context zhangsan@kubernetes \
--kubeconfig=zhangsan.kubeconfig

第 5 步:分发 kubeconfig + 验证
# 把 kubeconfig 发给用户
scp zhangsan.kubeconfig zhangsan@192.168.91.21:~/.kube/config
# 用户验证——现在应该是 403(认证过了,但还没授权)
KUBECONFIG=~/.kube/config kubectl get pods
# → Error: Forbidden(属于预期——下一步就是配 RoleBinding)

重点:证书签完之后,用户身份就有了(认证 OK),但还没有任何权限(授权未配)。下一步就是在集群侧创建 RoleBinding 把
dev-team这个 Group 绑定到对应 Role——这就是下一节要讲的内容。
2. ServiceAccount:Pod 的身份
跟 User 相反,ServiceAccount 是 K8s 原生管理的资源,用于给 Pod 里的程序一个身份:
# 创建一个 ServiceAccount
kubectl create sa my-app-sa -n prod
# 查看
kubectl get sa my-app-sa -n prod -o yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-app-sa
namespace: prod

每个 namespace 有一个默认的 ServiceAccount default——如果创建 Pod 时不指定 serviceAccountName,用的就是这个。
关键认知:ServiceAccount 是给程序(Pod)用的。当应用需要调用 K8s API(比如读取 ConfigMap、创建 Pod),它用的身份就是 ServiceAccount。
3. Role / ClusterRole:权限规则
3.1 概念:命名空间级 vs 集群级
Role 是命名空间级别的权限集合,ClusterRole 是集群级别的。Role 只在指定 namespace 内生效,ClusterRole 跨所有 namespace。
3.2 Role 示例
# Role:只能操作 prod 命名空间内的 pods 和 configmaps
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-reader
namespace: prod
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get"]
3.3 ClusterRole 示例
# ClusterRole:可以操作所有命名空间的 pods
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: cluster-pod-reader
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
3.4 什么时候用哪个?
| 场景 | 用 Role | 用 ClusterRole |
|---|---|---|
| 只操作某个 namespace 的资源 | ✅ | ✅(但 overkill) |
| 操作所有 namespace 的资源 | ❌ | ✅ |
| 操作集群级资源(Node、PV、Namespace 本身) | ❌ | ✅ |
| 操作非资源端点(/healthz、/metrics) | ❌ | ✅ |
3.5 常见 Verb(操作动词)
| Verb | 含义 | 典型场景 |
|---|---|---|
get |
读取单个资源 | kubectl get pod xyz |
list |
列出资源列表 | kubectl get pods |
watch |
监听资源变化 | Controller/Operator 必备 |
create |
创建资源 | 部署应用 |
update |
更新资源 | 修改配置 |
patch |
部分更新资源 | HPA 调整副本数 |
delete |
删除单个资源 | 清理 Pod |
deletecollection |
批量删除 | kubectl delete pods --all |
4. RoleBinding / ClusterRoleBinding:绑定关系
4.1 概念:把 Subject 和 Role 关联起来
Binding 把 Subject(User/ServiceAccount)和 Role/ClusterRole 关联起来。没有 Binding,Role 只是一堆规则,谁也拿不到。
4.2 RoleBinding 示例
# RoleBinding:把 zhangsan 这个 User 绑定到 pod-reader Role
# → zhangsan 在 prod 命名空间里可以 get/list/watch pods
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: zhangsan-can-read-pods
namespace: prod
subjects:
- kind: User
name: zhangsan
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
4.3 ClusterRoleBinding 示例
# ClusterRoleBinding:把 my-app-sa 这个 ServiceAccount 绑定到 cluster-pod-reader
# → 这个 SA 在所有命名空间都可以 get/list/watch pods
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: app-sa-can-read-pods
subjects:
- kind: ServiceAccount
name: my-app-sa
namespace: prod
roleRef:
kind: ClusterRole
name: cluster-pod-reader
apiGroup: rbac.authorization.k8s.io
4.4 Binding 的四种组合
| Binding 类型 | 绑定的 Role 类型 | 作用范围 | 用法 |
|---|---|---|---|
| RoleBinding + Role | Role(命名空间级) | 仅当前 namespace | 给开发只读权限 |
| RoleBinding + ClusterRole | ClusterRole(集群级) | 仅当前 namespace | 复用集群级规则但限制在单个 ns |
| ClusterRoleBinding + ClusterRole | ClusterRole(集群级) | 整个集群 | 给监控系统读全集群 |
| ClusterRoleBinding + Role | ❌ 不可能 | — | Role 没有跨命名空间的能力 |
三、总结
1. 四个概念一句话速记
| 概念 | 一句话 | 谁在用 |
|---|---|---|
| User | 人的身份,K8s 不管理,靠外部证书/OIDC 认证 | 你敲 kubectl 的时候 |
| ServiceAccount | 程序的身份证,K8s 原生资源,自动挂载到 Pod | 你的应用调 K8s API 的时候 |
| Role / ClusterRole | 权限规则(能对哪些资源做什么操作) | 没有它,谁也动不了资源 |
| RoleBinding / ClusterRoleBinding | 把 Subject 和 Role 绑一起的绳子 | 不绑 = 有身份也没权限 |
2. 核心认知总结
- 权限生效链路:Subject(我是谁)→ Binding(谁和权限绑定了)→ Role(能做什么)。从左到右,缺一环就 403。
- 请求校验顺序:认证(Authentication)→ 授权(RBAC)→ 准入(Admission)。RBAC 只管第二关,但第一关产出的 User/Group 是它的输入。
- User vs SA:User 给人、SA 给程序。User 通过证书的
CN和O(组)定义;SA 通过serviceAccountName挂载到 Pod。 - Role vs ClusterRole:Role 局限在单个 namespace,ClusterRole 跨所有 ns。用 RoleBinding 引用 ClusterRole 可以实现"复用一个集群级规则但限制在单个 ns"。
- Group 优于 User:证书的
O字段就是天然的 RBAC Group。通过 Group 授权,新人入职只需签发证书,RBAC 配置不用动。
3. 还差一步
学完这四个概念,知识结构是:
✅ 知道 User 和 ServiceAccount 分别给谁用
✅ 知道 Role 和 ClusterRole 的作用范围区别
✅ 知道 Binding 的四种组合
✅ 会签发客户端证书生成 kubeconfig
❌ 还不会搭建一套完整的权限体系(开发组只读 + 运维组管理)
别急,这就是中集的内容。
📺 下集预告:「从零搭建 K8s 权限体系:开发组只读 + 运维组管理」——手把手走两个递进案例:先给单个用户授权,再给 Group 授权。每一步都能跟着敲。
更多推荐
所有评论(0)