第 38 篇 k8s之RBAC 与 ServiceAccount 实战
IT策士 10余年一线大厂经验,专注 IT 思维、架构、职场进阶。我会在各个平台持续发布最新文章,助你少走弯路。
在前面的 37 篇文章中,我们一直在“用”Kubernetes——创建 Pod、配置 Deployment、管理存储、设置调度策略。但有一个问题一直被我刻意忽略了:谁有权限做这些事?到目前为止,你一直在以cluster-admin(集群管理员)的身份操作,拥有集群的最高权限。
在一个真实的生产集群中,会有多个人、多个团队、多个自动化系统同时操作。开发团队只应该有权更新自己命名空间下的 Deployment,CI/CD 系统只应该有权触发滚动更新,监控系统只应该有权读取 Pod 指标。如果所有人都用cluster-admin,一次误操作就可能导致全集群故障。
Kubernetes 提供了两套机制来解决权限控制问题:RBAC(Role-Based Access Control,基于角色的访问控制)决定“谁能做什么”,ServiceAccount决定“Pod 以什么身份与 API Server 交互”。今天这篇,我们从最核心的 RBAC 概念讲起,结合实战为贯穿案例的应用创建最小权限的访问规则。
一、理解 RBAC 的核心组件
RBAC 是 K8s 授权机制的核心,它的设计可以用一句话概括:一个 Subject(主体)通过 RoleBinding(角色绑定)获得 Role(角色)中定义的权限,在指定的命名空间或集群范围内执行特定操作。
1.1 四大核心概念
把 RBAC 想象成一个公司的门禁系统,可以帮你快速理解这四个概念:
Role 和 ClusterRole 的区别在于作用范围:
Role作用在特定命名空间内,适合“开发团队只能管理自己的 Pod”这类需求。
ClusterRole作用在整个集群范围,适合访问集群级资源(Node、PV、StorageClass)或需要在所有命名空间生效的权限。
1.2 RBAC 的工作方式
K8s 的 RBAC 遵循默认拒绝原则:如果你没有明确授予某个用户或 ServiceAccount 某项权限,它就是被拒绝的。这与“默认允许,再逐步限制”的安全模型完全相反——更安全,但初次使用时更容易遇到“权限不足”的困惑。
当你执行kubectl apply -f deployment.yaml时,API Server 会依次完成:
认证(Authentication):确认“你是谁”,验证客户端证书或 Bearer Token。
授权(Authorization):检查你是否拥有执行该操作的 Role。API Server 遍历所有 RoleBinding,检查你是否有对应的权限。
准入控制(Admission Control):在请求被真正执行前,做最后的校验和修改(如资源配额检查、注入 Sidecar)。
RBAC 就是第二步“授权”的具体实现。
二、实战:为一个“只读用户”创建 Role
场景:新来的运维实习生只需要查看default命名空间的 Pod 和 Service 信息,不能做任何修改。
2.1 创建 ServiceAccount
ServiceAccount 是 K8s 为 Pod 内部进程提供的一种身份,也可以用于外部用户。这里我们为实习生创建一个 ServiceAccount:
kubectl create serviceaccount readonly-sa查看 ServiceAccount:
kubectl get sa readonly-sa# NAME SECRETS AGE# readonly-sa 0 10s创建 ServiceAccount 时,K8s 会自动创建一个对应的 Token(存储在 Secret 中),供外部认证使用:
# 获取 Token(K8s v1.24+ 使用方式)kubectl create token readonly-sa--duration=24h# eyJhbGciOiJSUzI1NiIsImtpZCI6...(长 Token 字符串)这个 Token 就是实习生的“门禁卡”——持卡人可以在集群中执行 Token 所关联 ServiceAccount 被授权的操作。
2.2 创建 Role
apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: readonly-role namespace: default rules: - apiGroups:[""]resources:["pods","services","pods/log"]verbs:["get","list","watch"]解读:
apiGroups: [""]:核心 API 组(Pod、Service 等核心资源属于空字符串组)。其他常见组包括apps(Deployment)、batch(Job/CronJob)、networking.k8s.io(NetworkPolicy)。resources:可以访问的资源类型。pods/log允许查看日志。verbs:允许的操作。get(获取单个资源)、list(列出资源)、watch(监听资源变化)。
2.3 绑定 Role 到 ServiceAccount
apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: readonly-binding namespace: default subjects: - kind: ServiceAccount name: readonly-sa namespace: default roleRef: kind: Role name: readonly-role apiGroup: rbac.authorization.k8s.io一个 RoleBinding 包含两部分:subjects指定权限的接收者(可以是多个),roleRef引用已定义的 Role。两者通过 RoleBinding 关联,实现权限的动态授予和回收。
kubectl apply-freadonly-role.yaml kubectl apply-freadonly-binding.yaml2.4 验证只读权限
首先,用kubectl auth can-i命令检查权限(这是调试 RBAC 最高效的工具):
kubectl auth can-i get pods--as=system:serviceaccount:default:readonly-sa# yeskubectl auth can-i delete pods--as=system:serviceaccount:default:readonly-sa# nokubectl auth can-i create deployments--as=system:serviceaccount:default:readonly-sa# no如果你拿到 Token 并配置了 kubeconfig(高级操作,此处不展开),实习生只能查看 Pod 和 Service,无法删除或创建任何资源。这就是最小权限原则的体现。
三、ClusterRole 和 ClusterRoleBinding
Role 和 RoleBinding 的作用范围是特定命名空间。如果你需要访问集群级别的资源(如 Node、PersistentVolume),或者需要在所有命名空间中生效,就需要 ClusterRole 和 ClusterRoleBinding。
例如,部署一个集群级别的日志查看器,需要读取所有命名空间的 Pod 日志:
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: logs-reader rules: - apiGroups:[""]resources:["pods/log"]verbs:["get","list","watch"]--- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: logs-reader-binding subjects: - kind: ServiceAccount name: log-viewer-sa namespace: default roleRef: kind: ClusterRole name: logs-reader apiGroup: rbac.authorization.k8s.io四、实战:为 Flask 应用创建最小权限的 ServiceAccount
到目前为止,我们的 Flask Pod 一直使用default命名空间中的defaultServiceAccount——这个 SA 的权限比较宽松。生产环境的最佳实践是为每个应用创建一个专用的 ServiceAccount,并授予最小必要权限。
4.1 创建专用 ServiceAccount
kubectl create serviceaccount flask-sa4.2 创建最小权限 Role
Flask 应用通常不需要直接访问 K8s API(除非代码中包含 K8s 客户端),但它的 Pod 可能需要读取自己的 ConfigMap 或 Secret:
apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: flask-app-role namespace: default rules: - apiGroups:[""]resources:["configmaps","secrets"]verbs:["get","list"]resourceNames:["flask-counter-config","flask-secret"]resourceNames字段将权限限制到特定资源实例。这意味着即使 Role 允许get secrets,也只能访问列表中的 Secret,而不是整个命名空间的所有 Secret。
4.3 绑定并应用到 Deployment
apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: flask-app-binding namespace: default subjects: - kind: ServiceAccount name: flask-sa roleRef: kind: Role name: flask-app-role apiGroup: rbac.authorization.k8s.io在 Deployment 中引用 ServiceAccount:
spec: template: spec: serviceAccountName: flask-sa containers: - name: flask image: flask-redis-counter:3.0kubectl apply-fflask-deployment-with-sa.yaml kubectl get pod<pod-name>-ojsonpath='{.spec.serviceAccountName}'# flask-sa现在 Flask Pod 使用的身份是flask-sa,如果应用代码尝试访问未授权的 K8s API(如列出所有 Pod),API Server 会返回 403 Forbidden。这就避免了某个被攻破的 Pod 利用过高权限访问集群资源。
五、RBAC 排错指南
当kubectl返回forbidden时,按以下步骤排查:
# 1. 确认当前用户/SA 身份kubectl authwhoami# 2. 检查是否能执行特定操作kubectl auth can-i create pods--as=<user># 3. 查看某个 Role 的完整权限kubectl describe role<role-name># 4. 查看某个 RoleBinding 的绑定关系kubectl describe rolebinding<binding-name># 5. 检查集群中所有 RoleBinding(搜索特定 SA)kubectl get rolebinding --all-namespaces-owide|grep<sa-name>六、与 Docker Compose 的安全对比
Compose 本身没有用户和权限系统,安全性完全依赖宿主机的 Docker Daemon 权限(通常需要 root 或 docker 组成员)。这意味着任何能运行docker compose命令的人,都能看到所有容器的环境变量(包括明文密码)、挂载任意宿主机目录、甚至提权到 root。
K8s 的 RBAC 体系将集群操作权限精细控制到“谁能对哪些资源执行什么操作”,是多租户环境下安全管理的基石。配合 ServiceAccount 机制,Pod 默认无法访问 K8s API,从根本上消除了容器逃逸后横向移动的风险。
七、命令速查表
八、本篇总结
RBAC 的四个核心:Role(权限集合)、Subject(用户/SA)、RoleBinding(绑定关系)、ClusterRole(集群级权限)。三者缺一不可。
命名空间与集群作用域:Role 限定命名空间,ClusterRole 跨越所有命名空间。日常应用授权使用 Role 即可,集群级工具(监控、日志)才需要 ClusterRole。
ServiceAccount:Pod 与 K8s API 交互的身份凭证,每个 Pod 必须关联一个 ServiceAccount。为应用创建专属 SA 并授予最小必要权限,是安全最佳实践。
最小权限原则:永远只授予应用所需的最小权限。用
resourceNames限制到具体资源实例,用命名空间级 Role 限制作用范围。
本篇是 K8s 核心系列(第 19-38 篇)的最后一篇。至此,你已经完整掌握了从 Pod、控制器、Service、Ingress,到配置管理、存储、资源管理、调度策略和 RBAC 安全体系。下一篇——第 39 篇:Helm 入门:包管理工具与 Chart,我们将进入 K8s 生态与实战阶段,学习如何用 Helm 统一打包和管理复杂的 K8s 应用。
想了解更多还可以去各个平台搜索「IT策士」,一起升级 IT 思维 !
