提升CKA考试胜算:一文带你全面了解RBAC权限控制!

云计算
在 Kubernetes 中,RBAC 是一种强大的访问控制机制,用于管理对集群资源的访问权限。

一、RBAC概述

RBAC引入了四个新的顶级资源对象。Role、ClusterRole、RoleBinding、 ClusterRoleBinding。同其他 API 资源对象一样,用户可以使用 kubectl 或者 API 调用等 方式操作这些资源对象。kubernetes集群相关所有的交互都通过apiserver来完成,对于这样集中式管理的系统来说,从1.6版本起,K8S默认启用RBAC访问控制策略,目前RBAC已作为稳定的功能,通过启动文件kube-apiserver.service中的-authorization-mode=RBAC来启用RABC。在RBAC API中,通过如下步骤进行授权:

  • 「定义角色」:在定义角色时会指定此角色对于资源访问控制的规则;
  • 「绑定角色」:将主体与角色进行绑定,对用户进行访问授权;

二、RBAC资源对象

在 Kubernetes 中,RBAC 是一种强大的访问控制机制,用于管理对集群资源的访问权限。RBAC 可以帮助管理员精确地控制用户、ServiceAccount 或其他实体对 Kubernetes API 中资源的操作权限。RBAC 基于角色的授权模型使得管理员可以定义角色和角色绑定,从而实现对不同用户或实体的访问权限控制。RBAC 由四个基本概念组成:

  • 「角色(Role)」:角色定义了一组操作权限,例如对某个命名空间下资源的读取、创建或删除等操作。
  • 「角色绑定(RoleBinding)」:角色绑定将特定的角色授予 User、Group 或者 ServiceAccount,从而赋予它们相应的权限。
  • 「集群角色(ClusterRole)」:类似于角色,但作用范围更广,可以授权对整个集群中资源的操作权限。
  • 「集群角色绑定(ClusterRoleBinding)」:将集群角色绑定给 User、Group 或者 ServiceAccount,授予它们在整个集群范围内的权限。

三、角色

一个角色就是一组权限的集合,这里的权限都是许可形式的,「不存在拒绝的规则」。Role 总是用来在某个名字空间内设置访问权限;在你创建 Role 时,你必须指定该 Role 所属的名字空间。与之相对,ClusterRole 则是一个集群作用域的资源。这两种资源的名字不同(Role 和 ClusterRole) 是因为 Kubernetes 对象要么是名字空间作用域的,要么是集群作用域的,不可两者兼具。ClusterRole 有若干用法。你可以用它来:

  • 定义对某名字空间域对象的访问权限,并将在个别名字空间内被授予访问权限;
  • 为名字空间作用域的对象设置访问权限,并被授予跨所有名字空间的访问权限;
  • 为集群作用域的资源定义访问权限。

如果你希望在名字空间内定义角色,应该使用 Role;如果你希望定义集群范围的角色,应该使用 ClusterRole。

1.Role 示例

(1) 命令方式创建

如果忘记了命令方式,也可以通过kubectl create role --help查阅帮助,如下图:

help

kubectl create role pod-reader \
--verb=get,list,watch \
--resource=pods
  • verb:是指定这个角色包含哪些操作,如get、list、watch
  • resource:是指这个角色能操作哪些资源对象,如pods
  • resource-name:指定对特定资源实例的访问权限。

(2) 资源清单方式创建

下面是一个位于 default 名字空间的 Role 的示例,可用来授予对 Pod 的读访问权限:

apiVersion:rbac.authorization.k8s.io/v1
kind:Role
metadata:
  namespace:default
  name:pod-reader
rules:
-apiGroups:[""]# "" 标明 core API 组
  resources:["pods"]
  verbs:["get","watch","list"]

2.ClusterRole 示例

ClusterRole 同样可以用于授予 Role 能够授予的权限。因为 ClusterRole 属于集群范围,所以它也可以为以下资源授予访问权限:

  • 集群范围资源(比如节点(Node))
  • 非资源端点(比如 /healthz)
  • 跨名字空间访问的名字空间作用域的资源(如 Pod)

比如,你可以使用 ClusterRole 来允许某特定用户执行 kubectl get pods --all-namespaces下面是一个 ClusterRole 的示例,可用来为任一特定名字空间中的 Secret 授予读访问权限, 或者跨名字空间的访问权限(取决于该角色是如何绑定的):

命令行创建:

kubectl create clusterrole  secret-reader \
--verb=get,watch,list \
--resource=secrets

资源清单创建:

apiVersion:rbac.authorization.k8s.io/v1
kind:ClusterRole
metadata:
  # "namespace" 被忽略,因为 ClusterRoles 不受名字空间限制
  name:secret-reader
rules:
-apiGroups:[""]
  # 在 HTTP 层面,用来访问 Secret 资源的名称为 "secrets"
  resources:["secrets"]
  verbs:["get","watch","list"]

三、角色绑定和集群角色绑定

角色绑定(Role Binding)是将角色中定义的权限赋予一个或者一组用户。它包含若干「主体(Subject」)(用户、组或服务账户)的列表和对这些主体所获得的角色的引用。RoleBinding 在指定的名字空间中执行授权,而 ClusterRoleBinding 在集群范围执行授权。一个 RoleBinding 可以引用同一的名字空间中的任何Role。或者,一个RoleBinding可以引用某 ClusterRole并将该 ClusterRole 绑定到 RoleBinding 所在的名字空间。如果你希望将某 ClusterRole绑定到集群中所有名字空间,你要使用ClusterRoleBinding。

RoleBinding 示例

下面的例子中的RoleBinding 将pod-reader Role授予在default名字空间中的用户 jane。这样,用户 jane 就具有了读取 default名字空间中所有Pod的权限。

命令行创建:

 kubectl create rolebinding read-pods \
 --role=pod-reader \
 --user=jance \
 --namespace=default

详细清楚可以使用帮助文件  kubectl create rolebinding --help。

资源清单创建:

apiVersion:rbac.authorization.k8s.io/v1
# 此角色绑定允许 "jane" 读取 "default" 名字空间中的 Pod
# 你需要在该名字空间中有一个名为 “pod-reader” 的 Role
kind:RoleBinding
metadata:
  name:read-pods
  namespace:default
subjects:
# 你可以指定不止一个“subject(主体)”
-kind:User
  name:jane# "name" 是区分大小写的
  apiGroup:rbac.authorization.k8s.io
roleRef:
  # "roleRef" 指定与某 Role 或 ClusterRole 的绑定关系
  kind:Role# 此字段必须是 Role 或 ClusterRole
  name:pod-reader# 此字段必须与你要绑定的 Role 或 ClusterRole 的名称匹配
  apiGroup:rbac.authorization.k8s.io

四、ClusterRoleBinding 示例

要跨整个集群完成访问权限的授予,你可以使用一个ClusterRoleBinding。下面的ClusterRoleBinding 允许manager组内的所有用户访问任何名字空间中的 Secret。

命令行创建:

kubectl create clusterrolebinding read-secrets-global\
--group=manager \
--clusterrole=secret-reader

资源清单创建:

apiVersion:rbac.authorization.k8s.io/v1
# 此集群角色绑定允许 “manager” 组中的任何人访问任何名字空间中的 Secret 资源
kind:ClusterRoleBinding
metadata:
  name:read-secrets-global
subjects:
-kind:Group
  name:manager# 'name' 是区分大小写的
  apiGroup:rbac.authorization.k8s.io
roleRef:
  kind:ClusterRole
  name:secret-reader
  apiGroup:rbac.authorization.k8s.io

五、资源

在Kubernetes API 中,大多数资源都是使用对象名称的字符串表示来呈现与访问的。例如,对于Pod应使用 pods。RBAC 使用对应 API 端点的 URL 中呈现的名字来引用资源。有一些Kubernetes API 涉及子资源(subresource),例如 Pod 的日志。对 Pod 日志的请求看起来像这样:

GET /api/v1/namespaces/{namespace}/pods/{name}/log

在这里,pods 对应名字空间作用域的 Pod 资源,而 log 是 pods 的子资源。在 RBAC 角色表达子资源时,使用斜线(/)来分隔资源和子资源。要允许某主体读取 pods 同时访问这些 Pod 的 log 子资源,你可以这样写:

apiVersion:rbac.authorization.k8s.io/v1
kind:Role
metadata:
  namespace:default
  name:pod-and-pod-logs-reader
rules:
-apiGroups:[""]
  resources:["pods","pods/log"]
  verbs:["get","list"]

对于某些请求,也可以通过 resourceNames 列表按名称引用资源。在指定时,可以将请求限定为资源的单个实例。下面的例子中限制可以 get 和 update 一个名为 my-configmap 的 ConfigMap:

命令行创建:

kubectl create role configmap-updater \
--verb=update,get \
--resource=configmaps \
--resource-name=my-configmap

资源清单创建:

apiVersion:rbac.authorization.k8s.io/v1
kind:Role
metadata:
  namespace:default
  name:configmap-updater
rules:
-apiGroups:[""]
  # 在 HTTP 层面,用来访问 ConfigMap 资源的名称为 "configmaps"
  resources:["configmaps"]
  resourceNames:["my-configmap"]
  verbs:["update","get"]

六、主体

RoleBinding或者ClusterRoleBinding可绑定角色到某「主体(Subject)」 上。主体可以是组,用户或者服务账户。K8s的用户分两种,一种是普通用户,一种是ServiceAccount(服务账户)。

1.普通用户

普通用户是假定被外部或独立服务管理的。管理员分配私钥。平时常用的kubectl命令都是普通用户执行的。如果是用户需求权限,则将Role与User(或Group)绑定(这需要创建User/Group),是给用户使用的。

2.ServiceAccount(服务账户)

ServiceAccount(服务帐户)是由KubernetesAPI管理的用户。它们绑定到特定的命名空间,并由API服务器自动创建或通过API调用手动创建。

服务帐户与存储为Secrets的一组证书相关联,这些凭据被挂载到pod中,以便集群进程与Kubernetes API通信。(登录dashboard时我们使用的就是ServiceAccount)

如果是程序需求权限,将Role与ServiceAccount指定(这需要创建ServiceAccount并且在deployment中指定ServiceAccount),是给程序使用的。

下面示例是RoleBinding中的片段,仅展示其subjects的部分。

对于名称为 alice@example.com 的用户:

subjects:
-kind:User
  name:"alice@example.com"
  apiGroup:rbac.authorization.k8s.io

对于名称为 frontend-admins 的用户组:

subjects:
-kind:Group
  name:"frontend-admins"
  apiGroup:rbac.authorization.k8s.io

对于在任何名字空间中的服务账户:

subjects:
-kind:Group
  name:system:serviceaccounts
  apiGroup:rbac.authorization.k8s.io

七、CKA中的真题

CKA真题

  • 「Context:」为部署流水线创建一个新的 ClusterRole 并将其绑定到范围为特定的 namespace 的特ServiceAccount。
  • 「Task:」创建一个名为 「deployment-clusterrole」 的clusterrole,该 clusterrole 只允许「Deployment、Daemonset、Statefulset」 具有「create」 权限,在现有的namespace app-team1中创建一个名为 「cicd-token」 的新ServiceAccount。
  • 「限于」namespace app-team1 中,将新的 ClusterRole deployment-clusterrole 绑定到新的 ServiceAccount cicd-token。

这题考点是对RBAC授权模型的理解。可以参考官网文档有关RBAC的资料或者使用-h帮助。

#考试时务必执行,切换集群。
kubectl config use-context k8s

#创建一个名称为deployment-clusterrole的clusterrole

kubectl create clusterrole deployment-clusterrole \
-verb=create -resource=deployments,daemonsets,statefulsets

#在命名空间app-team1创建一个名为cicd-token
kubectl create sa  cicd-token -n app-team1

#题目中写了“限于 namespace app-team1 中”,则创建 rolebinding。没有写的话,则创建 clusterrolebinding。
kubectl create rolebinding cicd-token-rolebinding \
--clusterrole=clusterrole 
--serviceaccount=app-team1:cicd-token --namespace=app-team1

# rolebinding 后面的名字 cicd-token-rolebinding 随便起的,因为题目中没有要求,如果题目中有要求,就不能随便起了。

可以通过下面的命令检查:

kubectl -n app-team1 describe rolebindings cicd-token-rolebinding

出现如下图的证明已经创建成功。

责任编辑:赵宁宁 来源: 攻城狮成长日记
相关推荐

2023-11-20 08:18:49

Netty服务器

2022-11-11 19:09:13

架构

2023-11-06 08:16:19

APM系统运维

2023-10-27 08:15:45

2023-11-08 08:15:48

服务监控Zipkin

2022-02-24 07:34:10

SSL协议加密

2019-04-08 15:17:15

Windows操作系统功能

2024-04-15 09:09:54

TimeGPT人工智能算法

2020-02-02 15:14:24

HTTP黑科技前端

2020-10-08 14:32:57

大数据工具技术

2022-04-28 09:22:46

Vue灰度发布代码

2022-09-29 13:09:38

DataClassPython代码

2023-12-06 16:28:56

2022-02-18 10:13:07

SolrElasticSea开源

2023-03-31 08:16:53

Flutter优化内存管理

2018-10-22 08:14:04

2022-09-06 11:21:49

光网络光纤

2019-07-04 15:16:52

数据挖掘大数据算法

2019-08-06 09:00:00

JavaScript函数式编程前端

2023-05-17 11:33:45

梯度下降机器学习
点赞
收藏

51CTO技术栈公众号