引言
在 Kubernetes 集群中,随着业务规模不断扩大,越来越多的人和程序需要访问集群资源。有人需要部署应用、有人需要查看日志、有人只需要读取监控指标,而自动化流水线(CI/CD)也需要调用 API 完成镜像发布。如果所有人都使用同一个高权限账号,一旦凭证泄露,整个集群都可能被攻破。因此,一套细粒度、可管理、可审计的权限体系是生产集群的必备能力。
Kubernetes 的权限安全体系由「认证(Authentication)」「授权(Authorization)」和「准入控制(Admission Control)」三部分组成。认证回答”你是谁”,授权回答”你能做什么”,准入控制则在你动手之前做最后一道校验。今天我们要深入讲解其中最核心的一环:基于角色的访问控制(RBAC,Role-Based Access Control)以及承载 Pod 身份的服务账号(ServiceAccount)。

核心概念
1. 认证与授权的关系
Kubernetes 并不管理用户本身,普通用户(自然人)通常由外部系统(如证书、OpenID Connect、LDAP)提供身份。集群内真正原生的”身份”是 ServiceAccount,它是给 Pod 里运行的程序使用的账号。认证通过后,授权阶段由 RBAC 决定这个身份对哪些资源拥有哪些操作权限。
2. RBAC 四大对象
RBAC 通过四个 API 对象来描述权限:
- Role:定义某个命名空间内的一组权限规则(能对哪些资源做哪些操作)。
- ClusterRole:与 Role 类似,但作用域是整个集群,也可以授权给非命名空间级资源(如 Node、Namespace、PersistentVolume)。
- RoleBinding:把 Role 授予某个命名空间内的主体(用户、组、ServiceAccount)。
- ClusterRoleBinding:把 ClusterRole 授予集群范围内的主体。
3. ServiceAccount
每个命名空间默认会有一个名为 default 的 ServiceAccount。Pod 若未显式指定,就使用 default。ServiceAccount 关联一个 Token(令牌),程序挂载该 Token 即可调用 Kubernetes API。从 1.24 起,默认不再自动挂载长期 Token,推荐使用绑定的临时 Token。
实战步骤
步骤 1:创建命名空间与 ServiceAccount
先创建一个专用命名空间,并为部署团队创建专属服务账号。
kubectl create namespace dev
kubectl create serviceaccount deploy-sa -n dev
查看刚创建的 ServiceAccount:
kubectl get serviceaccount deploy-sa -n dev
步骤 2:编写 Role 定义权限
下面这个 Role 允许在 dev 命名空间内对 Deployment、Service、Pod 进行增删改查,但禁止访问 Secret 和 ConfigMap。
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: dev
name: deploy-role
rules:
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- apiGroups: [""]
resources: ["pods", "services"]
verbs: ["get", "list", "watch", "create", "update", "delete"]
步骤 3:使用 RoleBinding 绑定账号
通过 RoleBinding 把 deploy-role 授予 deploy-sa:
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
namespace: dev
name: deploy-binding
subjects:
- kind: ServiceAccount
name: deploy-sa
namespace: dev
roleRef:
kind: Role
name: deploy-role
apiGroup: rbac.authorization.k8s.io
应用并验证:
kubectl apply -f role.yaml
kubectl apply -f rolebinding.yaml
kubectl auth can-i create deployments -n dev --as=system:serviceaccount:dev:deploy-sa
步骤 4:验证越权操作被拒绝
用该账号尝试访问 Secret,应当被拒绝:
kubectl auth can-i get secrets -n dev --as=system:serviceaccount:dev:deploy-sa
# 输出 no
步骤 5:让 Pod 使用 ServiceAccount
在 Deployment 的 Pod 模板中指定 serviceAccountName,并显式声明不自动挂载默认 Token:
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
namespace: dev
spec:
replicas: 2
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
serviceAccountName: deploy-sa
automountServiceAccountToken: false
containers:
- name: app
image: nginx:1.25
ports:
- containerPort: 80
常见问题
问题 1:明明绑定了 Role,Pod 却报 forbidden。
先确认 ServiceAccount 名称与命名空间是否完全一致,再检查 Role 的 apiGroups 是否写对。核心资源组(Pod、Service)的 apiGroups 是空字符串 "",而 Deployment 属于 apps 组,写错会导致授权不生效。
问题 2:想给用户只读权限,如何快速实现?
集群内置了若干聚合 ClusterRole,例如 view、edit、admin。只读用户直接绑定 view 即可,无需手写 Role。
kubectl create rolebinding viewer --clusterrole=view --user=alice -n dev
问题 3:ServiceAccount 的 Token 泄露了怎么办?
立即删除并重建该 ServiceAccount,Token 会随之失效。生产环境建议缩短 Token 有效期、使用准入控制限制 Secret 访问,并定期轮换凭证。
问题 4:权限改动后为何有时要等几秒才生效?
RBAC 授权结果会被缓存,默认最多延迟约 10 秒。若验证时未立即生效,稍等片刻再试即可。
总结
RBAC 是 Kubernetes 权限管理的基石,它用「角色 + 绑定」的解耦方式,把”能做什么”与”谁来做”分开管理,配合 ServiceAccount 为 Pod 内的程序提供受控身份。掌握 Role/ClusterRole 与 RoleBinding/ClusterRoleBinding 的区别,理解最小权限原则,是构建安全集群的第一步。建议在生产中坚持”按需授权、定期审计、凭证轮换”三原则,避免宽泛的 cluster-admin 权限被滥用。
下期预告
下一期《第 12 天:证书与多集群——kubeconfig 与集群切换》,我们将讲解如何通过 kubeconfig 管理多个集群的访问凭证,实现本地与多套集群之间的无缝切换,敬请期待。


















暂无评论内容