核心思想:RBAC 是什么?

简单来说,RBAC 是一种“谁(Who)能对什么(What)资源执行哪些(Which)操作”的授权模式。

想象一下公司的门禁系统:

  • 谁 (Subject) :你(员工)、某个部门(例如“研发部”)、或者一个机器人(例如“CI/CD流水线”)。

  • 能做什么 (Verbs) :进入、离开、锁门、开灯等操作。

  • 什么资源 (Resource) :研发部的办公室、服务器机房、一楼大厅等。

RBAC 就是 Kubernetes 世界里的这套“门禁系统”,它通过 API Server 控制着对集群内所有资源的访问权限。

RBAC 的四大核心组件

RBAC 主要由四个核心的 API 对象组成,理解了这四个对象,你就掌握了 RBAC 的精髓。它们两两一组,分别负责“定义权限”和“授予权限”。

1. 定义权限 (Permissions)

这部分定义了“可以做什么”的规则集合。

  • Role (角色)

    • 作用域命名空间级别 (Namespaced)

    • 描述:一个 Role 只能定义对某个特定命名空间内 的资源进行操作的权限。例如,创建一个名为 pod-reader 的 Role,允许它读取 development 命名空间下的所有 Pods。你无法用它来授予访问集群节点(Node)的权限,因为节点不属于任何命名空间。

    • 包含:一组 rules,每条 rule 由以下三部分组成:

      • apiGroups:资源所属的 API 组(例如 "" 代表核心组,appsbatch 等)。

      • resources:资源类型(例如 pods, deployments, services)。

      • verbs:允许的操作(例如 get, list, watch, create, update, delete)。

  • ClusterRole (集群角色)

    • 作用域集群级别 (Cluster-wide)

    • 描述ClusterRole 的权限不受命名空间限制。它主要用于两种场景:

      1. 授权管理集群级别的资源,例如节点 (nodes)、持久卷 (persistentvolumes)、命名空间本身 (namespaces)。

      2. 定义一套通用的权限模板,可以在多个命名空间中通过 RoleBinding 重复使用。例如,定义一个通用的 admin ClusterRole,然后在每个项目的命名空间里把它授予给项目负责人。

2. 授予权限 (Bindings)

这部分负责将定义好的“角色”绑定给“用户”。

  • RoleBinding (角色绑定)

    • 作用域命名空间级别 (Namespaced)

    • 描述:将一个 Role 或者 ClusterRole 的权限授予给一个或多个主体 (Subject),但这个授权仅在 RoleBinding 所在的命名空间内生效。

    • 关键:即使你绑定的是一个 ClusterRoleRoleBinding 也会将其权限限制在自己的命名空间内。

  • ClusterRoleBinding (集群角色绑定)

    • 作用域集群级别 (Cluster-wide)

    • 描述:将一个 ClusterRole 的权限授予给一个或多个主体 (Subject),这个授权在整个集群的所有命名空间都生效。

    • 注意ClusterRoleBinding 只能绑定 ClusterRole,不能绑定 Role,因为它本身就是集群级别的。

主体 (Subject) 是谁?

RoleBindingClusterRoleBinding 中,被授予权限的主体可以是以下三种:

  1. **User (用户)**:由外部认证系统(如 Keystone、LDAP 或证书)管理的普通用户。Kubernetes 本身不直接管理用户对象。

  2. **Group (用户组)**:和用户一样,由外部认证系统管理的一组用户。

  1. **ServiceAccount (服务账户)**:Kubernetes 内部管理的一种特殊“用户”,主要供集群内的 Pod 使用,让 Pod 中的进程可以与 API Server 安全地交互。

工作流程:如何组合使用?

授权流程非常清晰:

  1. 创建角色:首先,创建一个 RoleClusterRole 来定义一套具体的权限规则(“能做什么”)。

  2. 创建绑定:然后,创建一个 RoleBindingClusterRoleBinding,将这个角色(roleRef)和需要权限的主体(subjects)关联起来。

请求授权检查流程:当一个用户(Subject)发起 API 请求时,API Server 会:

  1. 检查该用户的所有 RoleBindingClusterRoleBinding

  2. 找出这些绑定所关联的 RoleClusterRole

  1. 汇总所有角色中的权限规则。

  2. 判断用户的请求(例如 GET /api/v1/namespaces/dev/pods/my-pod)是否在汇总后的权限范围内。如果在,则允许;否则,拒绝(返回 403 Forbidden)。

实践示例:授予开发者只读权限

假设我们想让一个名为 dev-user 的开发者能够查看 development 命名空间下的所有 Pods,但不能进行修改或删除。

第1步:创建 Role (定义权限)

创建一个名为 pod-reader-role.yaml 的文件:

1
2
3
4
5
6
7
8
9
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-reader # Role 的名字
namespace: development # 关键:指定命名空间
rules:
- apiGroups: [""] # "" 表示核心 API 组
resources: ["pods"] # 资源是 Pods
verbs: ["get", "list", "watch"] # 允许的操作是查看、列出和监视

第2步:创建 RoleBinding (授予权限)

创建一个名为 pod-reader-binding.yaml 的文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: dev-user-read-pods
namespace: development # 关键:绑定也必须在同一个命名空间
subjects:
- kind: User # 主体类型是用户
name: dev-user # 用户名
apiGroup: rbac.authorization.k8s.io
roleRef: # 引用我们上面创建的 Role
kind: Role # 引用的是 Role
name: pod-reader # Role 的名字
apiGroup: rbac.authorization.k8s.io

第3步:应用配置

在终端中执行:

1
2
kubectl apply -f pod-reader-role.yaml
kubectl apply -f pod-reader-binding.yaml

完成!现在 dev-user 就拥有了在 development 命名空间中查看 Pods 的权限。

常用 kubectl 命令

  • 查看权限:检查一个用户是否拥有某个操作的权限。

    1
    2
    3
    # 检查 dev-user 是否可以在 development 命名空间中列出 pods
    kubectl auth can-i list pods --namespace development --as dev-user
    # 如果返回 yes,则有权限;返回 no,则无权限。
  • 查看绑定

    1
    2
    kubectl get rolebindings,clusterrolebindings --all-namespaces
    kubectl describe rolebinding <binding-name> -n <namespace>
  • 创建(命令式)

    1
    2
    3
    4
    5
    # 快速创建一个 Role
    kubectl create role pod-reader --verb=get,list,watch --resource=pods -n development

    # 快速创建一个 RoleBinding
    kubectl create rolebinding dev-user-binding --role=pod-reader --user=dev-user -n development

总结与最佳实践

  • 最小权限原则:始终只授予必要的最小权限。优先使用 RoleRoleBinding,而不是 ClusterRoleClusterRoleBinding

  • 使用 ServiceAccount:对于在 Pod 中运行的应用程序,应为其创建专用的 ServiceAccount 并授予精确的权限,而不是使用 default ServiceAccount。

  • 命名清晰:为 Role 和 Binding 起一个有意义的名字,例如 [namespace]-[subject]-[permission] 的格式,便于管理和审计。

  • 利用 Group:如果可能,将权限授予用户组(Group)而不是单个用户,这样在人员变动时只需调整组成员,而无需修改 RBAC 规则。

RBAC 是 Kubernetes 安全的基石,虽然初看有些复杂,但只要掌握了 Role/ClusterRole (定义权限)RoleBinding/ClusterRoleBinding (授予权限) 这四个核心概念,就能灵活地为你的集群构建一套安全、可靠的权限体系。