写点什么

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

  • 2025-06-09
    福建
  • 本文字数:9207 字

    阅读完需:约 30 分钟

概述


官方文档:


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/v1kind: Rolemetadata:  # 可选,默认为当前命名空间,对应某个空间的操作权限  namespace: default  name: develop-rolerules:  # 规则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 apply 或 kubectl 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.yamlapiVersion: rbac.authorization.k8s.io/v1kind: Rolemetadata:  namespace: default  name: custom-rolerules:  # 规则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.yamlrole.rbac.authorization.k8s.io/custom-role created
复制代码


查看 Role


# 查看Role[root@master ~/role]# kubectl get role -o wideNAME          CREATED ATcustom-role   2025-06-07T06:34:52Z[root@master ~/role]# kubectl describe role custom-roleName:         custom-roleLabels:       <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/v1kind: ClusterRolemetadata:  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.yamlapiVersion: rbac.authorization.k8s.io/v1kind: ClusterRolemetadata:  name: custom-clusterrolerules:  # 规则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.yamlclusterrole.rbac.authorization.k8s.io/custom-clusterrole created
复制代码


查看 ClusterRole


# 查看Role[root@master ~/role]# kubectl get clusterrole custom-clusterroleNAME                 CREATED ATcustom-clusterrole   2025-06-07T06:44:54Z [root@master ~/role]# kubectl describe clusterrole custom-clusterroleName:         custom-clusterroleLabels:       <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 systemNAME                                                                   CREATED ATadmin                                                                  2025-05-24T05:57:58Zcalico-cni-plugin                                                      2025-05-24T05:58:41Zcalico-crds                                                            2025-05-24T05:59:30Zcalico-extension-apiserver-auth-access                                 2025-05-24T05:59:30Zcalico-kube-controllers                                                2025-05-24T05:58:41Zcalico-node                                                            2025-05-24T05:58:41Zcalico-typha                                                           2025-05-24T05:58:40Zcalico-webhook-reader                                                  2025-05-24T05:59:30Zcluster-admin                                                          2025-05-24T05:57:57Zcustom-clusterrole                                                     2025-06-07T06:44:54Zedit                                                                   2025-05-24T05:57:58Zkubeadm:get-nodes                                                      2025-05-24T05:57:59Ztigera-operator                                                        2025-05-24T05:58:37Zview                                                                   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/v1kind: RoleBindingmetadata:  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: ""
复制代码


字段说明

  • metadatanamespace:必填,指定 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/v1kind: ClusterRolemetadata:  name: namespace-pod-readerrules:- apiGroups: [""]  resources: ["pods", "services"]  verbs: ["get", "list", "watch"]  resourceNames: []  # 不限制具体资源名称,作用于整个命名空间 # 通过 RoleBinding 将 ClusterRole 绑定到命名空间apiVersion: rbac.authorization.k8s.io/v1kind: RoleBindingmetadata:  name: clusterrole-binding  namespace: dev-namespaceroleRef:  apiGroup: rbac.authorization.k8s.io  kind: ClusterRole  # 引用集群级角色  name: namespace-pod-readersubjects:- 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/v1kind: ClusterRoleBindingmetadata:  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: ""
复制代码


字段说明


  • metadataname:ClusterRoleBinding 的唯一名称(集群级别)。

  • roleRef 引用要绑定的集群角色,必须是 ClusterRole,不能是普通 Role。ClusterRole 可以是:集群级资源权限(如管理节点、命名空间)。所有命名空间资源的权限(如查看所有命名空间中的 Pod)。非资源端点权限(如 /healthz、/metrics)。

  • subjects 定义被授权的主体,结构与 RoleBinding 相同,但服务账户需指定命名空间(若有)。


Role 和 ClusterRole 的区别



RoleBinding 和 ClusterRoleBinding 的区别



文章转载自:huangSir-devops

原文链接:https://www.cnblogs.com/huangSir-devops/p/18908560

体验地址:http://www.jnpfsoft.com/?from=001YH

用户头像

还未添加个人签名 2023-06-19 加入

还未添加个人简介

评论

发布
暂无评论
一文搞懂K8s中的RBAC认证授权_Kubernetes_不在线第一只蜗牛_InfoQ写作社区