K8s学习笔记(二十一) RBAC
1 RBAC 是什么?为什么需要它?
在 K8s 中,所有操作(比如kubectl get pod
、delete deployment
)最终都会通过API Server执行。RBAC 是 K8s 默认的授权模式,作用是:
- 控制 “谁”(用户 / 服务账户)能访问 API Server;
- 限制 “能做什么”(比如只读、修改、删除);
- 限定 “作用范围”(比如某个命名空间、整个集群)。
核心原则:最小权限原则(只给完成任务必需的权限,避免过度授权)。
2 RBAC 的 4 个核心组件(必背)
RBAC 通过 4 个 K8s API 资源实现权限控制,分为 “角色(定义权限)” 和 “绑定(分配权限)” 两类:
组件类型 | 资源名称 | 作用域 | 核心作用 |
---|---|---|---|
角色(权限定义) | Role | 单个命名空间 | 定义 “在某个命名空间内,能对哪些资源执行哪些操作” |
角色(权限定义) | ClusterRole | 整个集群(无命名空间) | 定义 “集群级资源(如节点、命名空间)” 或 “跨所有命名空间资源” 的操作权限 |
绑定(权限分配) | RoleBinding | 单个命名空间 | 将 Role 的权限分配给 “主体”(用户 / 服务账户 / 用户组) |
绑定(权限分配) | ClusterRoleBinding | 整个集群 | 将 ClusterRole 的权限分配给 “主体”,作用于整个集群或所有命名空间 |
2.1 先理解 “权限三要素”
无论 Role 还是 ClusterRole,定义权限时都围绕 3 个要素:
- 资源(Resources):K8s 中的对象,如
pods
、deployments
、services
、namespaces
(集群级)、nodes
(集群级)等; - 操作(Verbs):对资源的动作,如
get
、list
、create
、update
、delete
、watch
(实时监听)等; - 资源名称(ResourceNames,可选):限定权限只作用于 “特定名称的资源”(比如只允许修改名为
my-pod
的 Pod)。
2.2 逐个拆解核心组件
(1)Role:命名空间内的权限
特点:仅作用于它所在的命名空间,无法访问集群级资源(如节点)。
示例 YAML:创建一个名为pod-reader
的 Role,允许在default
命名空间 “读取 Pod”(get
/list
/watch
):
# role-pod-reader.yaml
apiVersion: rbac.authorization.k8s.io/v1 # RBAC的固定API版本
kind: Role
metadata:name: pod-reader # Role名称namespace: default # 作用的命名空间(必须指定)
rules: # 权限规则(可多个)
- apiGroups: [""] # API组:""表示核心API组(如pods、services)resources: ["pods"] # 允许操作的资源:Podverbs: ["get", "list", "watch"] # 允许的操作
创建命令:kubectl apply -f role-pod-reader.yaml
(2)ClusterRole:集群级 / 跨命名空间权限
特点:
- 作用于整个集群,无需指定命名空间;
- 可管理集群级资源(如
nodes
、namespaces
); - 可管理 “跨所有命名空间的资源”(如 “查看所有命名空间的 Pod”);
- 可被 RoleBinding 引用(实现 “在单个命名空间使用集群级权限”)。
示例 YAML:创建一个名为cluster-pod-reader
的 ClusterRole,允许 “读取所有命名空间的 Pod” 和 “查看节点信息”:
# clusterrole-pod-reader.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:name: cluster-pod-reader # ClusterRole名称(无命名空间)
rules:
# 规则1:读取所有命名空间的Pod
- apiGroups: [""]resources: ["pods"]verbs: ["get", "list", "watch"]
# 规则2:查看节点(集群级资源)
- apiGroups: [""]resources: ["nodes"]verbs: ["get", "list"]
创建命令:kubectl apply -f clusterrole-pod-reader.yaml
(3)RoleBinding:将 Role/ClusterRole 绑定到主体(命名空间内)
作用:把 “Role 的权限” 或 “ClusterRole 的权限(限定在单个命名空间)” 分配给 “主体”。
主体(Subject):权限的接收者,分 3 类:
User
:外部用户(如运维人员,由 K8s 外的认证系统管理,如 CA 证书、LDAP);Group
:用户组(如 “dev-team” 组,包含多个 User);ServiceAccount
:K8s 内部的 “服务账户”(给 Pod 内的应用使用,如 Pod 访问 API Server 时用的账户)。
示例 1:绑定 Role 到 ServiceAccount
创建一个 RoleBinding,将前面的pod-reader
Role 绑定到default
命名空间的my-sa
ServiceAccount:
# rolebinding-pod-reader.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:name: pod-reader-bindingnamespace: default # 必须和Role的命名空间一致
subjects: # 主体列表
- kind: ServiceAccountname: my-sa # ServiceAccount名称namespace: default # ServiceAccount所在命名空间
roleRef: # 引用的角色(固定格式)apiGroup: rbac.authorization.k8s.iokind: Role # 引用的是Role(也可改为ClusterRole)name: pod-reader # 引用的Role名称
示例 2:绑定 ClusterRole 到 User(限定在单个命名空间)
如果想让用户dev-user
仅在dev
命名空间拥有cluster-pod-reader
的权限(虽然 ClusterRole 是集群级,但 RoleBinding 限定了命名空间):
# rolebinding-cluster-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:name: dev-user-pod-readernamespace: dev # 限定在dev命名空间
subjects:
- kind: Username: dev-user # 外部用户名称apiGroup: rbac.authorization.k8s.io
roleRef:apiGroup: rbac.authorization.k8s.iokind: ClusterRole # 引用ClusterRolename: cluster-pod-reader
(4)ClusterRoleBinding:将 ClusterRole 绑定到主体(集群级)
作用:把 ClusterRole 的权限分配给主体,作用于整个集群(所有命名空间 + 集群资源)。
示例:让用户组admin-team
拥有 “集群管理员” 权限(K8s 默认有cluster-admin
ClusterRole,拥有所有权限):
# clusterrolebinding-admin.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:name: admin-team-binding
subjects:
- kind: Groupname: admin-team # 用户组名称apiGroup: rbac.authorization.k8s.io
roleRef:apiGroup: rbac.authorization.k8s.iokind: ClusterRolename: cluster-admin # K8s默认ClusterRole(所有权限,谨慎使用)
3 关键实操:如何验证权限?
创建 Role/Binding 后,需要验证权限是否生效,核心命令是 kubectl auth can-i
(检查 “某个主体能否执行某个操作”)。
语法
# 1. 检查当前用户的权限(默认是kubectl配置的用户)
kubectl auth can-i <操作> <资源> -n <命名空间># 2. 检查指定ServiceAccount的权限
kubectl auth can-i <操作> <资源> -n <命名空间> --as=system:serviceaccount:<命名空间>:<ServiceAccount名称># 3. 检查跨命名空间/集群资源的权限
kubectl auth can-i <操作> <资源> --all-namespaces # 所有命名空间
kubectl auth can-i <操作> nodes # 集群资源(无需-n)
示例
-
检查
default
命名空间的my-sa
能否读取 Pod:kubectl auth can-i get pods -n default --as=system:serviceaccount:default:my-sa # 输出:yes(表示有权限)/ no(无权限)
-
检查
dev-user
能否在dev
命名空间删除 Pod:kubectl auth can-i delete pods -n dev --as=dev-user
-
检查
admin-team
能否查看节点:kubectl auth can-i list nodes --as=system:serviceaccount:kube-system:default --as-group=admin-team
4 常见场景:实战案例
场景 1:给 Pod 内应用授权(最常用)
Pod 内的应用(如 Java 程序)要调用 K8s API(比如获取 Pod 列表),需通过ServiceAccount授权:
-
创建自定义 ServiceAccount:
kubectl create sa my-app-sa -n dev
-
创建 Role(允许在
dev
命名空间读取 Pod):参考前面的pod-reader
-
创建 RoleBinding(将 Role 绑定到
my-app-sa
):参考前面的rolebinding-pod-reader
-
部署 Pod 时指定 ServiceAccount:
# pod-with-sa.yaml apiVersion: v1 kind: Pod metadata:name: my-app-podnamespace: dev spec:serviceAccountName: my-app-sa # 指定ServiceAccountcontainers:- name: my-appimage: nginx
场景 2:给开发人员 “命名空间只读权限”
让dev-user
只能在dev
命名空间查看 Pod/Deployment,不能修改:
-
创建 ClusterRole(通用只读权限,可复用):
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata:name: ns-reader rules: - apiGroups: ["", "apps"] # ""=核心组(pods),apps=部署组(deployments)resources: ["pods", "deployments", "services"]verbs: ["get", "list", "watch"]
-
创建 RoleBinding(将 ClusterRole 绑定到
dev-user
,限定在dev
命名空间):apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata:name: dev-user-readernamespace: dev subjects: - kind: Username: dev-userapiGroup: rbac.authorization.k8s.io roleRef:apiGroup: rbac.authorization.k8s.iokind: ClusterRolename: ns-reader
5 避坑指南
-
命名空间一致性:Role 和引用它的 RoleBinding 必须在同一个命名空间,ClusterRole 无命名空间限制。
-
API 组正确:不同资源属于不同 API 组,比如:
-
核心资源(pods、services):
apiGroups: [""]
-
部署资源(deployments、statefulsets):
apiGroups: ["apps"]
-
网络资源(ingresses):
apiGroups: ["networking.k8s.io"]
(不确定时用
kubectl api-resources | grep <资源名>
查看 API 组)。
-
-
避免过度授权:除非必要,不要使用
cluster-admin
(所有权限),也不要给delete
/update
等高危操作。 -
权限不生效?检查三点:
- Role/Binding 是否创建成功:
kubectl get role -n <ns>
、kubectl get rolebinding -n <ns>
- 主体(Subject)的名称 / 命名空间是否正确;
- 规则(rules)的
apiGroups
/resources
/verbs
是否正确。
- Role/Binding 是否创建成功:
6 总结
RBAC 的核心逻辑是 “先定义权限(Role/ClusterRole),再分配权限(RoleBinding/ClusterRoleBinding) ”,记住:
- 命名空间内的权限:Role + RoleBinding;
- 集群级 / 跨命名空间权限:ClusterRole + ClusterRoleBinding;
- 验证权限用
kubectl auth can-i
,实战优先掌握 “ServiceAccount 给 Pod 授权” 的场景。