公司动态

【Kubernetes从入门到精通】第53篇:RBAC——基于角色的访问控制完全指南,别再给CI/CD账号开“管理员“了

📅 2026/8/17 21:36:02
【Kubernetes从入门到精通】第53篇:RBAC——基于角色的访问控制完全指南,别再给CI/CD账号开“管理员“了
上一篇【第52篇】K8s安全体系全景——AuthN/AuthZ/Admission三道防线API Server的“安检流水线“下一篇【第54篇】ServiceAccount——Pod的身份证摘要上篇讲了K8s安全的四道关卡其中授权环节的绝对主力是RBAC。今天咱们把它彻底拆开。RBACRole-Based Access Control的核心思想特别朴素先定义角色这角色能干啥再把角色绑定给某个用户/账号。就这么简单。但K8s的RBAC有四个名词容易绕晕Role、ClusterRole、RoleBinding、ClusterRoleBinding。很多人嫌麻烦直接给CI/CD账号绑个cluster-admin——结果某天流水线脚本一个bug把生产namespace全删了。这就是不做最小权限的代价。这篇文章讲清四件套的区别再手把手给你一个生产级实战给Jenkins/GitLab CI创建一个只敢部署、不敢删除的最小权限账号。一、RBAC四件套1.1 两个角色 两个绑定【RBAC 四件套关系图】 Role (命名空间级角色) ClusterRole (集群级角色) 在default ns能干啥 在整个集群能干啥 │ │ │ RoleBinding │ ClusterRoleBinding │ (在XX ns生效) │ (全集群生效) ▼ ▼ ┌──────────────┐ ┌──────────────┐ │ 绑定给 Subject│ │ 绑定给 Subject│ │ (User/SA/Group)│ │ (User/SA/Group)│ └──────────────┘ └──────────────┘ 关键组合规律 • Role RoleBinding 某ns内的权限 • ClusterRole RoleBinding 某ns内借用集群角色(缩小范围!) • ClusterRole ClusterRoleBinding 全集群权限(最危险)要点最容易搞混的是ClusterRole RoleBinding这个组合——它看起来矛盾但其实是个缩小范围的技巧用一个全集群定义的角色只绑定到某个namespace生效。比如K8s内置的view角色是ClusterRole但你用RoleBinding把它绑到prodns就只在prod里生效只读。1.2 Role vs ClusterRole维度RoleClusterRole作用范围单个namespace整个集群定义位置带namespace元数据不带namespace能管集群级资源吗❌ (如Node/PV)✅典型用途应用级权限集群管理员/系统组件# Role: 只在 default ns 能读Pod、能部署DeploymentapiVersion:rbac.authorization.k8s.io/v1kind:Rolemetadata:namespace:defaultname:deployerrules:-apiGroups:[apps]resources:[deployments]verbs:[get,list,watch,create,update,patch]-apiGroups:[]resources:[pods]verbs:[get,list]# ClusterRole: 全集群能读NodeapiVersion:rbac.authorization.k8s.io/v1kind:ClusterRolemetadata:name:node-readerrules:-apiGroups:[]resources:[nodes]verbs:[get,list,watch]二、聚合ClusterRole——“拼乐高”2.1 自动聚合多个角色K8s有个很实用的特性ClusterRole可以自动聚合其他ClusterRole的规则。# 定义一个监控员聚合角色自动收编所有带label的监控角色apiVersion:rbac.authorization.k8s.io/v1kind:ClusterRolemetadata:name:monitoringaggregationRule:clusterRoleSelectors:-matchLabels:monitoring-role:true# 自动聚合所有带这个label的ClusterRolerules:[]# 注意rules留空由聚合自动填充# 另一个文件里定义具体角色打上label即可被聚合apiVersion:rbac.authorization.k8s.io/v1kind:ClusterRolemetadata:name:prometheus-metricslabels:monitoring-role:truerules:-apiGroups:[]resources:[pods,services]verbs:[get,list,watch]要点聚合ClusterRole在管理一堆相关权限时特别省心——你不用改主角色只要给新角色打上对应label它就自动被收编。K8s内置的很多角色如admin、edit、view就是用这套机制组织的。三、实战给CI/CD创建最小权限账号3.1 需求拆解【场景GitLab CI 要部署应用到 prod 命名空间】 需求 • 能 create/update/patch/delete Deployment、Service • 能 get/list/watch Pod (看日志、看状态) • 能 创建/删除 Secret (部署需要镜像凭证) • 绝对不能删namespace、动Node、动其他ns、提权 错误做法 kubectl create clusterrolebinding ci-admin \ --clusterrolecluster-admin --serviceaccountci:deployer ❌ 一个部署账号拿到了全集群管理员权限3.2 正确的最小权限配置# 1. 创建ServiceAccountapiVersion:v1kind:ServiceAccountmetadata:name:deployernamespace:prod# 2. 定义Role(只在prod ns生效精确限制资源)apiVersion:rbac.authorization.k8s.io/v1kind:Rolemetadata:name:deployer-rolenamespace:prodrules:-apiGroups:[apps]resources:[deployments]verbs:[get,list,watch,create,update,patch,delete]-apiGroups:[]resources:[services,configmaps]verbs:[get,list,watch,create,update,patch,delete]-apiGroups:[]resources:[pods]verbs:[get,list,watch]-apiGroups:[]resources:[secrets]verbs:[get,list,create,update,patch,delete]# 注意没有 namespaces / nodes / persistentvolumes → 想动也动不了# 3. 绑定(注意用RoleBinding,不是ClusterRoleBinding!)apiVersion:rbac.authorization.k8s.io/v1kind:RoleBindingmetadata:name:deployer-bindingnamespace:prodsubjects:-kind:ServiceAccountname:deployernamespace:prodroleRef:kind:Rolename:deployer-roleapiGroup:rbac.authorization.k8s.io3.3 验证权限# 用deployer的身份测试(确认能部署)kubectl--assystem:serviceaccount:prod:deployer\create deployment nginx--imagenginx-nprod# 成功# 测试它越权会怎样(尝试删ns)kubectl--assystem:serviceaccount:prod:deployer\delete namespace prod# Error from server (Forbidden): ... cannot delete resource namespaces in API group at the cluster scope# ↑ 被拒完美它碰不到namespace级别的资源四、常见坑4.1 权限不生效检查这几处【RBAC 排错清单】 1. Subject 的 name/namespace 写对了(SA名字拼错绑定了个空气) 2. RoleBinding 的 namespace 和 Role 一致(跨ns绑定不生效) 3. verbs 写全了(patch和update是两个不同的verb) 4. apiGroups 对了吗(apps vs 核心组搞错就403) 5. 用 kubectl auth can-i 验证# 神器直接问API Server这个身份能不能干这事kubectl auth can-i create deployments-nprod\--assystem:serviceaccount:prod:deployer# yeskubectl auth can-i delete nodes--assystem:serviceaccount:prod:deployer# no# 自查当前用户权限kubectl auth can-i--list要点kubectl auth can-i是RBAC排错的第一神器——它直接问API Server这个身份到底能不能干这件事返回一个yes/no比你看半天YAML靠谱多了。记住verbs里的patch和update是两回事apiGroups里apps和空字符串(“”)也是两回事这两个是最容易写错导致403的地方。本篇小结RBAC四件套——Rolens级角色、ClusterRole集群级角色、RoleBindingns内绑定、ClusterRoleBinding集群绑定。组合规律记牢RoleRoleBinding在ns内生效ClusterRoleRoleBinding是缩小范围ClusterRoleClusterRoleBinding是全集群最危险。生产铁律最小权限原则。给CI/CD建独立ServiceAccount用RoleBinding精确限制到ns和资源绝不开cluster-admin。下一篇聊ServiceAccount本身——Pod的身份证是怎么工作和保护的。上一篇【第52篇】K8s安全体系全景——AuthN/AuthZ/Admission三道防线API Server的“安检流水线“下一篇【第54篇】ServiceAccount——Pod的身份证