基于角色的访问控制:RBAC
RBAC(Role-Based Access Control,基于角色的访问控制)是一种新型、灵活且使用广泛的访问控制机制,它将权限授予 "角色"(role)之上。
一、RBAC授权插件
RBAC 是一种操作授权机制,用于界定 "谁"(subject)能够或不能够 "操作"(verb)哪个或哪类 "对象"(Object)。动作的发出者即 "主体",通常以 "帐号" 为载体,它既可以是常规用户(User Account),也可以是服务帐号(Service Account)。"操作"(verb)用于表明要执行的具体操作,包括创建、删除、修改和查看等,对应于 kubectl 来说,它通常由 create、apply、delete、update、path、edit 和 get 等子命令来给出。而 "客体" 则是指操作施加于的目标实体,对 Kubernetes API 来说主要是指各类的资源对象以及非资源型 URL。
相对于 ABAC 和 Webhook 等授权机制来说,RBAC 具有如下优势:
- 对集群中的资源和非资源型 URL 的权限实现了完整覆盖。
- 整个 RBAC 完全由少数几个 API 对象实现,而且同其他 API 对象一样可以用 kubectl 或 API 调用进行操作。
- 支持权限的运行时调整,无须重新启动 API Server。
RBAC 授权插件支持 Role 和 ClusterRole 两类角色,其中 Role 作用于名称空间级别,用于定义名称空间资源权限集合,而 ClusterRole 则用于组织集群级别的资源权限集合,它们都是标准的 API 资源类型。
对这两类角色进行赋权时,需要用到 RoleBinding 和 ClusterRoleBinding 这两种资源类型。
-
- RoleBinding 用于将 Role 上的许可权限绑定到一个或一组用户上,它隶属于且仅能作用于一个名称空间。绑定时,可以引用同一名称中的 Role,也可以引用集群级别的 ClusterRole。
- ClusterRoleBinding 用于把 ClusterRole 中定义的许可权限绑定在一个或一组用户之上,它仅可以引用集群级别的 ClusterRole。
一个名称空间中可以包含多个 Role 和 RoleBinding 对象,类似地,集群级别也可以同时存在多个 ClusterRole 和 ClusterRoleBinding对象。一个账户也可经由 RoleBinding 或 ClusterRoleBinding 关联至多个角色,从而具有多重许可授权。
二、Role 和 RoleBinding
Role 仅是一组许可(permission)权限的集合,它描述了对哪些资源可执行何种操作。资源配置清单中使用 rules 字段嵌套授权规则。下面是一个定义在 testing 名称空间中的 Role 对象的配置清单示例,它设定了读取、列出及监视 Pod 和 Service 资源的许可权限。
下面是一个定义在 default 名称空间中的 admin Role 对象的配置清单示例。它设定了读取、列出及监视 Pod 和 Service 资源许可权限:
[root@k8s-master01-test-2-26 ~]# kubectl get role
NAME CREATED AT
admin 2022-07-01T02:31:15Z
operator 2022-07-01T02:31:14Z
role-template-manage-alerting-messages 2022-07-01T02:31:14Z
role-template-manage-alerting-policies 2022-07-01T02:31:15Z
role-template-manage-app-workloads 2022-07-01T02:31:15Z
role-template-manage-configmaps 2022-07-01T02:31:15Z
role-template-manage-custom-monitoring 2022-07-01T02:31:14Z
role-template-manage-members 2022-07-01T02:31:14Z
role-template-manage-project-settings 2022-07-01T02:31:14Z
role-template-manage-roles 2022-07-01T02:31:14Z
role-template-manage-secrets 2022-07-01T02:31:13Z
role-template-manage-serviceaccount 2022-07-01T02:31:15Z
role-template-manage-snapshots 2022-07-01T02:31:13Z
role-template-manage-volumes 2022-07-01T02:31:14Z
role-template-view-alerting-messages 2022-07-01T02:31:14Z
role-template-view-alerting-policies 2022-07-01T02:31:14Z
role-template-view-app-workloads 2022-07-01T02:31:15Z
role-template-view-basic 2022-07-01T02:31:15Z
role-template-view-configmaps 2022-07-01T02:31:15Z
role-template-view-custom-monitoring 2022-07-01T02:31:13Z
role-template-view-members 2022-07-01T02:31:14Z
role-template-view-roles 2022-07-01T02:31:14Z
role-template-view-secrets 2022-07-01T02:31:14Z
role-template-view-serviceaccount 2022-07-01T02:31:13Z
role-template-view-snapshots 2022-07-01T02:31:14Z
role-template-view-volumes 2022-07-01T02:31:14Z
viewer 2022-07-01T02:31:14Z
[root@k8s-master01-test-2-26 ~]# kubectl get role/admin -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
annotations:
iam.kubesphere.io/aggregation-roles: '["role-template-view-members","role-template-manage-members",
"role-template-view-roles","role-template-manage-roles", "role-template-view-app-workloads","role-template-manage-app-workloads",
"role-template-view-volumes","role-template-manage-volumes", "role-template-view-snapshots","role-template-manage-snapshots",
"role-template-view-secrets","role-template-manage-secrets", "role-template-view-serviceaccount","role-template-manage-serviceaccount",
"role-template-view-configmaps","role-template-manage-configmaps", "role-template-view-alerting-policies","role-template-manage-alerting-policies",
"role-template-view-alerting-messages","role-template-manage-alerting-messages",
"role-template-view-custom-monitoring","role-template-manage-custom-monitoring",
"role-template-view-pipelines","role-template-manage-pipelines", "role-template-view-pipelineruns","role-template-manage-pipelineruns",
"role-template-view-credentials","role-template-manage-credentials", "role-template-view-gitrepositories","role-template-manage-gitrepositories",
"role-template-view-gitops-applications","role-template-manage-gitops-applications",
"role-template-manage-project-settings","role-template-manage-devops-settings"]'
kubesphere.io/creator: system
creationTimestamp: "2022-07-01T02:31:15Z"
name: admin
namespace: default
resourceVersion: "7711"
uid: 5b32875d-04a4-43ca-95ff-181b9b3ef954
rules:
- apiGroups:
- '*'
resources:
- '*'
verbs:
- '*'
[root@k8s-master01-test-2-26 ~]#
类似上面的 Role 对象中的 rules 也称为 PolicyRule,用于定义策略规则,不过它不包含规则应用的目标,其可以内嵌的字段包含如下几个:
[root@k8s-master01-test-2-26 ~]# kubectl explain role
KIND: Role
VERSION: rbac.authorization.k8s.io/v1
DESCRIPTION:
Role is a namespaced, logical grouping of PolicyRules that can be
referenced as a unit by a RoleBinding.
FIELDS:
apiVersion <string>
APIVersion defines the versioned schema of this representation of an
object. Servers should convert recognized schemas to the latest internal
value, and may reject unrecognized values. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
kind <string>
Kind is a string value representing the REST resource this object
represents. Servers may infer this from the endpoint the client submits
requests to. Cannot be updated. In CamelCase. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
metadata <Object>
Standard object's metadata.
rules <[]Object>
Rules holds all the PolicyRules for this Role
[root@k8s-master01-test-2-26 ~]#
[root@k8s-master01-test-2-26 ~]# kubectl explain role.rules
KIND: Role
VERSION: rbac.authorization.k8s.io/v1
RESOURCE: rules <[]Object>
DESCRIPTION:
Rules holds all the PolicyRules for this Role
PolicyRule holds information that describes a policy rule, but does not
contain information about who the rule applies to or which namespace the
rule applies to.
FIELDS:
apiGroups <[]string>
APIGroups is the name of the APIGroup that contains the resources. If
multiple API groups are specified, any action requested against one of the
enumerated resources in any API group will be allowed.
nonResourceURLs <[]string>
NonResourceURLs is a set of partial urls that a user should have access to.
*s are allowed, but only as the full, final step in the path Since
non-resource URLs are not namespaced, this field is only applicable for
ClusterRoles referenced from a ClusterRoleBinding. Rules can either apply
to API resources (such as "pods" or "secrets") or non-resource URL paths
(such as "/api"), but not both.
resourceNames <[]string>
ResourceNames is an optional white list of names that the rule applies to.
An empty set means that everything is allowed.
resources <[]string>
Resources is a list of resources this rule applies to. '*' represents all
resources.
verbs <[]string> -required-
Verbs is a list of Verbs that apply to ALL the ResourceKinds contained in
this rule. '*' represents all verbs.
[root@k8s-master01-test-2-26 ~]#
-
- apiGroups <[]string>: 包含了资源的 API 组的名称,支持列表格式指定的多个组,空串("")表示核心组。
- resourceNames <[]string>: 规则应用的目标资源名称列表,可选,缺省时意味着指定资源类型下的所有资源。
- resources <[]string>: 规则应用的目标资源类型组成的列表,例如 pods、deployments、daemonsets、roles等,ResourceAll 表示所有资源。
- verbs <[]string> -required-: 可应用至此规则匹配到所有资源类型的操作列表,可用选项有 get 、list、create、update、patch、watch、proxy、redirect、delete 和 deletecollection;此为必选字段。
- nonResourceURLs <[]string>: 用于定义用户应该有权限访问的网址列表,它并非名称空间级别的资源,因此只能应用于 ClusterRole 和 ClusterRoleBinding,在 Role 中提供此字段目的仅为与 ClusterRole 在格式上兼容。
如果需要支持子资源(subresource),例如 Pod 对象的 /log,Node 对象的 /status 等,它们的 URL 格式通常形式如下表示:
GET /api/v1/namespaces/{namespace}/pods/{name}/log
在 RBAC 角色定义中,如果要引用这种类型的子资源,则需要使用 "resource/subresource" 的格式,如上面示例规则中的 "pods/log"。另外,还可以通过直接给定资源名称(resourceName)来引用特定的资源,此时支持使用的操作通常仅为 get、delete、update 和 patch,也可使用这四个操作的子集实现更小范围的可用操作权限。
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: pods-reader
rules:
- apiGroups:
- '*'
resources:
- 'pods'
'pods/log'
verbs:
- 'get'
- 'list'
- 'watch'
[root@k8s-master01-test-2-26 ~]# kubectl create role service-admin --verb="*" --resource="service,services/**" -n default
role.rbac.authorization.k8s.io/service-admin created
[root@k8s-master01-test-2-26 ~]#
将清单中的 Role 资源也创建于集群上之后,default 名称空间中就有了 pods-reader 和 services-admin 两个角色:
[root@k8s-master01-test-2-26 ~]# kubectl get role |egrep "pods-reader|service-admin"
pods-reader 2022-07-03T09:12:59Z
service-admin 2022-07-03T08:48:46Z
[root@k8s-master01-test-2-26 ~]#
角色本身并不能作为动作的执行主体,它们需要 "绑定"(RoleBinding)到主体(如 user、group 或 service account)之上才能发生作用。
RoleBinding 用于将 Role 中定义的权限赋予给一个或一组用户,它由一组主体,以及一个要引用来赋予这组主体的 Role 或 ClusterRole 组成。
RoleBinding 仅能够引用同一名称空间中的 Role 对象完成授权。例如,下面配置清单中的 RoleBinding 于 default 名称空间中将 pods-reader 角色赋予给 kube-user1,从而使得 kube-user1 拥有了此角色之上的所有许可授权:
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: resource-reader
namespace: default
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: pods-reader
subjects:
- kind: User
name: kube-user1
namespace: default
[root@k8s-master02-test-2-27 ~]# kubectl get rolebinding
NAME ROLE AGE
resource-reader Role/pods-reader 8s
将此 RoleBinding 资源应用到集群中,kube-user1 用户便有了读取 defalut 名称空间中 pods 资源的权限。
将 kubectl 的配置上下文切换至 kube-user1 用户,分别对 pods 和 services 资源发起访问请求测试:
[root@k8s-master01-test-2-26 pki]# kubectl config use-context kube-user1@cluster.local
Switched to context "kube-user1@cluster.local".
[root@k8s-master01-test-2-26 pki]# kubectl get pods -n default
No resources found in default namespace.
[root@k8s-master01-test-2-26 pki]# kubectl get services -n default
Error from server (Forbidden): services is forbidden: User "kube-user1" cannot list resource "services" in API group "" in the namespace "default"
[root@k8s-master01-test-2-26 pki]#
由上面的命令结果可以看出,它能够读取 pods 资源,但对其他任何资源的任何操作请求都将被拒绝。
RoleBinding 资源也可以在命令行直接创建。例如,将 kubectl 的上下文切换为 kubernetse-admin 用户,将前面创建的 services-admin 角色绑定于 kube-user1 上,可以使用如下命令:
[root@k8s-master01-test-2-26 pki]# kubectl config use-context kubernetes-admin@cluster.local
Switched to context "kubernetes-admin@cluster.local".
[root@k8s-master01-test-2-26 pki]# kubectl create rolebinding admin-services --role=service-admin --user=kube-user1 -n defaultrolebinding.rbac.authorization.k8s.io/admin-services created
[root@k8s-master01-test-2-26 pki]#
再次切换到 kube-user1 用户,进行 services 资源的访问测试,命令如下:
[root@k8s-master01-test-2-26 pki]# kubectl config use-context kube-user1@cluster.local
Switched to context "kube-user1@cluster.local".
[root@k8s-master01-test-2-26 pki]# kubectl get services -n default
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.233.0.1 <none> 443/TCP 2d7h
[root@k8s-master01-test-2-26 pki]#
通过 admin-services 这个 RoleBinding 绑定至 services-admin 角色之后,kube-user1 用户拥有管理员 default 名称空间的 Service 资源的所有权限。
虽然 RoleBinding 不能跨名称空间引用 Role 管理,但主题中的用户帐号、用户组和服务帐号却不受名称空间的限制,因此,管理员可为一个主体通过不同的 RoleBinding 资源绑定多个名称空间的角色。
RoleBinding 的配置文件中主要包含两个嵌套字段 subjects 和 roleRef,定义如下:
[root@k8s-master01-test-2-26 pki]# kubectl explain rolebinding
KIND: RoleBinding
VERSION: rbac.authorization.k8s.io/v1
DESCRIPTION:
RoleBinding references a role, but does not contain it. It can reference a
Role in the same namespace or a ClusterRole in the global namespace. It
adds who information via Subjects and namespace information by which
namespace it exists in. RoleBindings in a given namespace only have effect
in that namespace.
FIELDS:
apiVersion <string>
APIVersion defines the versioned schema of this representation of an
object. Servers should convert recognized schemas to the latest internal
value, and may reject unrecognized values. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
kind <string>
Kind is a string value representing the REST resource this object
represents. Servers may infer this from the endpoint the client submits
requests to. Cannot be updated. In CamelCase. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
metadata <Object>
Standard object's metadata.
roleRef <Object> -required-
RoleRef can reference a Role in the current namespace or a ClusterRole in
the global namespace. If the RoleRef cannot be resolved, the Authorizer
must return an error.
subjects <[]Object>
Subjects holds references to the objects the role applies to.
[root@k8s-master01-test-2-26 pki]#
其中,
subjects 字段的嵌套字段定义如下:
[root@k8s-master01-test-2-26 pki]# kubectl explain rolebinding.subjects
KIND: RoleBinding
VERSION: rbac.authorization.k8s.io/v1
RESOURCE: subjects <[]Object>
DESCRIPTION:
Subjects holds references to the objects the role applies to.
Subject contains a reference to the object or user identities a role
binding applies to. This can either hold a direct API object reference, or
a value for non-objects such as user and group names.
FIELDS:
apiGroup <string>
APIGroup holds the API group of the referenced subject. Defaults to "" for
ServiceAccount subjects. Defaults to "rbac.authorization.k8s.io" for User
and Group subjects.
kind <string> -required-
Kind of object being referenced. Values defined by this API group are
"User", "Group", and "ServiceAccount". If the Authorizer does not
recognized the kind value, the Authorizer should report an error.
name <string> -required-
Name of the object being referenced.
namespace <string>
Namespace of the referenced object. If the object kind is non-namespace,
such as "User" or "Group", and this value is not empty the Authorizer
should report an error.
[root@k8s-master01-test-2-26 pki]#
roleRef 字段的嵌套定义如下:
[root@k8s-master01-test-2-26 pki]# kubectl explain rolebinding.roleRef
KIND: RoleBinding
VERSION: rbac.authorization.k8s.io/v1
RESOURCE: roleRef <Object>
DESCRIPTION:
RoleRef can reference a Role in the current namespace or a ClusterRole in
the global namespace. If the RoleRef cannot be resolved, the Authorizer
must return an error.
RoleRef contains information that points to the role being used
FIELDS:
apiGroup <string> -required-
APIGroup is the group for the resource being referenced
kind <string> -required-
Kind is the type of resource being referenced
name <string> -required-
Name is the name of resource being referenced
[root@k8s-master01-test-2-26 pki]#
为什么有了 Role 和 RoleBinding,还要有 ClusterRole 和 ClusterRoleBinding?
因为 Role 和 RoleBindinig 是名称空间级别的资源,它们仅能用于完成单个名称空间内的访问控制,此时若要赋予某主体多个名称空间的访问权限,就不得不逐个名称空间地进行。但是,还有一些资源并不属于名称空间(如 PV、namespace 和 Node等),甚至还有一些非资源型的 URL 路径(如 /healthz 等),对此类资源的管理显然无法在名称空间级别完成,此时就需要用到另外两个集群级别的资源类型 ClusterRole 和 ClusterRoleBinding。
三、ClusterRole 和 ClusterRoleBinding
集群级别的角色资源 ClusterRole 资源除了能够管理与 Role 资源一样的许可权限之外,还可以用于集群级组件的授权,配置方式及其在 rules 字段中可内嵌的字段也与 Role 资源类似。
下面的配置清单示例中定义了 ClusterRole 资源 nodes-reader,它拥有访问集群的节点信息的权限:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: nodes-reader
rules:
- apiGroups:
- ""
resources:
- nodes
verbs:
- get
- list
- watch
[root@k8s-master01-test-2-26 pki]# kubectl get clusterrole |grep nodes-reader
nodes-reader 2022-07-03T09:56:33Z
[root@k8s-master01-test-2-26 pki]#
ClusterRole 是集群级别的资源,它不属于名称空间,所以在此处不用配置 metadata.namespace 字段,
RoleBinding 也能够将主体绑定在 ClusterRole 资源之上,但仅能够赋予用户访问 RoleBinding 资源本身所在的名称空间之内可由 ClusterRole 赋予的权限。比如,在 ClusterRole 具有访问所有名称空间的 ConfigMap 资源权限时,通过 xxx 名称空间的 RoleBinding 将其绑定至 kube-user1 用户,则 kube-user1 用户就具有了访问 xxx 名称空间中的 ConfigMap 资源的权限,但不能访问其他名称空间中的 ConfigMap 资源。如果想要访问其他名称空间的资源,需要用 ClusterRoleBinding 进行绑定。
所以,我们经常会在集群方位内预先定义好一组访问名称空间级别资源的权限的 ClusterRole 资源,而后在多个名称空间中多次通过 RoleBinding 来应用它们,从而让用户分别具有不同名称空间上的资源的相应访问权限,完成名称空间级别权限的快速授权。如果要用 ClusterRoleBinding 引用这类 ClusterRole,则相应的用户就拥有了所有名称空间上的权限。
四、聚合型ClusterRole
Kubernetes 自 1.9 版本开始支持 rules 字段中嵌套 aggregationRule 字段来整合其他的 ClusterRole 对象的规则,这种类型的 ClusterRole 的权限受控于控制器,它们由所有被标签选择器匹配到的用于聚合的 ClusterRole 的授权规则合并而成。
clusterrole.aggregationRule 字段嵌套定义如下:
[root@k8s-master01-test-2-26 pki]# kubectl explain clusterrole.aggregationRule
KIND: ClusterRole
VERSION: rbac.authorization.k8s.io/v1
RESOURCE: aggregationRule <Object>
DESCRIPTION:
AggregationRule is an optional field that describes how to build the Rules
for this ClusterRole. If AggregationRule is set, then the Rules are
controller managed and direct changes to Rules will be stomped by the
controller.
AggregationRule describes how to locate ClusterRoles to aggregate into the
ClusterRole
FIELDS:
clusterRoleSelectors <[]Object>
ClusterRoleSelectors holds a list of selectors which will be used to find
ClusterRoles and create the rules. If any of the selectors match, then the
ClusterRole's permissions will be added
[root@k8s-master01-test-2-26 pki]#
下面是一个示例,它定义了一个标签选择器用于挑选匹配的 ClusterRole:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: monitoring
aggregationRule:
clusterRoleSelectors:
- matchLabels:
rbac.example.com/aggregate-to-monitoring: "true"
rules: []
[root@k8s-master01-test-2-26 pki]# kubectl get clusterrole monitoring
NAME CREATED AT
monitoring 2022-07-03T10:13:37Z
[root@k8s-master01-test-2-26 pki]# kubectl get clusterrole monitoring -o yaml
aggregationRule:
clusterRoleSelectors:
- matchLabels:
rbac.example.com/aggregate-to-monitoring: "true"
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"aggregationRule":{"clusterRoleSelectors":[{"matchLabels":{"rbac.example.com/aggregate-to-monitoring":"true"}}]},"apiVersion":"rbac.authorization.k8s.io/v1","kind":"ClusterRole","metadata":{"annotations":{},"name":"monitoring"},"rules":[]}
creationTimestamp: "2022-07-03T10:13:37Z"
name: monitoring
resourceVersion: "301103"
uid: 619d6a9a-c79f-4f12-b839-b0dabe7a6e00
rules: null
[root@k8s-master01-test-2-26 pki]#
任何能够被示例中的资源的标签匹配到的 ClusterRole 的相关规则都将一同合并为它的授权规则,后续新增的 ClusterRole 资源亦是如此。因此,聚合型 ClusterRole 的规则会随着标签选择器的匹配结果而动态变化。
下面是一个能匹配到此聚合型 ClusterRole 的另一个 ClusterRole 的示例:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: monitoring-endpoints
labels:
rbac.example.com/aggregate-to-monitoring: "true"
# These rules will be added to the "monitoring" role.
rules:
- apiGroups: [""]
resources: ["services", "endpoints", "pods"]
verbs: ["get", "lsit", "watch"]
创建这两个资源,而后,查看聚合型 ClusterRole 资源 monitoring 的相关权限信息,由下面的命令结果可知,它所拥有的权限包含了 ClusterRole 资源 monitoring-endpoints 的所有授权:
[root@k8s-master01-test-2-26 pki]# kubectl apply -f clusterrole-aggregationrule-selectors.yaml
clusterrole.rbac.authorization.k8s.io/monitoring-endpoints created
[root@k8s-master01-test-2-26 pki]# kubectl get clusterrole monitoring -o yaml
aggregationRule:
clusterRoleSelectors:
- matchLabels:
rbac.example.com/aggregate-to-monitoring: "true"
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"aggregationRule":{"clusterRoleSelectors":[{"matchLabels":{"rbac.example.com/aggregate-to-monitoring":"true"}}]},"apiVersion":"rbac.authorization.k8s.io/v1","kind":"ClusterRole","metadata":{"annotations":{},"name":"monitoring"},"rules":[]}
creationTimestamp: "2022-07-03T10:13:37Z"
name: monitoring
resourceVersion: "303443"
uid: 619d6a9a-c79f-4f12-b839-b0dabe7a6e00
rules:
- apiGroups:
- ""
resources:
- services
- endpoints
- pods
verbs:
- get
- lsit
- watch
[root@k8s-master01-test-2-26 pki]#
五、面向用户的内建 ClusterRole
API Server 内建了一组默认的 ClusterRole 和 ClusterRoleBinding 以预留系统使用,其中大多数都以 "system:" 为前缀。另外还有一些非以 "system:" 为前缀的默认的 Role 资源,它们是为面向用户的需求而设计的,包括超级用户角色(clustere-admin)、用于授权集群级别权限的 ClusterRoleBinding(cluster-status)以及授予特定名称空间级别权限的 RoleBinding(admin、edit 和 view)。
掌握这些默认的内建 ClusterRole 对按需创建用户并快速配置权限至关重要:
内建的 ClusterRole 资源 cluster-admin 拥有管理集群所有资源的权限,它基于同名的 ClusterRoleBinding 资源绑定到了 "system:masters" 组上,这意味着所有隶属于此组的用户都具有集群的超级管理员权限。
kubernetes-admin 为什么能具有集群管理员权限呢?
Kubeadm 安装设定集群的时候,会自动创建配置文件 /etc/kubernetes/admin.conf,该文件定义了用户 kubernetes-admin 使用的证书文件 /etc/kubernetes/pki/apiserver-kubelet-client.crt 向 API Server 进行验证。而此证书的 Issuer: CN=kubernetes, Subject: O=system:masters, CN=kube-apiserver-kubelet-client,进行认证时,CN 的值可作为用户名使用,而 O 的值将作为用户所属组名使用,因此,kubernetes-admin 具有集群管理权限。
[root@k8s-master01-test-2-26 pki]# openssl x509 -in /etc/kubernetes/pki/apiserver-kubelet-client.crt -noout -text
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 4078254936089925157 (0x3898df41c11f9625)
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN=kubernetes
Validity
Not Before: Jul 1 02:11:11 2022 GMT
Not After : Jul 1 02:11:12 2023 GMT
Subject: O=system:masters, CN=kube-apiserver-kubelet-client
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:cb:ae:0c:22:09:72:4d:db:8a:92:92:e9:ab:a6:
9a:18:d8:19:7c:d9:2e:d2:2d:93:83:d4:a0:0e:d2:
31:49:92:ce:29:ac:7b:64:c7:d2:a8:4c:ed:25:26:
98:83:1d:b6:5c:7f:0a:41:e3:a6:23:5b:76:32:d6:
b8:4d:fb:97:8d:3e:eb:3d:b6:91:63:81:a9:30:23:
fb:32:a6:fd:28:97:b4:22:42:8f:68:5f:c2:76:15:
71:d7:97:6c:f8:06:e8:02:6c:37:c3:8b:2b:0c:a9:
88:0d:0a:b1:19:18:de:7c:30:a0:fe:a9:8d:e6:d3:
c8:71:5d:08:67:65:cd:55:e0:df:d1:bd:7a:bb:f0:
4e:85:9f:f3:28:2b:94:b2:6c:97:ba:f5:0d:ee:f0:
b3:79:df:7e:a9:5b:f6:48:d5:0f:bb:bd:b4:d0:3e:
42:9e:1a:57:65:70:64:1e:4a:cc:37:68:52:68:67:
d5:b5:b6:58:53:80:de:13:62:77:08:7a:16:c9:95:
17:90:3d:53:0c:40:ff:6d:ee:34:3b:7f:1f:1d:ad:
c5:f9:cb:89:b1:23:be:d8:eb:4f:87:84:30:c4:59:
10:08:3a:e5:e8:b8:b9:53:fa:75:ef:67:65:4c:e7:
34:c9:1c:b4:e2:f5:1a:08:87:6b:53:2f:a1:2e:b8:
2b:f3
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Key Usage: critical
Digital Signature, Key Encipherment
X509v3 Extended Key Usage:
TLS Web Client Authentication
X509v3 Basic Constraints: critical
CA:FALSE
X509v3 Authority Key Identifier:
keyid:62:73:00:B9:04:BA:E2:76:84:4B:43:C5:8E:08:F4:85:FA:33:82:8A
Signature Algorithm: sha256WithRSAEncryption
3f:a3:74:a5:ef:5b:45:1f:9f:72:8b:10:c9:f5:ed:f9:5d:20:
bb:99:cf:b6:b8:69:4e:2f:96:e0:67:00:53:c9:56:2e:b4:c4:
c7:75:98:db:43:6d:cf:d6:5d:ae:19:20:c8:de:15:76:a8:96:
48:10:3d:e3:90:16:1f:a5:b5:9a:c3:e9:f0:7c:87:50:e8:73:
3f:fd:e4:94:1a:64:53:d8:81:c6:9c:45:95:7c:44:91:38:30:
ef:2c:b4:54:05:ff:02:5f:fe:1a:e3:74:34:e3:fd:59:43:cf:
f1:5b:26:99:5a:de:64:80:17:08:4b:af:02:b8:73:0f:ef:5c:
98:cb:a1:08:8a:c3:b0:fa:fd:2e:28:d1:54:9c:29:6d:52:fa:
d4:56:c2:78:5e:96:b6:67:b5:29:56:01:fe:a3:ac:ff:43:18:
69:d8:ec:03:bc:ae:6c:08:6a:d6:8b:e9:0b:18:89:9d:2c:3a:
bb:9c:1f:43:18:ad:8a:7f:34:09:bf:2e:d0:72:e7:9e:5f:6f:
67:31:79:29:b4:f3:8a:3d:77:26:1f:e1:fc:b9:5a:bc:19:9b:
2a:26:e7:fd:a2:7d:de:73:63:1a:a7:bc:8b:07:ce:b7:0c:e9:
f5:b0:93:fc:9a:92:c6:0e:63:2d:41:c6:af:2b:8d:f4:e8:ad:
f3:92:73:cb
[root@k8s-master01-test-2-26 pki]#
所以,为 Kubernetes 集群额外创建管理员的方法至少有两种:
-
- 创建用户证书,其 Subject 中的 O 值为 "system:masters"。
- 创建 ClusterRoleBinding 将用户绑定至 cluster-admin。
如果想创建 只读 或 读写 权限,则仅需要将创建 RoleBinding 时应用的 ClusterRole 相应的修改为 view 或 edit 即可。
默认的 ClusterRole | 默认的 ClusterRoleBinding | 说明 |
cluster-admin | system:masters 组 | 授予超级管理员在任何对象上执行任何操作的权限 |
admin | None | 以 RoleBinding 机制访问指定名称空间的所有资源,包括名称空间的 Role 和 RoleBinding,但不包括资源配置和名称空间本身。 |
edit | None | 允许读写访问一个名称空间内的绝大多数资源,但不允许查看或修改 Role 或 RoleBinding |
view | None | 允许读取一个名称空间内的绝大数资源,但不允许查看 Role 或 RoleBinding,以及 secret 资源 |
六、其他的内建 ClusterRole 和 ClusterRoleBinding
API Server 会创建一组默认的 ClusterRole 和 ClusterRoleBinding,大多数以 "system:" 为前缀,被系统基础架构所使用,修改这些资源会导致集群功能不正常。这里就省略不说了。