一文搞懂K8s中的RBAC认证授权

概述

官方文档:

Kubernetes作为一个分布式集群的管理工具,保证集群的安全性是其一个重要的任务。所谓的安全性其实就是保证对Kubernetes的各种客户端进行认证和鉴权操作。

在K8S中,当我们试图通过API与集群资源交互时,必定经过集群资源管理对象入口kube-apiserver。显然不是随随便便来一个请求它都欢迎的,每个请求都需要经过合规检查,包括Authentication(身份验证)、Authorization(授权)和Admission Control(准入控制)。通过一系列验证后才能完成交互。

  • Authentication(认证):身份鉴别,只有正确的账号才能够通过认证
  • Authorization(授权): 判断用户是否有权限对访问的资源执行特定的动作
  • Admission Control(准入控制):用于补充授权机制以实现更加精细的访问控制功能。

认证账号分类

在K8S体系中有两种账号类型:

  • User accounts(用户账号),即针对human user的;
  • Service accounts(服务账号),即针对pod的。

这两种账号都可以访问 API server,都需要经历认证、授权、准入控制等步骤

当然,除了上面两种之外,还有一个组的概念,这就是Group,主要是用于将用户或服务账号(ServiceAccount)分组,以便可以对整个组应用统一的权限策略。

认证管理方式

Kubernetes集群安全的最关键点在于如何识别并认证客户端身份,它提供了3种客户端身份认证方式:

HTTP Base认证

这种方式通过通过用户名+密码的方式认证。把"用户名:密码"用BASE64算法进行编码后的字符串放在HTTP请求中的Header Authorization域里发送给服务端。服务端收到后进行解码,获取用户名及密码,然后进行用户身份认证的过程。

HTTP Token认证

这种认证方式是用一个很长的难以被模仿的字符串--Token来表明客户身份的一种方式。每个Token对应一个用户名,当客户端发起API调用请求时,需要在HTTP Header里放入Token,API Server接到Token后会跟服务器中保存的token进行比对,然后进行用户身份认证的过程。

HTTPS认证(推荐!!)

基于CA根证书签名的双向数字证书认证方式,这种认证方式是安全性最高的一种方式,也是生产环境中最常用的一种。但是同时也是操作起来最麻烦的一种方式。

授权管理方式

授权发生在认证成功之后,通过认证就可以知道请求用户是谁, 然后Kubernetes会根据事先定义的授权策略来决定用户是否有权限访问,这个过程就称为授权。

每个发送到ApiServer的请求都带上了用户和资源的信息:比如发送请求的用户、请求的路径、请求的动作等,授权就是根据这些信息和授权策略进行比较,如果符合策略,则认为授权通过,否则会返回错误。

API Server目前支持以下几种授权策略:

  • AlwaysDeny:表示拒绝所有请求,一般用于测试
  • AlwaysAllow:允许接收所有请求,相当于集群不需要授权流程(Kubernetes默认的策略)
  • ABAC:基于属性的访问控制,表示使用用户配置的授权规则对用户请求进行匹配和控制
  • Webhook:通过调用外部REST服务对用户进行授权
  • Node:是一种专用模式,用于对kubelet发出的请求进行访问控制
  • RBAC:基于角色的访问控制(kubeadm安装方式下的默认选项)

RBAC介绍

RBAC(Role-Based Access Control) 基于角色的访问控制,主要是在描述一件事情:给哪些对象授予了哪些权限

其中涉及到了下面几个概念:

  • 对象:User、Groups、ServiceAccount
  • 角色:代表着一组定义在资源上的可操作动作(权限)的集合
  • 绑定:将定义好的角色跟用户绑定在一起

RBAC引入了4个顶级资源对象:

  • Role:普通角色,只能对命名空间内的资源进行授权,需要指定nameapce,可以指定一组权限

  • ClusterRole:集群角色,可以对集群范围内资源、跨namespaces的范围资源、非资源类型进行授权

  • RoleBinding:将 Role 中定义的权限绑定到特定命名空间内的用户、组或服务账户。只能引用同一命名空间中的 Role。若需在多个命名空间使用相同权限,需为每个命名空间创建单独的 RoleBinding。

  • ClusterRoleBinding:将 ClusterRole 中定义的权限绑定到集群范围内的用户、组或服务账户。

RoleBinding和ClusterRoleBinding区别
RoleBinding

将 Role 中定义的权限绑定到特定命名空间内的用户、组或服务账户。

只能引用同一命名空间中的 Role。

若需在多个命名空间使用相同权限,需为每个命名空间创建单独的 RoleBinding。
ClusterRoleBinding

将 ClusterRole 中定义的权限绑定到集群范围内的用户、组或服务账户。

绑定的 ClusterRole 可以是集群级资源(如 Nodes)或非资源型 URL(如/healthz)。

可用于授予跨命名空间的权限(如查看所有命名空间的 Pods)。
ClusterRole 与 RoleBinding 的组合

虽然 ClusterRoleBinding 只能绑定 ClusterRole,但RoleBinding 可以绑定 ClusterRole,此时权限会被限制在 RoleBinding 所在的命名空间内。

Role详解

在 Kubernetes 中,Role 是一种用于定义命名空间(Namespace)内权限的资源对象,属于 RBAC(基于角色的访问控制)系统的核心组件之一。通过 Role,你可以精确控制用户或服务账户对命名空间内资源的操作权限,遵循最小权限原则(Least Privilege Principle)。

定义Role资源清单

示例:

复制代码
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  # 可选,默认为当前命名空间,对应某个空间的操作权限
  namespace: default
  name: develop-role
rules:
  # 规则1:操作核心组和 apps 组的 pods、deployments,仅允许 get 和 list
- apiGroups: ["","apps"]
  resources: ["pods","deployments"]
  verbs: ["get", "list"]
  
  # 规则2:操作核心组和 apps 组的 configmaps、secrets、daemonsets,仅允许 get 和 list
- apiGroups: ["","apps"]
  resources: ["configmaps","secrets","daemonsets"]
  verbs: ["get", "list"]
  
  # 规则3:操作核心组的 secrets,允许 delete 和 create
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["delete","create"]

资源清单详解

rules:权限规则列表,每条规则包含:

  • apiGroups:API 组(如 ""、apps、networking.k8s.io)。
  • resources:资源类型(如 pods、deployments)。
  • verbs:操作权限(如 get、create、delete)。
  • resourceNames(可选):限定特定资源名称(如 web-pod)。
  • nonResourceURLs(可选):非资源 URL(如 /healthz,仅 ClusterRole 支持)。

apiGroups,API 组(分组标识)

作用

  • 用于标识 Kubernetes 资源所属的 API 分组,不同的资源属于不同的 API 组,便于对资源进行分类管理。
  • Kubernetes 将核心资源(如 pods、services)归为 核心组(Core Group),非核心资源(如 deployments、daemonsets)归为 非核心组(如 apps、networking.k8s.io 等)。

取值规则:

  • 核心组(Core Group):
    • apiGroups 取值为 [""](空字符串),对应 Kubernetes API 中的 v1 版本资源。
    • 常见资源:pods、services、configmaps、secrets、namespaces 等。
  • 非核心组:
    • apiGroups 取值为具体的组名(如 apps、batch、networking.k8s.io),对应不同 API 版本的资源。
    • 常见资源:
      • apps 组:deployments、daemonsets、replicasets 等。
      • networking.k8s.io 组:ingresses、networkpolicies 等。
      • batch 组:jobs、cronjobs 等。

示例:

  • apiGroups: [""]:匹配核心组资源(如 pods、secrets)。
  • apiGroups: ["apps"]:匹配 apps 组资源(如 deployments、daemonsets)。
  • apiGroups: ["*"]:匹配 所有 API 组(包括核心组和非核心组),需谨慎使用。集群管理员就是这一个

resources:资源类型(具体操作对象)

作用

  • 定义 允许操作的 Kubernetes 资源类型,需使用资源的 完整名称(不支持简称)。
  • 资源类型需与 apiGroups 配合使用,例如:
    • apiGroups: [""] + resources: ["pods"]:操作核心组的 pods 资源。
    • apiGroups: ["apps"] + resources: ["deployments"]:操作 apps 组的 deployments 资源。

取值规则:

  • 单一资源:直接填写资源全称(如 pods、configmaps)。
  • 资源集合:
    • 使用 * 匹配 同一组下的所有资源(如 resources: ["*"])。

    • 使用 resourceName 匹配 特定名称的资源(需结合 verbs 中的 get、update 等操作)。

      • apiGroups: [""]
        resources: ["pods"]
        resourceNames: ["web-pod"] # 仅操作名为 "web-pod" 的 Pod
        verbs: ["get"]

verbs:操作权限(允许的动作)

作用

  • 定义 对指定资源允许执行的操作,用于控制用户或服务账户的行为权限。

常见 verbs 分类

  • 基础操作:

    • get:获取单个资源,如 kubectl get pod <name>
    • list:列出资源列表,如 kubectl list pods
    • create:创建资源,如 kubectl create pod
    • update:更新资源,如 kubectl applykubectl edit
    • delete:删除资源,如 kubectl delete pod <name>
  • 高级操作:

    • patch:部分更新资源,如 kubectl patch pod <name> -p '{"spec": {...}}')
    • watch:监控资源变化,如 kubectl get pods --watch
    • exec:进入 Pod 执行命令,如 kubectl exec -it <pod> /bin/sh
    • connect:建立连接,如 kubectl port-forward
  • 特殊操作:

  • *:允许所有操作(需谨慎使用)。

  • list 和 watch 通常配合使用,用于实现资源监控(如 Dashboard 或控制器)。

示例:

  • verbs: ["get", "list"]:允许查看资源(获取单个或列表)。
  • verbs: ["create", "delete"]:允许创建和删除资源。
  • verbs: ["*"]:允许对资源执行所有操作(危险操作,仅用于测试或管理员角色)。

Role实战

复制代码
# 定义Role
[root@master ~/role]# cat role-default.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: custom-role
rules:
  # 规则1:操作核心组和 apps 组的 pods、deployments,仅允许 get 和 list
- apiGroups: ["","apps"]
  resources: ["pods","deployments"]
  verbs: ["get", "list"]

  # 规则2:操作核心组和 apps 组的 configmaps、secrets、daemonsets,仅允许 get 和 list
- apiGroups: ["","apps"]
  resources: ["configmaps","secrets","daemonsets"]
  verbs: ["get", "list"]

  # 规则3:操作核心组的 secrets,允许 delete 和 create
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["delete","create"]

# 创建Role
[root@master ~/role]# kubectl apply -f role-default.yaml
role.rbac.authorization.k8s.io/custom-role created

查看Role

复制代码
# 查看Role
[root@master ~/role]# kubectl get role -o wide
NAME          CREATED AT
custom-role   2025-06-07T06:34:52Z
[root@master ~/role]# kubectl describe role custom-role
Name:         custom-role
Labels:       <none>
Annotations:  <none>
PolicyRule:
  Resources         Non-Resource URLs  Resource Names  Verbs
  ---------         -----------------  --------------  -----
  secrets           []                 []              [get list delete create]
  configmaps        []                 []              [get list]
  daemonsets        []                 []              [get list]
  deployments       []                 []              [get list]
  pods              []                 []              [get list]
  configmaps.apps   []                 []              [get list]
  daemonsets.apps   []                 []              [get list]
  deployments.apps  []                 []              [get list]
  pods.apps         []                 []              [get list]
  secrets.apps      []                 []              [get list]

ClusterRole详解

在 Kubernetes 中,ClusterRole 是一种用于定义集群级别权限的资源对象,属于 RBAC(基于角色的访问控制)系统的核心组件之一。与只能作用于单个命名空间的 Role 不同,ClusterRole 可以跨命名空间授权,或用于集群级资源(如节点、命名空间)的访问控制。

核心概念

ClusterRole 是一个 集群级别的资源,用于定义对 集群范围资源 或 非资源 URL 的操作权限。

可以用于以下场景:

  • 对集群级资源(如 Node、PersistentVolume)的访问控制。
  • 对所有命名空间资源(如 Pod、Deployment)的跨命名空间访问。
  • 对非资源端点(如 /healthz、/metrics)的访问控制。

ClusterRole资源清单文件

ClusterRole资源清单文件和上述Role是一致的

复制代码
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: <clusterrole-name>  # ClusterRole 的名称
rules:
- apiGroups: [""]  # API 组列表
  resources: ["nodes"]  # 资源类型列表(集群级资源)
  verbs: ["get", "list", "watch"]  # 操作权限
- apiGroups: ["apps"]
  resources: ["deployments"]
  verbs: ["*"]  # 所有操作权限
  resourceNames: ["backend"]  # 可选,限定特定资源名称
- nonResourceURLs: ["/healthz", "/metrics"]  # 非资源 URL(仅 ClusterRole 支持)
  verbs: ["get"]

ClusterRole实战

复制代码
# 定义ClusterRole
[root@master ~/role]# cat ClusterRole-1.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: custom-clusterrole
rules:
  # 规则1:操作核心组和 apps 组的 pods、deployments,仅允许 get 和 list
- apiGroups: ["","apps"]
  resources: ["pods","deployments"]
  verbs: ["get", "list"]

  # 规则2:操作核心组和 apps 组的 configmaps、secrets、daemonsets,仅允许 get 和 list
- apiGroups: ["","apps"]
  resources: ["configmaps","secrets","daemonsets"]
  verbs: ["get", "list"]

  # 规则3:操作核心组的 secrets,允许 delete 和 create
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["delete","create"]


# 创建Role
[root@master ~/role]# kubectl apply -f ClusterRole-1.yaml
clusterrole.rbac.authorization.k8s.io/custom-clusterrole created

查看ClusterRole

复制代码
# 查看Role
[root@master ~/role]# kubectl get clusterrole custom-clusterrole
NAME                 CREATED AT
custom-clusterrole   2025-06-07T06:44:54Z

[root@master ~/role]# kubectl describe clusterrole custom-clusterrole
Name:         custom-clusterrole
Labels:       <none>
Annotations:  <none>
PolicyRule:
  Resources         Non-Resource URLs  Resource Names  Verbs
  ---------         -----------------  --------------  -----
  secrets           []                 []              [get list delete create]
  configmaps        []                 []              [get list]
  daemonsets        []                 []              [get list]
  deployments       []                 []              [get list]
  pods              []                 []              [get list]
  configmaps.apps   []                 []              [get list]
  daemonsets.apps   []                 []              [get list]
  deployments.apps  []                 []              [get list]
  pods.apps         []                 []              [get list]
  secrets.apps      []                 []              [get list]

集群中默认的ClusterRole

复制代码
[root@master ~/role]# kubectl get clusterrole | grep -v system
NAME                                                                   CREATED AT
admin                                                                  2025-05-24T05:57:58Z
calico-cni-plugin                                                      2025-05-24T05:58:41Z
calico-crds                                                            2025-05-24T05:59:30Z
calico-extension-apiserver-auth-access                                 2025-05-24T05:59:30Z
calico-kube-controllers                                                2025-05-24T05:58:41Z
calico-node                                                            2025-05-24T05:58:41Z
calico-typha                                                           2025-05-24T05:58:40Z
calico-webhook-reader                                                  2025-05-24T05:59:30Z
cluster-admin                                                          2025-05-24T05:57:57Z
custom-clusterrole                                                     2025-06-07T06:44:54Z
edit                                                                   2025-05-24T05:57:58Z
kubeadm:get-nodes                                                      2025-05-24T05:57:59Z
tigera-operator                                                        2025-05-24T05:58:37Z
view                                                                   2025-05-24T05:57:58Z

其中主要关注这四个

  • admin:主要用于授权命名空间的读写权限
  • cluster-admin:超级管理员,拥有集群的所有权限
  • edit:允许对大多数对象读写操作,不允许查看或者修改角色,角色绑定。
  • view:允许对命名空间大多数对象只读权限,不允许查看角色,角色绑定和secret

RoleBinding详解

在 Kubernetes(K8s)中,RoleBinding 是实现权限控制(RBAC,Role-Based Access Control)的核心资源之一,用于将角色(Role)与用户、服务账户或组关联起来,从而赋予其对特定资源的操作权限。

RoleBinding 仅在单个命名空间内生效,用于授予对命名空间内资源的访问权限(如 Pod、Service 等)。

若需跨命名空间或集群级权限(如管理节点、命名空间本身),需使用 ClusterRoleBinding(关联 ClusterRole)。

作用

将 Role(角色)定义的权限授予 主体(Subjects),主体可以是:

  • 用户账户(User Accounts):K8s 中的外部用户(如管理员、开发人员),通常通过认证插件(如 X509、OIDC)管理。
  • 服务账户(Service Accounts):K8s 内部用于 Pod 中容器访问 API 的账户,自动创建于命名空间中。
  • 组(Groups):用户组(如通过认证插件定义的组),用于批量授权。

RoleBinding资源清单文件

复制代码
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: developer-rolebinding  # RoleBinding 名称
  namespace: dev-namespace   # 作用的命名空间
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role         # 引用的角色类型(必须是 Role 或 ClusterRole)
  name: developer    # 引用的角色名称
subjects:          # 被授权的主体列表
- kind: User        # 主体类型(User/ServiceAccount/Group)
  name: alice       # 主体名称
  apiGroup: ""      # User 和 Group 的 apiGroup 为空
- kind: ServiceAccount
  name: my-app-sa
  namespace: dev-namespace  # 服务账户所在的命名空间(若与 RoleBinding 同命名空间可省略)
- kind: Group
  name: my-group            # 组名
  apiGroup: ""

字段说明

  • metadata
    • namespace:必填,指定 RoleBinding 生效的命名空间。
    • name:RoleBinding 的唯一名称。
  • roleRef:引用要绑定的角色,支持两种类型:
    • Role:命名空间内的角色,授予对该命名空间内资源的权限。
    • ClusterRole:集群级角色,可通过 RoleBinding 绑定到命名空间,授予该命名空间内资源的权限(需角色定义中包含命名空间作用域的规则)。
  • subjects:定义被授权的主体,每个主体包含:
    • kind:主体类型,取值为 User、ServiceAccount 或 Group。
    • name:主体名称(如用户名、服务账户名、组名)。
    • namespace:仅当主体为服务账户且与 RoleBinding 不在同一命名空间时需指定。

RoleBinding与ClusterRole

虽然 RoleBinding 通常绑定 Role,但也可以绑定 ClusterRole,前提是该 ClusterRole 的规则适用于命名空间内的资源。例如:

复制代码
# 使用 ClusterRole 定义命名空间内权限
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: namespace-pod-reader
rules:
- apiGroups: [""]
  resources: ["pods", "services"]
  verbs: ["get", "list", "watch"]
  resourceNames: []  # 不限制具体资源名称,作用于整个命名空间

# 通过 RoleBinding 将 ClusterRole 绑定到命名空间
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: clusterrole-binding
  namespace: dev-namespace
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole  # 引用集群级角色
  name: namespace-pod-reader
subjects:
- kind: User
  name: charlie
  apiGroup: ""

ClusterRoleBinding详解

在 Kubernetes(K8s)中,ClusterRoleBinding 是实现集群级权限控制的核心资源,用于将集群级角色(ClusterRole)与用户、服务账户或组关联,从而赋予其跨命名空间或集群级资源的访问权限。

ClusterRoleBinding 不局限于单个命名空间,而是对整个集群生,可用于授权对集群级资源(如 Nodes、Namespaces、PersistentVolumes)或所有命名空间资源(如所有 Pod、ConfigMaps)的访问。

作用

将 ClusterRole 定义的权限授予 主体(Subjects),主体可以是:

  • 用户账户(User Accounts):K8s 中的外部用户(如集群管理员)。
  • 服务账户(Service Accounts):K8s 内部用于 Pod 中容器访问 API 的账户。
  • 组(Groups):用户组(如通过认证插件定义的组)。

ClusterRoleBinding资源清单文件

复制代码
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: cluster-admin-binding  # ClusterRoleBinding 名称
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole  # 必须是 ClusterRole
  name: cluster-admin  # 引用的 ClusterRole 名称
subjects:
- kind: User        # 主体类型
  name: admin-user  # 用户名
  apiGroup: ""
- kind: Group
  name: system:serviceaccounts  # 所有服务账户所在的组
  apiGroup: ""

字段说明

  • metadata
    • name:ClusterRoleBinding 的唯一名称(集群级别)。
  • roleRef
    • 引用要绑定的集群角色,必须是 ClusterRole,不能是普通 Role。
    • ClusterRole 可以是:
      • 集群级资源权限(如管理节点、命名空间)。
      • 所有命名空间资源的权限(如查看所有命名空间中的 Pod)。
      • 非资源端点权限(如 /healthz、/metrics)。
  • subjects
    • 定义被授权的主体,结构与 RoleBinding 相同,但服务账户需指定命名空间(若有)。

Role和ClusterRole的区别

特性 Role ClusterRole
作用范围 单个命名空间内 集群范围(所有命名空间或集群级资源)
定义位置 属于命名空间资源(需指定 namespace) 集群级资源(无需 namespace 字段)
可授权的资源类型 命名空间内资源(如 Pod、Service) 1. 集群级资源(如 Nodes、Namespaces) 2. 所有命名空间的资源(如所有 Pod) 3. 非资源端点(如 /healthz、/metrics)
绑定方式 通过 RoleBinding 绑定到主体 1. 通过 RoleBinding 绑定到单个命名空间(需角色规则适用于命名空间资源) 2. 通过 ClusterRoleBinding 绑定到整个集群
典型场景 授权命名空间内的操作(如开发人员管理自己命名空间的资源) 1. 集群管理员权限 2. 跨命名空间操作 3. 访问集群级资源

RoleBinding和ClusterRoleBinding的区别

特性 RoleBinding ClusterRoleBinding
作用范围 单个命名空间内 集群范围(所有命名空间或集群级资源)
绑定的角色类型 1. Role(命名空间内角色) 2. ClusterRole(需角色规则适用于命名空间资源) 仅 ClusterRole(集群级角色)
定义位置 属于命名空间资源(需指定 namespace) 集群级资源(无需 namespace 字段)
典型场景 授权用户/服务账户操作特定命名空间内的资源(如开发人员管理 dev 命名空间的 Pod) 1. 集群管理员权限 2. 跨命名空间操作 3. 访问集群级资源(如 Nodes)