我们在前面的章节,讲解了许多K8S中的对象,例如Pods、ConfigMaps、Deployments、Nodes、Secrets、Namespaces等,那如何对他们进行权限管理呢?
假设我们有一个名为 zhangsan 的用户,想相对这些资源拥有权限,首先想到的就是针对每个资源针对用户进行赋权,例如create、get、delete、list、update、edit、watch、exec各种权限,那这时候又来了一个 lisi 的用户,需要想同的权限,那上述操作是不是需要再重复一次。有没有更简单的方法?当然有,首先创建一个用户 zhangsan(User), 然后创建一个角色(Role),最后将它们2个绑定到一次(RoleBinding)。这样后面想创建 lisi 的角色,也只需要创建完用户后,继续绑定到这个角色上即可。
一、RBAC 核心概念与架构
RBAC 是 Kubernetes 中实现细粒度权限管理的核心机制,通过 角色(Role/ClusterRole) 和 绑定(RoleBinding/ClusterRoleBinding) 控制用户、服务账户等主体对集群资源的访问权限,允许管理员通过 Kubernetes API 动态配置策略,要启用RBAC
,需要在 apiserver 中添加参数--authorization-mode=RBAC
,如果使用的kubeadm
安装的集群,目前版本都默认开启了RBAC
,可以通过查看 Master 节点上 kube-apiserver.yaml查看是否启用:
cat /etc/kubernetes/manifests/kube-apiserver.yaml
资源列表:
- Pods
- ConfigMaps
- Deployments
- Nodes
- Secrets
- Namespaces
操作权限:
- create
- get
- delete
- list
- update
- edit
- watch
- exec
角色讲解:
1.角色(Role)
- 作用范围:限定在单个命名空间内,定义对特定资源的操作权限(如 Pod 的增删改查)。
- 示例配置:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: pod-reader
rules:
- apiGroups: [""] # 核心 API 组(如 Pod、Node 等)
resources: ["pods"]
verbs: ["get", "list", "watch"] # 允许的操作类型
2.角色绑定(RoleBinding)
将 Role 或 ClusterRole 绑定到主体(如用户、服务账户),限定在特定命名空间内生效。
- 示例:将
pod-reader
角色绑定至服务账户cicd-sa
:
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: cicd-pod-access
namespace: default
subjects:
- kind: ServiceAccount
name: cicd-sa
roleRef:
kind: Role
name: pod-reader
3.集群角色(ClusterRole)
- 作用范围:全局生效,适用于跨命名空间或集群级资源(如节点、存储卷)。
- 典型场景:授予跨命名空间的 Deployment 只读权限。
- 示例配置
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: cluster-pod-reader
rules:
- apiGroups: [""] # 核心 API 组(如 Pod、Node 等)
resources: ["pods", "nodes"]
verbs: ["get", "list", "watch"] # 允许的操作类型
4.集群角色绑定(ClusterRoleBinding)
赋予主体集群级权限(如管理所有命名空间的 Secrets)。
示例:将 cluster-pod-reader
角色绑定至服务账户 dev-team
:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: cluster-pod-reader-binding
subjects:
- kind: Group
name: dev-team # 用户组名称(需与认证系统集成)
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: cluster-pod-reader # 引用的 ClusterRole 名称
apiGroup: rbac.authorization.k8s.io
通过上面的觉得讲解可以看出来,有两种类型的角色和绑定,一种是Role&RoleBinding,一种是c&ClsterRoleBinding,这两者有什么区别?
其实从字面就可以看出来,前者是角色,后者是集群角色,那后者权限一定是大于前者的。我们将在后面进行讲解。
二、RBAC 应用场景与最佳实践
1.普通用户dev-team,赋予指定权限
场景:企业中存在开发、测试和运维团队,需确保各团队仅能访问其所属命名空间内的资源。这里创建一个dev-team的用户,规定只能访问名为dev的namespace下的pods和services,并且权限只有"get", "list", "create", "delete"
实现方案:
1.创建普通用户:dev-team
-
生成用户私钥与证书签名请求(CSR)
# 生成私钥(2048位RSA密钥)
openssl genrsa -out dev-team.key 2048
# 创建证书签名请求(CN为用户标识,O为用户组)
openssl req -new -key dev-team.key -out dev-team.csr -subj "/CN=dev-team/O=dev-group"
-
使用集群 CA 签发用户证书
# 使用 Kubernetes 集群 CA 签发证书(有效期 365 天)
openssl x509 -req -in dev-team.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -out dev-team.crt -days 365
-
生成 kubeconfig 文件
# 设置集群信息
kubectl config set-cluster kubernetes \
--certificate-authority=/etc/kubernetes/pki/ca.crt \
--embed-certs=true \
--server=https://<API-Server-IP>:6443 \
--kubeconfig=dev-team.kubeconfig
# 添加用户凭证
kubectl config set-credentials dev-team \
--client-certificate=dev-team.crt \
--client-key=dev-team.key \
--embed-certs=true \
--kubeconfig=dev-team.kubeconfig
# 创建上下文并设为默认
kubectl config set-context dev-team-context \
--cluster=kubernetes \
--user=dev-team \
--kubeconfig=dev-team.kubeconfig
kubectl config use-context dev-team-context --kubeconfig=dev-team.kubeconfig
2.创建Role:dev-team-role
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: dev
name: dev-team-role
rules:
- apiGroups: [""]
resources: ["pods", "services"] # 允许访问 Pod 和 Service
verbs: ["get", "list", "watch"] # 仅授予只读权限
3.创建RoleBinging:dev-team-binding
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: dev-team-binding
namespace: dev
subjects:
- kind: User
name: dev-team # 绑定对应的用户名
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: dev-team-role #绑定对应的role名称
apiGroup: rbac.authorization.k8s.io
4. 应用配置
kubectl apply -f dev-team-role.yaml
kubectl apply -f dev-team-binding.yaml
5.权限验证
1. 验证权限范围
# 检查 dev 命名空间 Pod/Service 访问权限
kubectl auth can-i get pods --namespace=dev --kubeconfig=dev-team.kubeconfig # 预期返回 yes
kubectl auth can-i create pods --namespace=dev --kubeconfig=dev-team.kubeconfig # 预期返回 no
# 检查其他命名空间权限
kubectl auth can-i get pods --namespace=prod --kubeconfig=dev-team.kubeconfig # 预期返回 no
2. 实际操作测试
# 查看 dev 命名空间的 Pod 和 Service(成功)
kubectl get pods,svc -n dev --kubeconfig=dev-team.kubeconfig
# 尝试删除 Pod(失败)
kubectl delete pod -n dev nginx-6b9f9cd485-456jb --kubeconfig=dev-team.kubeconfig
Error from server (Forbidden): pods "nginx-6b9f9cd485-456jb" is forbidden: User "dev-team" cannot delete resource "pods" in API group "" in the namespace "dev"
2.超级账号Boss用户,赋予最大权限
场景:老板看大伙办事不力,准备亲自下场,现在要求给他创建一个最大权限的的账号。
1. 生成用户Boss
# 生成私钥(RSA 2048位)
openssl genrsa -out boss.key 2048
# 创建证书签名请求(CN 必须与用户名一致)
openssl req -new -key boss.key -out boss.csr -subj "/CN=boss/O=admin-group"
# 使用集群 CA 签发证书(有效期 365 天)
openssl x509 -req -in boss.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -out boss.crt -days 365
# 生成 kubeconfig 文件
kubectl config set-cluster kubernetes \
--certificate-authority=/etc/kubernetes/pki/ca.crt \
--embed-certs=true \
--server=https://172.21.176.3:6443 \
--kubeconfig=boss.kubeconfig
kubectl config set-credentials boss \
--client-certificate=boss.crt \
--client-key=boss.key \
--embed-certs=true \
--kubeconfig=boss.kubeconfig
kubectl config set-context boss-context \
--cluster=kubernetes \
--user=boss \
--kubeconfig=boss.kubeconfig
kubectl config use-context boss-context --kubeconfig=boss.kubeconfig
2、创建ClusterRole和ClusterRoleClusterRoleBinging
这里可以有两种方式来操作,两种方式任选一种即可
1.创建一个新的new-cluster-admin集群角色,并且手动赋予最大权限
2.选择Kubernetes 默认提供 cluster-admin
集群角色,拥有对所有资源的完全控制权。
2.1 手动创建:
1、创建一个名为new-cluster-admin的最大权限
# cat new-cluster-admin.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: new-cluster-admin
rules:
- apiGroups: ["*"] # 覆盖所有 API 组(包括核心组、apps、networking 等)
resources: ["*"] # 所有资源类型(如 pods、nodes、secrets、services 等)
verbs: ["*"] # 允许所有操作(get、list、create、delete、patch 等)
- nonResourceURLs: ["*"] # 非资源端点(如 /healthz、/metrics、/api 等)
verbs: ["*"] # 允许访问所有非资源 URL
2、绑定new-cluster-admin
# cluster-admin-binding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: boss-cluster-admin
subjects:
- kind: User
name: boss
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: new-cluster-admin # 预置超级管理员角色
apiGroup: rbac.authorization.k8s.io
3、绑定
# kubectl apply -f new-cluster-admin.yaml
clusterrole.rbac.authorization.k8s.io/new-cluster-admin unchanged
# kubectl apply -f new-cluster-admin-binding.yaml
clusterrolebinding.rbac.authorization.k8s.io/boss-cluster-admin created
2.2 绑定内置ClusterRole,通过 ClusterRoleBinding 直接关联用户:
1、直接绑定 cluster-admin-binding
# cluster-admin-binding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: boss-cluster-admin
subjects:
- kind: User
name: boss
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: cluster-admin # 预置超级管理员角色
apiGroup: rbac.authorization.k8s.io
2、绑定cluster-admin-binding
kubectl apply -f cluster-admin-binding.yaml
3、权限验证
3.1. 基础权限检查
# 验证集群级权限
kubectl auth can-i '*' '*' --kubeconfig=boss.kubeconfig # 预期返回 yes
# 验证跨命名空间操作
kubectl auth can-i delete pods -n kube-system --kubeconfig=boss.kubeconfig # 预期返回 yes
3.2. 实际操作测试
# 创建/删除集群级资源(如 Node 查看)
kubectl get nodes --kubeconfig=boss.kubeconfig
# 操作敏感资源(如 Secrets)
kubectl get secrets -n kube-system --kubeconfig=boss.kubeconfig
kubectl delete pod <pod-name> -n kube-system --kubeconfig=boss.kubeconfig
3.两者的区别:
Role:
作用范围:Role 的作用范围限定在特定的命名空间内,例如 dev
或 prod
,仅能控制该命名空间内的资源(如 Pod、Service)的访问权限
可授权的资源类型:授权同一命名空间内的资源操作,例如在 dev
命名空间中管理 Pod 的增删改查
绑定方式与权限复用: RoleBinding 引用 ClusterRole:如网页所述,ClusterRole 可以通过 RoleBinding 绑定到特定命名空间,此时其权限仅在该命名空间生效(例如将集群级角色限制在 prod
命名空间使用)
典型应用场景:授权 dev
命名空间的 ServiceAccount 管理 Deployment(仅限该命名空间)
ClusterRole:
作用范围:ClusterRole 的权限覆盖整个集群,包括所有命名空间、集群级资源(如 Node、PersistentVolume)和非资源端点(如 /healthz
)
可授权的资源类型:可授权集群级资源(如 Node、ClusterRole)和跨命名空间资源(如所有 Secrets),同时支持对非 RESTful API 端点的访问
绑定方式与权限复用: 直接赋予全局权限,例如授权用户查看所有命名空间的 Pod(kubectl get pods --all-namespaces
)
典型应用场景:予全局 Secret 读取权限,或跨命名空间 Pod 监控权限
总结:
- Role:适用于单一命名空间内的细粒度权限控制,例如开发团队的资源隔离。
- ClusterRole:用于全局或跨命名空间的权限需求,如集群管理员、监控工具或跨团队资源共享。
- 选择原则:优先使用 Role 满足最小权限原则,仅在需要跨命名空间或集群级操作时使用 ClusterRole
二、RBAC 工作原理与授权流程
-
权限校验流程
- 请求接收:用户或服务账户通过
kubectl
或 API 发起操作请求。 - 鉴权匹配:API Server 根据 RBAC 规则验证主体是否具备执行操作的权限。
- 权限决策:若权限匹配则放行,否则拒绝并记录审计日志。
- 请求接收:用户或服务账户通过
-
规则定义逻辑
- 资源与操作:通过
apiGroups
、resources
、verbs
字段精确控制可访问的 API 资源及操作类型。 - 例外控制:通过
resourceNames
限制对特定资源实例的操作(如禁止删除critical-config
ConfigMap)。
- 资源与操作:通过
三、RBAC 应用场景与最佳实践
-
典型应用场景
- CI/CD 流水线权限:授予服务账户管理 Pod 的
get/list/watch
权限,支持自动化部署。 - 多团队协作:通过命名空间隔离不同团队的资源访问权限。
- 安全合规:限制运维人员仅能查看日志,禁止修改生产环境资源。
- CI/CD 流水线权限:授予服务账户管理 Pod 的
-
最佳实践
- 最小权限原则:避免使用
verbs: ["*"]
,明确列出所需操作。 - 使用内置角色:优先选择
view
(只读)、edit
(编辑)等预定义角色。 - 定期审计:通过
kubectl auth can-i
检查权限有效性。 - 服务账户管理:为每个微服务创建独立服务账户,避免共享默认
default
账户。
- 最小权限原则:避免使用