Skip to content

Kubernetes-RBAC鉴权

RBAC基于角色(Role)的访问控制(RBAC)是一种基于组织中用户的角色来调节控制对计算机或网络资源的访问的方法。RBAC 鉴权机制使用 rbac.authorization.k8s.io API 组来驱动鉴权决定, 允许你通过 Kubernetes API 动态配置策略。要启用 RBAC,在启动 API 服务器时将 --authorization-mode 参数设置为一个逗号分隔的列表并确保其中包含 RBAC 。

RBAC 核心架构

mermaid
graph LR
    Subject(User/Group/SA) -->|绑定| RoleBinding/ClusterRoleBinding
    RoleBinding -->|引用| Role/ClusterRole
    Role/ClusterRole -->|控制| API资源操作(verbs+resources)

四要素模型

  • Subject(主体)User/ Group/ ServiceAccount
  • Role(角色):定义权限规则(rules
  • ClusterRole(集群角色):非命名空间作用域的Role
  • Binding(绑定):将角色与主体关联

你可以像使用其他 Kubernetes 对象一样, 通过类似 kubectl 这类工具描述或修补 RBAC 对象。

Role 是用来在某个名字空间内设置访问权限; 在你创建 Role 时,你必须指定该 Role 所属的名字空间。

ClusterRole 则是一个集群作用域的资源。这两种资源的名字不同(Role 和 ClusterRole)是因为 Kubernetes 对象要么是名字空间作用域的,要么是集群作用域的,不可两者兼具。

特性RoleClusterRole
作用域单个命名空间内生效集群范围生效(包括非命名空间资源)
绑定方式通过 RoleBinding 绑定可通过 RoleBinding 或 ClusterRoleBinding 绑定
典型用途控制命名空间内资源(如 Pods)控制集群级资源(如 Nodes、StorageClass)或跨命名空间访问

对象定义解析

Role 解析(命名空间级权限)

yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: dev  								# 必须指定命名空间
  name: pod-editor
rules:
- apiGroups: [""]  								# 空字符串表示核心API组(如Pods、Services)
  resources: ["pods", "pods/log"]  				# 资源类型(支持子资源)
  verbs: ["get", "list", "create", "delete"]  	# 操作权限
- apiGroups: ["apps"]
  resources: ["deployments"]
  verbs: ["patch", "update"]

ClusterRole 示例(集群级权限)

yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: cluster-auditor  						# 无需命名空间
rules:
- apiGroups: [""]
  resources: ["nodes", "persistentvolumes"]
  verbs: ["get", "list", "watch"]
- apiGroups: ["rbac.authorization.k8s.io"]
  resources: ["clusterroles", "clusterrolebindings"]
  verbs: ["list"]

RBAC 示例-ClusterRole

这里使用kubernetes-dashboard登录

创建命名空间

bash
kubectl create namespace study

创建 ServiceAccount

bash
cat > demo-user.yaml << "EOF"
apiVersion: v1
kind: ServiceAccount
metadata:
  name: demo-user
  namespace: study
---
apiVersion: v1
kind: Secret
metadata:
  name: demo-user-token
  namespace: study
  annotations:
    kubernetes.io/service-account.name: demo-user  # 关键注解,关联SA
type: kubernetes.io/service-account-token
EOF

# 查看secret
kubectl describe secret demo-user-token -n study

创建 ClusterRole

yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole						# 资源类型:ClusterRole(集群级角色,不限定命名空间)
metadata:
  # 注意:ClusterRole 不应指定 namespace
  name: namespace-reader  				# 角色名称(集群内唯一)
rules:
- apiGroups: [""]  						# 空字符串表示核心API组(如Pods、Services、Namespaces等)
  resources: ["namespaces"]  			# 控制的资源类型(此处为命名空间)
  verbs: ["get", "list", "watch"]  		# 允许的操作(查询/列表/监听)
  # 可选扩展字段:
  # resourceNames: ["study"]  			# 可指定仅对特定命名空间生效

ClusterRoleBinding 关联 SA

yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding				# 资源类型:集群级角色绑定(影响所有命名空间)
metadata:
  name: namespace-reader  				# 绑定规则名称(集群内唯一)
  # 注意:ClusterRoleBinding 不应指定 namespace(此处是无效字段)
  # namespace: study  					# 错误写法(ClusterRoleBinding 无命名空间概念)
subjects:
- kind: ServiceAccount  				# 绑定目标类型(可以是 User/Group/ServiceAccount)
  name: demo-user       				# 服务账户名称
  namespace: study      				# 服务账户所在命名空间
  apiGroup: ""          				# 对于 ServiceAccount 必须设为空字符串
roleRef:
  kind: ClusterRole     				# 引用的角色类型(只能是 ClusterRole)
  name: namespace-reader 				# 引用的 ClusterRole 名称
  apiGroup: rbac.authorization.k8s.io  	# 固定值(必须明确指定)

登录kubernetes-dashboard

bash
# 获取登录token
kubectl describe secret demo-user-token -n study

修改 ClusterRole

权限修改完后需要重新获取token登录

bash
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: namespace-reader
rules:
- apiGroups: [""]
  resources: ["namespaces","pods"]  			# 增加pods资源
  verbs: ["get", "list", "watch", "create"]		# 增加create操作

测试pod

yaml
apiVersion: v1
kind: Pod
metadata:
  name: demo-pod
spec:
  containers:
    - name: demo-pod
      image: nginx
      imagePullPolicy: Never