在 Kubernetes 中,所有资源对象都是通过 API 进行操作,他们保存在
etcd里。而对 etcd 的操作我们需要通过访问kube-apiserver来实现,上面的 Service Account 其实就是 APIServer 的认证过程,而授权的机制是通过RBAC:基于角色的访问控制实现。
在Kubernetes(K8s)集群中,API Server就像“中央大门”,所有操作(比如查看Pod、部署应用、删除资源)都必须经过它。而RBAC(基于角色的访问控制)就是这扇大门的“智能门卫”——它不仅能识别“来访者”身份,还能精准管控“能进哪个区域”“能做什么事”,核心原则是“最小权限”:只给完成工作必需的权限,多余权限一概不给,从根源上降低集群安全风险。
对于新手来说,RBAC看似复杂,但只要抓住“定义权限→分配权限”的核心逻辑,再结合实际场景实操,就能快速掌握。本文将从基础概念、核心组件、实操技巧、高级用法到问题排查,全方位拆解RBAC,让你看完就能用。
一、先搞懂3个基础问题:为什么需要RBAC?
在没有RBAC的情况下,K8s集群可能面临“谁都能操作资源”的混乱局面——开发人员误删生产环境Pod、第三方应用非法访问集群资源等问题时有发生。RBAC的出现就是为了解决这些问题,它的核心价值体现在3点:
- 身份与权限分离:先定义“能做什么”(角色),再分配“谁能做”(绑定),逻辑清晰,便于管理;
- 细粒度控制:可按“命名空间+资源类型+操作动作”精准授权,比如“只允许开发人员在dev命名空间查看Pod,不能删除”;
- 可复用与可扩展:定义好的角色(尤其是ClusterRole)可多次绑定给不同对象,后续修改权限只需调整角色,无需逐个修改分配关系。
简单说,RBAC让K8s集群的权限管理从“粗放式”变成“精细化”,是保障集群安全的核心机制。
二、RBAC四大核心组件:通俗解释+实操示例
RBAC的权限控制靠4个核心API资源实现,分为“定义权限”和“分配权限”两大类。用生活化的比喻理解:Role/ClusterRole是“权限说明书”,明确能做什么;RoleBinding/ClusterRoleBinding是“权限分配单”,明确把说明书发给谁。
(一)核心组件速览表
| 组件类型 | 资源名称 | 作用范围 | 通俗作用 | 适用场景 |
|---|---|---|---|---|
| 定义权限 | Role | 单个命名空间 | 制定“局部权限说明书”:仅在当前命名空间生效 | 给特定命名空间内的资源授权(如dev命名空间的Pod查看权限) |
| 定义权限 | ClusterRole | 整个集群 | 制定“全局权限说明书”:可作用于所有命名空间或集群级资源 | 1. 管理集群级资源(如节点、命名空间);2. 跨命名空间授权(如查看所有命名空间的Pod);3. 复用权限(多个命名空间共用同一套权限规则) |
| 分配权限 | RoleBinding | 单个命名空间 | 发放“局部权限分配单”:把Role或ClusterRole的权限,限定在当前命名空间分配给对象 | 1. 给命名空间内的用户/服务账户分配Role权限;2. 让ClusterRole的权限仅在单个命名空间生效(如让用户仅在test命名空间使用全局只读权限) |
| 分配权限 | ClusterRoleBinding | 整个集群 | 发放“全局权限分配单”:把ClusterRole的权限分配给对象,全集群生效 | 给用户/用户组分配集群级权限(如运维人员的集群管理权限) |
(二)权限三要素:定义权限的“必填项”
不管是Role还是ClusterRole,制定“权限说明书”时必须明确3个要素,少一个都无法生效,就像写说明书要明确“操作对象+操作动作+限定条件”:
- 资源(Resources):要操作的K8s对象,比如Pod、Deployment、Service、Node(节点)、Namespace(命名空间)等;
- 操作(Verbs):对资源的具体动作,常用动作包括:
- 只读类:
get(查询单个资源)、list(列出资源清单)、watch(实时监听资源变化); - 写操作类:
create(创建)、update(更新)、patch(部分更新); -
删除类:
delete(删除单个资源)、deletecollection(删除资源集合,如所有Pod); -
资源名称(ResourceNames,可选):限定权限仅作用于“特定名称的资源”,比如只允许修改名为“prod-app”的Deployment,相当于“说明书的附加条件”。
(三)逐个拆解组件:附完整实操示例(可直接复制)
1. Role:命名空间内的“局部权限说明书”
特点:仅作用于所在的命名空间,无法操作Node等集群级资源,适合“局部资源管控”。
实操示例:在default命名空间创建一个名为pod-ops的Role,允许“查看、创建、更新Pod”,但仅允许删除名为test-pod的Pod(通过ResourceNames限定)。
# 保存为 role-pod-ops.yaml
apiVersion: rbac.authorization.k8s.io/v1 # RBAC固定API版本,直接照抄
kind: Role # 资源类型为Role
metadata:
name: pod-ops # Role名称,自定义
namespace: default # 必须指定命名空间(作用范围)
rules: # 权限规则(可配置多个规则)
- apiGroups: [""] # 核心资源(Pod、Service等)的API组,固定填""
resources: ["pods"] # 操作的资源:Pod
verbs: ["get", "list", "watch", "create", "update", "delete"] # 允许的操作
resourceNames: ["test-pod"] # 仅允许操作名为test-pod的Pod(可选配置)
- apiGroups: [""] # 第二个规则:允许查看所有Pod的日志(不受资源名称限制)
resources: ["pods/log"] # 操作的子资源:Pod日志
verbs: ["get", "list"]
创建命令:执行后Role立即生效
kubectl apply -f role-pod-ops.yaml
验证创建结果:查看default命名空间的Role
kubectl get role -n default
# 输出结果中会显示pod-ops,说明创建成功
2. ClusterRole:集群级的“全局权限说明书”
特点:无命名空间限制,可操作集群级资源(如Node),也可作用于所有命名空间的资源,适合“全局权限复用”。
实操示例:创建一个名为cluster-resource-ops的ClusterRole,允许:1. 查看所有命名空间的Pod、Deployment;2. 查看和创建命名空间;3. 查看节点信息。
# 保存为 clusterrole-resource-ops.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole # 资源类型为ClusterRole
metadata:
name: cluster-resource-ops # 自定义名称,无需指定命名空间
rules:
# 规则1:查看所有命名空间的Pod和Deployment
- apiGroups: ["", "apps"] # ""=核心组(Pod),apps=Deployment所属组
resources: ["pods", "deployments"]
verbs: ["get", "list", "watch"]
# 规则2:查看和创建命名空间(集群级资源)
- apiGroups: [""]
resources: ["namespaces"]
verbs: ["get", "list", "create"]
# 规则3:查看节点信息(集群级资源)
- apiGroups: [""]
resources: ["nodes"]
verbs: ["get", "list"]
创建命令:
kubectl apply -f clusterrole-resource-ops.yaml
验证创建结果:查看集群内所有ClusterRole
kubectl get clusterrole
# 输出结果中会显示cluster-resource-ops
3. RoleBinding:给“局部对象”分配权限
核心作用:把Role或ClusterRole的权限,分给“主体”(权限接收者),且仅在当前命名空间生效。
主体(Subject)类型:权限的接收者有3种,覆盖“外部用户”“内部服务”“用户组”所有场景:
- User:外部用户(如运维人员、开发人员),由K8s外的认证系统管理(如CA证书、LDAP);
- Group:用户组(如“dev-team”组,包含所有开发人员),方便批量授权;
- ServiceAccount:K8s内部的“服务账户”,专门给Pod内的应用使用(比如Pod里的Java程序要调用K8s API,就用这个账户授权)。
实操示例1:绑定Role到ServiceAccount(最常用场景)
把前面创建的pod-ops Role(default命名空间),绑定到default命名空间的my-app-sa服务账户,让Pod内应用拥有对应的Pod操作权限。
# 保存为 rolebinding-pod-ops.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: pod-ops-binding # 自定义名称
namespace: default # 必须和Role在同一个命名空间
subjects: # 权限接收者(主体)
- kind: ServiceAccount # 主体类型:服务账户
name: my-app-sa # 服务账户名称(需提前创建:kubectl create sa my-app-sa -n default)
namespace: default # 服务账户所在命名空间
roleRef: # 引用要分配的Role(固定格式,不能改)
apiGroup: rbac.authorization.k8s.io
kind: Role # 引用的是Role类型
name: pod-ops # 引用的Role名称
创建命令:
kubectl apply -f rolebinding-pod-ops.yaml
实操示例2:绑定ClusterRole到User(限定命名空间)
让外部用户dev-user仅在dev命名空间,拥有cluster-resource-ops ClusterRole的权限(相当于“全局权限局部使用”)。
# 保存为 rolebinding-cluster-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: dev-user-resource-ops
namespace: dev # 限定在dev命名空间生效(需提前创建dev命名空间:kubectl create ns dev)
subjects:
- kind: User # 主体类型:外部用户
name: dev-user # 用户名(需提前通过认证系统创建)
apiGroup: rbac.authorization.k8s.io
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole # 引用ClusterRole
name: cluster-resource-ops # 引用的ClusterRole名称
创建命令:
kubectl apply -f rolebinding-cluster-role.yaml
4. ClusterRoleBinding:给“全局对象”分配权限
核心作用:把ClusterRole的权限分给主体,作用于整个集群(所有命名空间+集群级资源),适合“批量授权全局权限”。
实操示例:给用户组ops-team(运维团队)分配K8s默认的cluster-admin权限(拥有集群内所有操作权限,谨慎使用!),让运维人员能管理整个集群。
# 保存为 clusterrolebinding-ops-admin.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: ops-team-admin-binding # 自定义名称
subjects:
- kind: Group # 主体类型:用户组
name: ops-team # 用户组名称
apiGroup: rbac.authorization.k8s.io
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin # K8s默认ClusterRole,拥有所有权限
创建命令:
kubectl apply -f clusterrolebinding-ops-admin-binding.yaml
三、关键实操:如何验证权限是否生效?(必学)
创建完Role和Binding后,不能凭感觉判断权限是否生效,用kubectl auth can-i命令就能“一键核查”,简单又精准,新手必须掌握!
(一)常用命令格式(直接套用)
| 核查场景 | 命令格式 | 示例 |
|---|---|---|
| 核查当前用户的权限 | kubectl auth can-i <操作> <资源> -n <命名空间> |
核查自己能否在default命名空间创建Pod:kubectl auth can-i create pods -n default |
| 核查指定ServiceAccount的权限 | kubectl auth can-i <操作> <资源> -n <命名空间> --as=system:serviceaccount:<命名空间>:<服务账户名> |
核查default命名空间的my-app-sa能否删除test-pod:kubectl auth can-i delete pods -n default --as=system:serviceaccount:default:my-app-sa |
| 核查跨命名空间权限 | kubectl auth can-i <操作> <资源> --all-namespaces |
核查能否查看所有命名空间的Deployment:kubectl auth can-i list deployments --all-namespaces |
| 核查集群级资源权限 | kubectl auth can-i <操作> <集群资源> |
核查能否查看节点信息:kubectl auth can-i list nodes |
(二)结果说明
- 输出
yes:权限生效,允许执行该操作; - 输出
no:权限未生效,不允许执行; - 输出
unknown:权限配置有误(如主体不存在、API组填错),需排查配置。
(三)进阶核查:查看权限来源
如果想知道“某个权限来自哪个Role/Binding”,可以在命令后加--verbose参数,示例:
kubectl auth can-i get pods -n default --as=system:serviceaccount:default:my-app-sa --verbose
输出结果中会显示权限对应的Role和RoleBinding名称,方便排查权限来源。
四、5个高频实战场景:直接套用,覆盖80%需求
RBAC的核心价值在于“落地到实际场景”,以下5个场景是工作中最常用的,新手可以直接复制配置文件,修改参数即可使用。
场景1:给Pod内应用授权(最核心场景)
Pod内的应用(如Java、Python程序)要调用K8s API(比如获取Pod列表、查看命名空间),必须通过ServiceAccount授权,步骤如下:
1.创建ServiceAccount(在prod命名空间):
kubectl create sa app-api-sa -n prod
2.创建Role(允许在prod命名空间查看Pod和Deployment):
# 保存为 role-app-api.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: app-api-role
namespace: prod
rules:
- apiGroups: ["", "apps"]
resources: ["pods", "deployments"]
verbs: ["get", "list", "watch"]
创建命令:kubectl apply -f role-app-api.yaml
3.创建RoleBinding(绑定Role到ServiceAccount):
# 保存为 rolebinding-app-api.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: app-api-binding
namespace: prod
subjects:
- kind: ServiceAccount
name: app-api-sa
namespace: prod
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: app-api-role
创建命令:kubectl apply -f rolebinding-app-api.yaml
4.部署Pod时指定ServiceAccount:
# 保存为 pod-app-api.yaml
apiVersion: v1
kind: Pod
metadata:
name: app-api-pod
namespace: prod
spec:
serviceAccountName: app-api-sa # 关联前面创建的服务账户
containers:
- name: app-api
image: your-app-image:latest # 替换为你的应用镜像
创建命令:kubectl apply -f pod-app-api.yaml
场景2:给开发人员分配“命名空间只读权限”
需求:让开发人员dev-user仅能在dev命名空间查看Pod、Deployment、Service,不能创建/删除资源,步骤如下:
1.创建ClusterRole(通用只读权限,可复用):
# 保存为 clusterrole-ns-reader.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: ns-reader
rules:
- apiGroups: ["", "apps", "networking.k8s.io"] # 包含核心资源、部署资源、网络资源
resources: ["pods", "deployments", "services", "ingresses"]
verbs: ["get", "list", "watch"]
创建命令:kubectl apply -f clusterrole-ns-reader.yaml
2.创建RoleBinding(绑定到dev-user,限定dev命名空间):
# 保存为 rolebinding-dev-reader.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: dev-user-reader
namespace: dev
subjects:
- kind: User
name: dev-user
apiGroup: rbac.authorization.k8s.io
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ns-reader
创建命令:kubectl apply -f rolebinding-dev-reader.yaml
场景3:给运维人员分配“集群级管理权限”
需求:让运维组ops-team能管理整个集群的资源(包括创建命名空间、管理节点、操作所有命名空间的资源):
直接使用K8s默认的cluster-admin ClusterRole,创建ClusterRoleBinding:
# 保存为 clusterrolebinding-ops-team.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: ops-team-admin
subjects:
- kind: Group
name: ops-team
apiGroup: rbac.authorization.k8s.io
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
创建命令:kubectl apply -f clusterrolebinding-ops-team.yaml
场景4:限制用户仅能操作特定资源(资源名称限定)
需求:让用户test-user仅能修改test命名空间中名为test-app的Deployment,不能操作其他资源:
1.创建Role(限定资源名称):
# 保存为 role-specific-deploy.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: specific-deploy-ops
namespace: test
rules:
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "update", "patch"]
resourceNames: ["test-app"] # 仅允许操作名为test-app的Deployment
创建命令:kubectl apply -f role-specific-deploy.yaml
2.创建RoleBinding(绑定到test-user):
# 保存为 rolebinding-test-user.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: test-user-deploy-ops
namespace: test
subjects:
- kind: User
name: test-user
apiGroup: rbac.authorization.k8s.io
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: specific-deploy-ops
创建命令:kubectl apply -f rolebinding-test-user.yaml
场景5:跨命名空间授权(查看所有命名空间的Pod)
需求:让用户audit-user能查看所有命名空间的Pod(跨命名空间权限):
1.创建ClusterRole(允许查看所有Pod):
# 保存为 clusterrole-all-pod-reader.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: all-pod-reader
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
创建命令:kubectl apply -f clusterrole-all-pod-reader.yaml
2.创建ClusterRoleBinding(绑定到audit-user):
# 保存为 clusterrolebinding-audit-user.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: audit-user-pod-reader
subjects:
- kind: User
name: audit-user
apiGroup: rbac.authorization.k8s.io
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: all-pod-reader
创建命令:kubectl apply -f clusterrolebinding-audit-user.yaml
五、RBAC高级用法:让权限管理更高效
(一)聚合ClusterRole:批量管理相似权限
如果有多个ClusterRole需要统一授权(比如“日志查看”“监控数据读取”等权限),可以用“聚合ClusterRole”把它们整合起来,后续授权只需绑定聚合角色,无需逐个绑定。
示例:创建聚合角色aggregated-monitor,包含log-reader和metrics-reader两个ClusterRole的权限:
# 保存为 clusterrole-aggregated-monitor.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: aggregated-monitor
labels:
rbac.authorization.k8s.io/aggregate-to-monitor: "true" # 聚合标签,用于匹配子角色
rules: [] # 无需配置规则,自动继承匹配标签的ClusterRole权限
创建子角色(需包含相同的聚合标签):
# 日志查看角色
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: log-reader
labels:
rbac.authorization.k8s.io/aggregate-to-monitor: "true" # 匹配聚合标签
rules:
- apiGroups: [""]
resources: ["pods/log"]
verbs: ["get", "list"]
# 监控数据读取角色
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: metrics-reader
labels:
rbac.authorization.k8s.io/aggregate-to-monitor: "true" # 匹配聚合标签
rules:
- apiGroups: ["metrics.k8s.io"]
resources: ["pods", "nodes"]
verbs: ["get", "list"]
后续授权时,只需绑定aggregated-monitor,就能获得两个子角色的所有权限,管理更高效。
(二)ServiceAccount自动挂载令牌
K8s 1.24+版本中,ServiceAccount的令牌不再自动挂载到Pod,需要手动开启“自动挂载”或创建Secret挂载。
方法1:创建ServiceAccount时开启自动挂载
kubectl create sa my-sa -n dev --automount-token=true
方法2:在Pod YAML中指定自动挂载
spec:
serviceAccountName: my-sa
automountServiceAccountToken: true # 开启自动挂载
六、避坑指南:新手常犯的6个错误及解决方案
1. 命名空间不一致(最常见错误)
- 错误表现:Role和RoleBinding不在同一个命名空间,导致权限绑定失效;
- 解决方案:确保Role的
metadata.namespace与RoleBinding的metadata.namespace完全一致,ClusterRole无需指定命名空间。
2. API组填写错误
- 错误表现:权限规则不生效,
kubectl auth can-i返回no; - 原因:不同资源属于不同API组,比如Deployment在
apps组,Ingress在networking.k8s.io组,填错API组会导致规则无效; - 解决方案:不确定资源所属API组时,用以下命令查询:
kubectl api-resources | grep <资源名称>
# 示例:查询Deployment的API组
kubectl api-resources | grep deployments
# 输出结果中“APIGROUP”列即为所属API组(如apps)
3. 过度授权(安全风险)
- 错误表现:给普通用户分配
cluster-admin权限,或给应用分配delete等高危操作权限; - 解决方案:遵循“最小权限原则”,仅分配必需的权限,比如:
- 开发人员:仅给命名空间只读权限;
- 应用程序:仅给需要的资源操作权限(如仅查看Pod,不分配删除权限)。
4. 主体(Subject)信息错误
- 错误表现:权限绑定后,主体无法使用权限;
- 常见错误:
- ServiceAccount的命名空间填错;
- User/Group名称与认证系统中的名称不一致(如LDAP中的用户名拼写错误);
- 解决方案:
- 检查ServiceAccount是否存在:
kubectl get sa -n <命名空间>; - 确认User/Group名称与认证系统(如CA证书、LDAP)中的配置一致。
5. 资源名称(ResourceNames)使用不当
- 错误表现:配置了
resourceNames后,无法操作目标资源; - 常见错误:资源名称拼写错误,或给
list(列清单)操作配置resourceNames(list操作针对资源集合,不能限定单个资源名称); - 解决方案:
- 确认资源名称正确:
kubectl get <资源类型> -n <命名空间>; resourceNames仅适用于单个资源操作(如get、update、delete),不适用于list、watch等集合操作。
6. 权限不生效的排查流程(通用步骤)
如果权限绑定后不生效,按以下步骤排查:
1.检查Role/ClusterRole是否创建成功:kubectl get role -n <命名空间> 或 kubectl get clusterrole;
2.检查RoleBinding/ClusterRoleBinding是否创建成功:kubectl get rolebinding -n <命名空间> 或 kubectl get clusterrolebinding;
3.检查权限规则是否正确:用kubectl describe role <角色名称> -n <命名空间>查看规则(API组、资源、 verbs是否正确);
4.用kubectl auth can-i --verbose命令查看权限来源,确认是否绑定到目标主体;
5.检查是否有其他RBAC规则冲突(如存在更严格的RoleBinding限制了权限)。
七、总结
RBAC的核心逻辑其实很简单:先定义权限(Role/ClusterRole),再分配权限(RoleBinding/ClusterRoleBinding),记住两个核心组合就能应对大部分场景:
- 命名空间内权限:Role + RoleBinding;
- 集群级/跨命名空间权限:ClusterRole + ClusterRoleBinding。
对于新手来说,建议先从“给Pod授权”和“只读权限配置”这两个场景入手,熟悉后再尝试高级用法。实操时多使用kubectl auth can-i命令验证权限,遇到问题按“避坑指南”排查,就能快速掌握RBAC的使用。
RBAC是K8s安全的基础,合理配置RBAC能有效防范非法访问和误操作,保护集群资源安全。随着集群规模扩大,还可以结合K8s的认证系统(如OIDC、LDAP)和网络策略,构建更完善的集群安全体系。
# kubeadm部署的k8s可以在/etc/kubernetes/manifests下查看到静态pod的yaml文件
root@k8s-master01:/etc/kubernetes/manifests# grep authorization kube-apiserver.yaml
- --authorization-mode=Node,RBAC
# Node是专用于向kubelet授权使用。
# RBAC是基于角色的范文控制
常用授权逻辑
DAC(自主访问控制)MAC(强制访问控制)RBAC(基于角色的访问控制)ABAC(基于属性的访问控制)
RBAC
RBAC:Role-Based Access Control

简单来说,就是通过将权限分配给➡角色,再将角色分配给➡用户,来实现对系统资源的访问控制。
在一个组织内把一个组织内应该具有的权限的集合定义成多个角色,然后设定某个用户可以扮演其中1到多个角色。从而让某个用户拥有在组织内的某个授权。
k8s的RBAC是一种许可授权,只允许用户做什么事情,默认拒绝所有。未显示指定授予的权限,默认都会被拒绝。
Role --> Verbs --> Objects
ClusterRole --> Verbs --> Objects
Subject --> RoleBinding --> Roles
Subject --> ClusterRoleBinding --> ClusterRoles
Subject --> RoleBinding --> ClusterRoles
k8s 的 API-Server 是 RESTful 风格的 http/https 服务,其权限无非就是基于http协议所能支持的 GET, POST, PUT, DELETE, PATCH, ...等操作,在 API-Server 上 Object 指的是资源对象。
所谓的权限也就是,Action 能施加到哪些对象上;
RBAC四个资源类型
Role: 角色,名称空间级别;ClusterRole:集群角色,全局级别;RoleBinding:"角色绑定",指是将用户与角色关联起来,意味着,用户仅得到了特定名称空间下的Role的权限,作用范围也限于该名称空间;ClusterRoleBinding:集群角色绑定,让用户扮演指定的集群角色;意味着,用户得到了是集群级别的权限,作用范围也是集群级别;
User --> Rolebindig --> ClusterRole:权限降级,ClusterRole,用户得到的权限仅是 ClusterRole 的权限在 Rolebinding 所属的名称空间上的一个子集;
系统上默认的ROLE
1.查看系统上默认的role
extension-apiserver-authentication-reader 2024-04-15T06:14:01Z
kube-proxy 2024-04-15T06:14:03Z
kubeadm:kubelet-config-1.21 2024-04-15T06:14:01Z
kubeadm:nodes-kubeadm-config 2024-04-15T06:14:01Z
system::leader-locking-kube-controller-manager 2024-04-15T06:14:01Z
system::leader-locking-kube-scheduler 2024-04-15T06:14:01Z
system:controller:bootstrap-signer 2024-04-15T06:14:01Z
system:controller:cloud-provider 2024-04-15T06:14:01Z
system:controller:token-cleaner 2024-04-15T06:14:01Z
2.查看kube-proxy的role中的内容
root@k8s-master01:~# kubectl get role kube-proxy -n kube-system -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
creationTimestamp: "2024-04-15T06:14:03Z"
name: kube-proxy
namespace: kube-system
resourceVersion: "299"
uid: b92871dd-4224-4f31-8fe2-0c4b89ca40ff
rules:
- apiGroups:
- ""
resourceNames:
- kube-proxy
resources:
- configmaps
verbs:
- get
能接受施加Verb的目标有三类:
resources:资源类型,该类型下的所有对象都是目标, pods;resourceNames:特定的对象个体,pods/mypod;nonResourceURLs:非资源型的URL,/status.
能施加的Verb有以下:
- create、get、list、delete、patch、update
RBAC示例
rbac资源清单创建示例
1.使用资源清单来创建role
root@k8s-master01:~/yaml/chapter09# vim pods-reader-rbac.yaml
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: pods-reader
namespace: default
rules:
- apiGroups: [""]
resources: ["pods","services","pods/log"]
verbs: ["get","list","watch"]
2.将其应用到集群上
root@k8s-master01:~/yaml/chapter09# kubectl apply -f pods-reader-rbac.yaml
role.rbac.authorization.k8s.io/pods-reader created
# 角色已经在default名称空间下生成
root@k8s-master01:~/yaml/chapter09# kubectl get role
NAME CREATED AT
pods-reader 2021-08-02T06:44:03Z
3.角色需要将其绑定到用户上
root@k8s-master01:~/yaml/chapter09# vim darius-pods-reader.yaml
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: darius-pods-reader
namespace: default
subjects:
- kind: User
name: darius
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pods-reader
apiGroup: rbac.authorization.k8s.io
4.应用绑定
root@k8s-master01:~/yaml/chapter09# kubectl apply -f darius-pods-reader.yaml
rolebinding.rbac.authorization.k8s.io/darius-pods-reader created
5.使用darius账号进行测试
root@k8s-master01:~/yaml/chapter09# kubectl get pods --kubeconfig=/tmp/newkubeconfig --context=darius@kubernetes
NAME READY STATUS RESTARTS AGE
configmaps-env-demo 1/1 Running 0 17d
configmaps-volume-demo 1/1 Running 0 17d
configmaps-volume-demo2 2/2 Running 0 17d
configmaps-volume-demo3 1/1 Running 0 16d
cronjob-demo-27131450-85h7z 0/1 Completed 0 5m1s
cronjob-demo-27131452-xqqrk 0/1 Completed 0 3m1s
cronjob-demo-27131454-fn7fp 0/1 Completed 0 61s
daemonset-demo-6qqmt 1/1 Running 0 11d
daemonset-demo-fvkhj 1/1 Running 0 11d
daemonset-demo-pxmrd 1/1 Running 0 11d
demodb-0 1/1 Running 0 6d5h
demodb-1 1/1 Running 0 6d5h
deployment-demo-77d46c4794-5whvx 1/1 Running 0 11d
# 已经能正常获取pods资源。
集群管理角色
admin集群管理角色
在 k8s 系统上存在一个 admin 的 ClusterRole,其作用的范围为集群范围,其内部定义了核心资源类型当中的非集群级别资源的管理权限。此 admin 拥有除集群级别之外的所有管理权限。
root@k8s-master01:~/yaml/chapter09# kubectl get clusterrole admin
NAME CREATED AT
admin 2024-04-15T06:13:59Z
如果我们使用 ClusterRolebinding 将某个用户绑定在 admin 这个 ClusterRole 上那么其将拥有除了集群级别管理权限之外的所有管理权限。
cluster-admin集群管理角色
cluster-admin 是集群管理员,其拥有k8s的一切管理权限。
root@k8s-master01:~/yaml/chapter09# kubectl get clusterrole cluster-admin
NAME CREATED AT
cluster-admin 2024-04-15T06:13:59Z
如果将某个用户以 clusterRoleBinding 绑定在 cluster-admin 那其将拥有集群级别的一切操作管理权限。
rbac命令行创建示例
admin集群管理角色绑定示例:
此处为了不予刚才示例混淆,先将 darius 的 role 和 rolebinding 删除
root@k8s-master01:~/yaml/chapter09# kubectl delete rolebindings.rbac.authorization.k8s.io darius-pods-reader
rolebinding.rbac.authorization.k8s.io "darius-pods-reader" deleted
root@k8s-master01:~/yaml/chapter09# kubectl delete role pods-reader
role.rbac.authorization.k8s.io "pods-reader" deleted
1.将用户于admin的clusterRole进行绑定
root@k8s-master01:~/yaml/chapter09# kubectl create clusterrolebinding darius-admin --user=darius --clusterrole=admin
clusterrolebinding.rbac.authorization.k8s.io/darius-admin created
2.使用darius账号进行测试
root@k8s-master01:~/yaml/chapter09# kubectl get pods -n kube-system --kubeconfig=/tmp/newkubeconfig --context=darius@kubernetes
NAME READY STATUS RESTARTS AGE
coredns-6f6b8cc4f6-8wm8v 1/1 Running 0 18d
coredns-6f6b8cc4f6-tzmnm 1/1 Running 0 18d
etcd-k8s-master01 1/1 Running 1 18d
kube-apiserver-k8s-master01 1/1 Running 1 18d
kube-controller-manager-k8s-master01 1/1 Running 1 18d
kube-flannel-ds-dl2rq 1/1 Running 0 18d
kube-flannel-ds-fmml6 1/1 Running 0 18d
kube-flannel-ds-rwh5f 1/1 Running 0 18d
kube-flannel-ds-tqbbv 1/1 Running 0 18d
kube-proxy-6qdpb 1/1 Running 0 18d
kube-proxy-kp5ch 1/1 Running 0 18d
kube-proxy-ntmzb 1/1 Running 0 18d
kube-proxy-vwdm8 1/1 Running 0 18d
kube-scheduler-k8s-master01 1/1 Running 1 18d
此时其能访问到 kube-system 的资源了。但是集群级别的操作依旧不能使用。
# 查看nodes相关资源
root@k8s-master01:~/yaml/chapter09# kubectl get nodes --kubeconfig=/tmp/newkubeconfig --context=darius@kubernetes
Error from server (Forbidden): nodes is forbidden: User "darius" cannot list resource "nodes" in API group "" at the cluster scope
# 权限被拒绝,因为admin的ClusterRole没有此授权。
cluster-admin集群管理角色绑定示例:
将此前创建的admin相关的 clusterrolebinding 进行删除,以免干扰
root@k8s-master01:~/yaml/chapter09# kubectl delete clusterrolebindings darius-admin
clusterrolebinding.rbac.authorization.k8s.io "darius-admin" deleted
3.将darius用户使用clusterRolebinding绑定到cluster-admin这个roles上
root@k8s-master01:~/yaml/chapter09# kubectl create clusterrolebinding darius-cluster-admin --user=darius --clusterrole=cluster-admin
clusterrolebinding.rbac.authorization.k8s.io/darius-cluster-admin created
4.再次测试其能否进行集群级别的操作
root@k8s-master01:~/yaml/chapter09# kubectl get nodes --kubeconfig=/tmp/newkubeconfig --context=darius@kubernetes
NAME STATUS ROLES AGE VERSION
k8s-master01 Ready control-plane,master 18d v1.21.2
k8s-node01 Ready <none> 18d v1.21.2
k8s-node02 Ready <none> 18d v1.21.2
k8s-node03 Ready <none> 18d v1.21.2
授权其他话题
组在k8s中的作用
在k8s中 cluster-admin 是将 system:masters 组绑定在 cluster-admin 之上的。那么组内的所有用户都将拥有此权限。
root@k8s-master01:~/yaml/chapter09# kubectl describe clusterrolebindings.rbac.authorization.k8s.io cluster-admin
Name: cluster-admin
Labels: kubernetes.io/bootstrapping=rbac-defaults
Annotations: rbac.authorization.kubernetes.io/autoupdate: true
Role:
Kind: ClusterRole
Name: cluster-admin
Subjects:
Kind Name Namespace
---- ---- ---------
Group system:masters
对于证书认证来说组信息在Subj中的O内存放,如果其O内存放的为 system:master 那么所创建的用户自动拥有管理员权限,无需再授权。
验证
# 生成私钥文件
root@k8s-master01:/etc/kubernetes/usercerts# (umask 077;openssl genrsa -out testadm.key 2048)
Generating RSA private key, 2048 bit long modulus (2 primes)
.....................................................................................................+++++
............+++++
e is 65537 (0x010001)
# 生成证书签署请求,此处subj中的O使用system:masters
root@k8s-master01:/etc/kubernetes/usercerts# openssl req -new -key testadm.key -out testadm.csr -subj "/CN=testadm/O=system:masters"
# 使用k8s集群的证书和私钥对证书签署请求进行签发
root@k8s-master01:/etc/kubernetes/usercerts# openssl x509 -req -days 3655 -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -in testadm.csr -out testadm.crt
Signature ok
subject=CN = testadm, O = system:masters
Getting CA Private Key
# 以下为制作kubeconfig文件
# 在kubeconfig文件中设定集群
root@k8s-master01:/etc/kubernetes/usercerts# kubectl config set-cluster kubernetes --server=https://kube-api:6443 --embed-certs --certificate-authority=/etc/kubernetes/pki/ca.crt --kubeconfig=/tmp/testadmcfg
Cluster "kubernetes" set.
# 在kubeconfig文件中设定用户
root@k8s-master01:/etc/kubernetes/usercerts# kubectl config set-credentials testadm --client-certificate=testadm.crt --client-key=testadm.key --embed-certs=true --kubeconfig=/tmp/testadmcfg
User "testadm" set.
# 在kubeconfig文件中设定用户和集群的关联关系
root@k8s-master01:/etc/kubernetes/usercerts# kubectl config set-context 'testadm@kubernetes' --user=testadm --cluster=kubernetes --kubeconfig=/tmp/testadmcfg
Context "testadm@kubernetes" created.
# 在kubeconfig文件中设定当前使用的账号
root@k8s-master01:/etc/kubernetes/usercerts# kubectl config use-context testadm@kubernetes --kubeconfig=/tmp/testadmcfg
Switched to context "testadm@kubernetes".
# 当前账号没有进行授权,使用该账号获取集群信息。
root@k8s-master01:/etc/kubernetes/usercerts# kubectl get nodes --kubeconfig=/tmp/testadmcfg
NAME STATUS ROLES AGE VERSION
k8s-master01 Ready control-plane,master 18d v1.21.2
k8s-node01 Ready <none> 18d v1.21.2
k8s-node02 Ready <none> 18d v1.21.2
k8s-node03 Ready <none> 18d v1.21.2
以上结果可以看出证书认证中 O 这一项如果为 system:masters 则无需再进行授权就能对集群进行操作。组这一项对k8s来说至关重要。
rolebinding来绑定ClusterRole
rolebinding 来绑定 ClusterRole 则以为着降级,其会将集群级别的操作限定在名称空间内。
验证
避免干扰先将此前创建的 clusterrolebinding 进行删除
root@k8s-master01:/etc/kubernetes/usercerts# kubectl delete clusterrolebindings darius-cluster-admin
clusterrolebinding.rbac.authorization.k8s.io "darius-cluster-admin" deleted
1.将darius用户使用 rolebinding 绑定到 cluster-admin 这个 ClusterRole 上
root@k8s-master01:/etc/kubernetes/usercerts# kubectl create rolebinding darius-admin --user=darius --clusterrole=cluster-admin
rolebinding.rbac.authorization.k8s.io/darius-admin created
# 注意此处rolebing时没有指定名称空间表示默认名称空间,darius用户的权限会限定在default名称空间下
# 如果指定了名称空间如"-n dev",darius用户则会被限定在dev名称空间下。
2.验证
# 测试访问默认名称空间内的资源
root@k8s-master01:/etc/kubernetes/usercerts# kubectl get svc --kubeconfig=/tmp/newkubeconfig --context=darius@kubernetes
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
demoapp-svc ClusterIP 10.102.254.190 <none> 80/TCP 11d
demodb ClusterIP None <none> 9907/TCP 7d3h
# 访问其他名称空间内的资源
root@k8s-master01:/etc/kubernetes/usercerts# kubectl get svc -n kube-system --kubeconfig=/tmp/newkubeconfig --context=darius@kubernetes
Error from server (Forbidden): services is forbidden: User "darius" cannot list resource "services" in API group "" in the namespace "kube-system"
root@k8s-master01:/etc/kubernetes/usercerts# kubectl get svc -n dev --kubeconfig=/tmp/newkubeconfig --context=darius@kubernetes
Error from server (Forbidden): services is forbidden: User "darius" cannot list resource "services" in API group "" in the namespace "dev"
rolebinding绑定ServiceAccount
创建一个 ServiceAccount,并将其使用 rolebinding 绑定到admin的 ClusterRole 上
# 创建ServiceAccount
root@k8s-master01:/etc/kubernetes/usercerts# kubectl create serviceaccount dev-admin
serviceaccount/dev-admin created
# 创建rolebinding将dev-admin的sa绑定到admin这个ClusterRole上
root@k8s-master01:~# kubectl create rolebinding dev-admin --clusterrole=admin --serviceaccount=dev:dev-admin -n dev
rolebinding.rbac.authorization.k8s.io/dev-admin created
# dev:dev-admin表示dev名称空间下的dev-admin的ServiceAccount
以上操作后,如果有pod的 ServiceAcountName 为 dev-admin 那么此pod将拥有该名称空间下的所有操作权限。