Contents
API Server的身份认证、授权、准入控制¶
之前我们使用的是kubectl反向代理,通过使kubectl反向代理API Server,可以直接使用kubectl命令的认证授权来访问API Server。然而,当在实际工作中使用API Server时,根本不会在Master节点上直接访问API Server,而对于不同的角色,也将设定合适的权限,根本不会有完整权限。
API Server的实际使用比之前的示例复杂很多,要经过三大关卡才能够访问合适的资源。由于API Server是访问和管理资源对象的唯 一入口,因此每一次的访问请求都需要进行合法性检验,需要在一系列验证通过之后才能访问或者存储数据到etcd当中。
访问API Server需要经过身份认证、授权及准入控制这三大关卡,如下图所示。只有这三大关卡都能通过,才可以访问Kubernetes集群中的资源。
访问API Server的三大关卡
身份认证主要用于确定用户能不能访问,授权则决定用户能够访问哪些资源,而准入控制决定用户访问这些资源时需要基于什么规范 或准则。
1. 身份认证¶
要访问API Server,首先需要经过的第一个关卡就是身份认证。之前我们在使用
kubectl反向代理或者直接使用kubectl命令时,其实也经历了身份认证。kubectl命令的认证是使用~/.kube/config文件进行的。通过$ kubectl config view命令,可以查看它的认证情况
$ kubectl config view
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: DATA+OMITTED
server: https://192.168.1.161:6443
name: kubernetes
contexts:
- context:
cluster: kubernetes
user: kubernetes-admin
name: kubernetes-admin@kubernetes
current-context: kubernetes-admin@kubernetes
kind: Config
preferences: {}
users:
- name: kubernetes-admin
user:
client-certificate-data: REDACTED
client-key-data: REDACTED
在安装完成后,Kubernetes会在Master节点上开启6443端口,这就是API Server的访问入口
在本例中,API Server的地址为https://192.168.1.161:6443,如果没有经过认证,将无法访问API Server。我们可以先试试没有认证时的访问效果。执行以下命令查询Pod。
命令执行后,会发现无法正常查询
$ curl --insecure https://192.168.1.161:6443/api/v1/namespaces/default/pods
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {
},
"status": "Failure",
"message": "pods is forbidden: User \"system:anonymous\" cannot list resource \"pods\" in API group \"\" in the namespace \"default\"",
"reason": "Forbidden",
"details": {
"kind": "pods"
},
"code": 403
要访问API Server,要先进行身份认证。Kubernetes中的身份认证主要分为以下两类。
常规用户认证:主要供普通用户或独立于Kubernetes之外的其他外部应用使用,以便能从外部访问API Server。
ServiceAccount认证:主要供集群内部的Pod使用,用来给Pod中的进程提供访问API Server的身份标识,以便Pod可以从内部调用 API Server。
1.1 常规用户认证¶
常规用户认证主要供普通用户或独立于Kubernetes之外的其他外部应用来使用,它主要有3种认证方式。
HTTPS证书认证:基于CA证书签名的数字证书认证。
HTTP令牌认证:通过令牌来识别用户。
HTTP Base认证:通过用户名和密码认证。
从使用角度来说,HTTP令牌认证是最实用也最易普及的方式,本节主要介绍这种方式。
首先,使用以下命令生成一个随机的令牌。
$ head -c 16 /dev/urandom | od -An -t x | tr -d ' '
937eadfa60efc23102f636f881d3d99e
拿到令牌后,就可以给Kubernetes创建令牌认证文件,命令如下。
$ vim /etc/Kubernetes/pki/token_auth_file
认证文件中可填入多行认证信息,一行对应一个用户,每行都须具备令牌、用户名、用户ID这3个字段。例如,可填入以下信息。
Token1,username1,1
Token2,username2,2
......
本例中使用刚才生成好的令牌来创建一个名为 exampleuser 的用户。这只需要在/etc/Kubernetes/pki/token_auth_file文件中填入以下内容然后保存文件即可。
937eadfa60efc23102f636f881d3d99e,exampleuser,1
现在认证文件已成功创建,只需要在API Server的启动参数中加入对该文件的引用。要修改启动参数,应编辑/etc/kubernetes/manifests/kube-apiserver.yaml文件,然后在spec属性部分加入- –token-auth- file=/etc/Kubernetes/pki/token_auth_file参数,如以下代码所示。
apiVersion: v1
...
spec:
containers:
- command:
- kube-apiserver
...
- --tls-cert-file=/etc/Kubernetes/pki/apiserver.crt
- --tls-private-key-file=/etc/Kubernetes/pki/apiserver.key
- --token-auth-file=/etc/Kubernetes/pki/token_auth_file
之后,API Server就会引用刚才创建的令牌认证文件。如果要以exampleuser身份访问API Server,只需要在请求中带上 一个Header即可,其格式为Authorization: Bearer {Token值},在本例中为Authorization:Bearer937eadfa60efc23102f636f881d3d99e。
此时带上令牌,以exampleuser身份调用API Server,获取Pod信息,命令如下。
$ curl --insecure https://192.168.1.161:6443/api/v1/namespaces/default/pods -H \
"Authorization:Bearer 937eadfa60efc23102f636f881d3d99e"
Kubernetes已经识别出exampleuser正在进行访问,但因为只通过了认证,还没有授权,所以访问仍会失败。认证已经完成。
1.2 ServiceAccount认证¶
ServiceAccount认证主要供集群内部Pod中的进程使用,以便Pod可以从内部调用API Server。
常规用户认证是不限制命名空间(namespace)的,但ServiceAccount认证的局限于它所在的命名空间中。
默认ServiceAccount¶
每个命名空间都有一个默认的ServiceAccount,如果在创建Pod时没有明确指定用哪个ServiceAccount,就会用默认的 ServiceAccount。
可以通过$ kubectl get serviceaccount命令查看当前已有的ServiceAccount
$ kubectl get serviceaccount
NAME SECRETS AGE
default 1 176d
可以看到在当前命名空间下,拥有一个名为default的ServiceAccount。
此时再通过$kubectl describe serviceaccount default命令查看其详情,
可以看到它关联了一个名为default-token-znfnr的Secret,里面存放了ServiceAccount的认证信息,通过这些认证信息可以访问APIServer。
# ServiceAccount查询结果
$ kubectl describe serviceaccount default
Name: default
Namespace: default
Labels: <none>
Annotations: <none>
Image pull secrets: <none>
Mountable secrets: default-token-znfnr
Tokens: default-token-znfnr
Events: <none>
$ kubectl get secrets
NAME TYPE DATA AGE
default-token-znfnr kubernetes.io/service-account-token 3 176d
接下来,创建一个示例Pod,用它来进行讲解,其定义如下所示。
apiVersion: v1
kind: Pod
metadata:
name: examplepodforheadlessservice
spec:
containers:
- name: testcontainer
image: docker.io/appropriate/curl
imagePullPolicy: IfNotPresent
command: ['sh', '-c']
args: ['echo "test pod for headless service!"; sleep 3600']
这个Pod的镜像为appropriate/curl。它是一种工具箱,里面存放了一些用于测试网络的工具,例如,curl命令正好可用于测试 API Server的访问。调用sleep 3600命令让该容器长期处于运行状态。
此时执行$ kubectl get pod examplepodforheadlessservice -o yaml命令查看Pod定义的
详情(或使用$ kubectl describe pod examplepodforheadlessservice命令查看Pod详情),
可以发现Pod中引用了一个Secret类型的存储卷,这个存储卷我们并没有在模板中定义,而是由Kubernetes自动附加的
Kubernetes在这个命名空间下以默认形式自动创建了一个ServiceAccount,而在default-token-znfnr里面存放了ServiceAccount的认证信息。
使用这些认证信息,就可以访问APIServer。
$ kubectl describe pod examplepodforheadlessservice
Name: examplepodforheadlessservice
Namespace: default
Priority: 0
Node: gitee-k8s-w02/192.168.1.36
Start Time: Wed, 20 Apr 2022 21:36:28 +0800
Labels: <none>
Annotations: <none>
......
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-sl2w8 (ro)
执行$ kubectl get secret default-token-znfnr -o yaml命令
(或$ kubectl describe secret default-token-znfnr命令),查看Secret定义的详情,
可以发现它主要存放了3个信息——ca.crt(证书)、namespace、token。
由于该Secret是以存储卷形式挂载到Pod容器当中的,因此可以使用映射路径获得证书和令牌,并用它们来访问API Server,例如,可 以使用以下路径。
/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
/var/run/secrets/kubernetes.io/serviceaccount/token
接下来,通过以下命令进入Pod内部,以便在Pod内部执行命令行。
$ kubectl exec -it pod/examplepodforheadlessservice -- /bin/s
现在可以使用ServiceAccount的令牌来访问API Server,只需要执行以下命令。
$ curl --insecure https://192.168.1.161:6443/api/v1/namespaces/default/pods -H \
"Authorization:Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)"
在本例中,我们通过cat /var/run/secrets/Kubernetes.io/serviceaccount/
token输出了存放在映射路径下的令牌。命令执行后,结果如下图
所示,Kubernetes已经通过认证,识别到名为default的ServiceAccount正在进行访问,由于还未授权,因此访问会失败。
自定义ServiceAccount¶
一般情况下,我们并不会更改默认ServiceAccount的授权。如果某些Pod需要访问API Server,通常会让它引用自定义ServiceAccount,并设置其授权。
ServiceAccount的定义非常简单。首先,通过以下命令创建一个名为exampleserviceaccount的自定义ServiceAccount。
exampleserviceaccount.yml
apiVersion: v1
kind: ServiceAccount
metadata:
name: exampleserviceaccount
运行以下命令,通过模板创建ServiceAccount。
$ kubectl apply -f exampleserviceaccount.yml
此时再执行以下命令,查询当前命名空间下的ServiceAccount。
可以看到刚才创建的ServiceAccount。
$ kubectl get serviceaccount
NAME SECRETS AGE
default 1 176d
exampleserviceaccount 1 2m3s
另外,还可以通过命令查看ServiceAccount的详细信息。
$ kubectl describe serviceaccounts exampleserviceaccount
Name: exampleserviceaccount
Namespace: default
Labels: <none>
Annotations: <none>
Image pull secrets: <none>
Mountable secrets: exampleserviceaccount-token-t4265
Tokens: exampleserviceaccount-token-t4265
Events: <none>
Kubernetes在创建ServiceAccount时自动为其生成了一个Secret(在本例中为exampleserviceaccount-token-t4265)。
和之前默认ServiceAccount的Secret一样,里面存放了与该ServiceAccount相关的证书和令牌等认证信息。
此时再创建一个Pod,将它的spec.serviceAccountName属性设置为刚才创建的自定义ServiceAccount。
首先,通过以下命令,创建模板文件。
examplepodforserviceaccount.yml
apiVersion: v1
kind: Pod
metadata:
name: examplepodforserviceaccount
spec:
serviceAccountName: exampleserviceaccount
containers:
- name: testcontainer
image: docker.io/appropriate/curl
imagePullPolicy: IfNotPresent
command: ['sh', '-c']
args: ['echo "test pod for headless service!"; sleep 3600']
在这个 Pod 的定义中,引用了先前创建的名为exampleserviceaccount 的自定义ServiceAccount。
接下来,运行以下命令,通过模板创建Pod。
$ kubectl apply -f examplepodforserviceaccount.yml
Pod创建后再执行$ kubectl get pod examplepodforserviceaccount -o yaml
命令查看Pod定义的详情(或用$ kubectl describe pod examplepodforserviceaccount命令查看Pod详情),
可以发现Pod中使用了自定义ServiceAccount的Secret,并将其配置为存储卷。
可以看到cm配置文件已经挂载到容器中了。
与默认的ServiceAccount一样,我们依然可以进入Pod内部,然后使用ServiceAccount的令牌来访问API Server。
$ curl --insecure https://192.168.1.161:6443/api/v1/namespaces/default/pods -H \
"Authorization:Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)"
Kubernetes会识别到examplepodforserviceaccount这个自定义ServiceAccount正在发起请求,但因为我们只设置了认证还没进行授权,所以访问会失败,下一节将基于该示例演示如何授权。
2. RBAC授权¶
Kubernetes中有基于属性的访问控制(Attribute Based AccessControl,ABAC)、
基于角色的访问控制(Role Based AccessControl,RBAC)、
基于HTTP回调机制的访问控制(Webhook)、
Node认证等授权模式,但从1.6版本开始,Kubernetes默认启用的是RBAC授权模式。本节将主要讲述RBAC授权模式。
RBAC授权主要分为两个步骤。
(1)角色定义:指定角色名称,定义允许访问哪些资源及允许的访问方式。
(2)角色绑定:将角色与用户(常规用户或ServiceAccount)进行绑定,这样用户就拥有与角色对应的权限。
RBAC授权的原理如图
角色定义和角色绑定分为两种。
只拥有单一指定命名空间访问权限的角色:角色定义关键字为Role,角色绑定关键字为RoleBinding。
拥有集群级别(不限命名空间)访问权限的角色:角色定义关键字为ClusterRole,角色绑定关键字为ClusterRoleBinding。
2.1 普通角色的定义与绑定¶
普通角色定义¶
首先,定义一个普通角色,创建一个名为podreader.yml的模板文件。命令如下。
podreader.yml
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: default
name: podreader
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list"]
这里介绍一下文件中的主要属性。
kind表示模板的类型,这里使用Role关键字以表示普通角色。
apiVersion表示使用的API版本,有关RBAC授权的API版本为rbac. authorization.k8s.io/v1。
metadata中指定角色的名称为podreader。namespace属性为default,这个属性可以不用填写,默认为default。
rules表示角色的规则定义。apiGroups表示可对哪些API组的资源进行操作。这里设置为空字符串,表示没有限制条件。 resources表示可以访问的资源列表,这里设置为pods。verbs表示可以对资源进行哪几种访问方式。这里设置为 get、watch和list,分别表示可以查询单条资源、监控资源并查询列表资源。
运行以下命令,通过模板创建普通角色。
$ kubectl apply -f podreader.yml
通角色创建成功后,可以通过$ kubectl get role命令查看。另外,还可以通过$ kubectl describe role podreader
命令查看普通角色podreader的详情
$ kubectl get role
NAME CREATED AT
podreader 2022-04-21T01:39:18Z
# 可以清晰地看到资源类型以及允许的访问方式。
$ kubectl describe role podreader
Name: podreader
Labels: <none>
Annotations: <none>
PolicyRule:
Resources Non-Resource URLs Resource Names Verbs
--------- ----------------- -------------- -----
pods [] [] [get watch list]
提示:要了解角色定义模板中支持的resources和verbs属性,可以通过以下方式来查询。
在Master节点上打开kubectl反向代理,本例中的命令为kubectl proxy –port=8080,然后访问 http://localhost:8080/{APIVersion}来查看资源列表,其中name属性表示支持的资源名称,verbs属性表示支持的操作。
例如,要查看Pod中有resources属性的类别以及支持的verbs属性,
可以执行命令$ curl http://localhost:8080/api/v1,然后在返回结果中找到与Pod相关的信息。
如果要查看Daemonsets控制器中resources属性的类别以及支持的verbs属性,
可以执行命令$ curl http://localhost:8080/apis/apps/v1,
然后在返回结果中找到与Daemonsets控制器相关的信息。
与Daemonsets控制器相关的resources及verbs属性
普通角色绑定¶
定义角色后就可以绑定角色了。绑定可以针对常规用户认证,也可以针对ServiceAccount认证。
在之前的示例中,我们创建过基于常规用户认证的用户,其名称为exampleuser,
还设置过一个自定义ServiceAccount,其名称为exampleserviceaccount(另一个名为 examplepodforserviceaccount的Pod引用了这个自定义ServiceAccount)。为了同时为它们进行角色绑定,首先,创建模板文件,命令如下。
podreaderbinding.yml
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: podreaderbinding
namespace: default
subjects:
- kind: User
name: exampleuser
apiGroup: ""
- kind: ServiceAccount
name: exampleserviceaccount
apiGroup: ""
roleRef:
kind: Role
name: podreader
apiGroup: ""
这里介绍一下它的主要属性。
kind表示模板的类型,这里使用RoleBinding关键字以表示普通角色绑定。
apiVersion 表示使用的 API 版本,有关 RBAC 授权的 API 版本为 rbac. authorization.k8s.io/v1。
metadata中定义角色的名称为podreaderbinding。namespace属性为default,这个属性可以不用填写,默认为default。
subjects表示将角色绑定给哪些认证主体,它是一个数组。 第一个认证主体是之前创建的常规用户认证示例,这里设置其kind为User,名称为之前设置的exampleuser,apiGroup为默认值表示没有限制。 第二个认证主体是之前创建的 ServiceAccount 认证示例,这里设置其 kind 为ServiceAccount,名称为之前设定的exampleserviceaccount。 roleRef表示要绑定的角色,这里的kind设置为Role以表示普通角色,名称为之前定义的podreader。
运行以下命令,通过模板创建普通角色绑定。
$ kubectl apply -f podreaderbinding.yml
普通角色绑定创建成功后,可以通kubectl get rolebinding命令查看它。
另外,还可以通过$ kubectl describe rolebinding podreaderbinding命令查看普通角色
绑定podreaderbinding的详情。如下所示,可以清晰地看到所绑定的认证主体,以及用于绑定的角色。
$ kubectl get rolebinding
NAME ROLE AGE
podreaderbinding Role/podreader <invalid>
$ kubectl describe rolebinding podreaderbinding
Name: podreaderbinding
Labels: <none>
Annotations: <none>
Role:
Kind: Role
Name: podreader
Subjects:
Kind Name Namespace
---- ---- ---------
User exampleuser
ServiceAccount exampleserviceaccount
角色绑定后就可以访问 API Server 了。接下来分别使用之前创建的常规用户认证和ServiceAccount认证来访问API Server。
为了使用常规用户认证,基于之前创建的用户exampleuser中的令牌,通过API Server访问Pod,命令如下。
$ curl --insecure https://192.168.1.161:6443/api/v1/namespaces/default/pods -H \
"Authorization:Bearer 937eadfa60efc23102f636f881d3d99e"
为了使用ServiceAccount认证,首先,通过以下命令进入Pod内部,以便在Pod内部执行命令行。
podreaderbinding-v2.yml
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: podreaderbinding
namespace: default
subjects:
- kind: ServiceAccount
name: exampleserviceaccount
apiGroup: ""
roleRef:
kind: Role
name: podreader
apiGroup: ""
$ kubectl exec -ti examplepodforserviceaccount -- /bin/sh
# curl --insecure https://192.168.1.161:6443/api/v1/namespaces/default/pods -H \
"Authorization:Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)"
可以发现通过ServiceAccount也成功获取了Pod列表信息。
2.2 集群角色的定义与绑定¶
集群角色与普通角色类似,但二者存在以下区别。
使用的关键字不同。普通角色使用的关键字为Role,绑定普通角色使用的关键字为RoleBinding;集群角色使用的关键字为ClusterRole,绑定集群角色使用的关键字为ClusterRoleBinding。
集群角色不属于任何命名空间,模板也无须指定命名空间。而普通角色要求指定命名空间,如果未指定,则默认为default命名空 间。
集群角色可以访问全部命名空间下的资源,也可以访问不在命名空间下的资源(如Node、StorageClass等),可以通过
$kubectl api-resources --namespaced=false命令查看不在命名空间下的资源。
Kubernetes系统在安装时就会设置一系列的集群角色定义和绑定,Kubernetes系统组件将会使用这些角色。
可以分别通过$ kubectl get clusterrole命令和$ kubectl get clusterrolebinding命令查看已有的角色定义及角色绑定。
集群角色定义的查询结果
$ kubectl get clusterrole
NAME CREATED AT
admin 2021-10-26T11:49:18Z
cilium 2021-10-26T12:08:24Z
cilium-operator 2021-10-26T12:08:24Z
cluster-admin 2021-10-26T11:49:18Z
edit 2021-10-26T11:49:18Z
efk-nfs-storage-nfs-client-provisioner-runner 2022-01-07T10:51:17Z
ingress-nginx 2021-10-26T12:54:18Z
kube-state-metrics 2022-04-15T08:00:09Z
kubeadm:get-nodes 2021-10-26T11:49:20Z
kubernetes-dashboard 2021-10-26T12:49:52Z
kubernetes-dashboard-view 2021-10-26T12:48:47Z
managed-nfs-storage-nfs-client-provisioner-runner 2022-01-09T06:03:49Z
mysql-nfs-storage-nfs-client-provisioner-runner 2022-02-25T08:22:17Z
pod-impersonation-shell-fhb5s 2021-10-29T11:47:15Z
prometheus 2022-04-15T08:00:09Z
system:aggregate-to-admin 2021-10-26T11:49:18Z
system:aggregate-to-edit 2021-10-26T11:49:18Z
system:aggregate-to-view 2021-10-26T11:49:18Z
system:aggregated-metrics-reader 2021-10-26T14:07:20Z
system:auth-delegator 2021-10-26T11:49:18Z
system:basic-user 2021-10-26T11:49:18Z
system:certificates.k8s.io:certificatesigningrequests:nodeclient 2021-10-26T11:49:18Z
system:certificates.k8s.io:certificatesigningrequests:selfnodeclient 2021-10-26T11:49:18Z
system:certificates.k8s.io:kube-apiserver-client-approver 2021-10-26T11:49:18Z
system:certificates.k8s.io:kube-apiserver-client-kubelet-approver 2021-10-26T11:49:18Z
system:certificates.k8s.io:kubelet-serving-approver 2021-10-26T11:49:18Z
system:certificates.k8s.io:legacy-unknown-approver 2021-10-26T11:49:18Z
system:controller:attachdetach-controller 2021-10-26T11:49:18Z
system:controller:certificate-controller 2021-10-26T11:49:18Z
system:controller:clusterrole-aggregation-controller 2021-10-26T11:49:18Z
system:controller:cronjob-controller 2021-10-26T11:49:18Z
system:controller:daemon-set-controller 2021-10-26T11:49:18Z
.....
集群角色绑定的查询结果
$ kubectl get clusterrolebinding
NAME ROLE AGE
cilium ClusterRole/cilium 176d
cilium-operator ClusterRole/cilium-operator 176d
cluster-admin ClusterRole/cluster-admin 176d
ingress-nginx ClusterRole/ingress-nginx 176d
jenkins-admin ClusterRole/cluster-admin 37d
kube-state-metrics ClusterRole/kube-state-metrics 5d18h
kubeadm:get-nodes ClusterRole/kubeadm:get-nodes 176d
kubeadm:kubelet-bootstrap ClusterRole/system:node-bootstrapper 176d
kubeadm:node-autoapprove-bootstrap ClusterRole/system:certificates.k8s.io:certificatesigningrequests:nodeclient 176d
kubeadm:node-autoapprove-certificate-rotation ClusterRole/system:certificates.k8s.io:certificatesigningrequests:selfnodeclient 176d
kubernetes-dashboard ClusterRole/kubernetes-dashboard 176d
kubernetes-dashboard-view ClusterRole/kubernetes-dashboard-view 176d
kuboard-admin-crb ClusterRole/cluster-admin 153d
kuboard-viewer-crb ClusterRole/view 153d
metrics-server:system:auth-delegator ClusterRole/system:auth-delegator 176d
pod-impersonation-shell-6x2qv ClusterRole/pod-impersonation-shell-fhb5s 173d
prometheus ClusterRole/cluster-admin 5d18h
run-efk-nfs-storage-nfs-client-provisioner ClusterRole/efk-nfs-storage-nfs-client-provisioner-runner 103d
在之前的示例中,我们定义了一个名为podreader的普通角色,并以普通角色绑定的方式将其绑定到认证主体上,也可以使用集群角色 及绑定来实现同样的功能。具体模板的代码如下所示。
clusterpodreader.yml
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: clusterpodreader
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: clusterpodreaderbinding
subjects:
# 常规用户认证
- kind: User
name: exampleuser
apiGroup: ""
# ServiceAccount认证
- kind: ServiceAccount
name: exampleserviceaccount
namespace: default
apiGroup: ""
roleRef:
kind: ClusterRole
name: clusterpodreader
apiGroup: ""
这段代码与之前的示例有几处区别。
其关键字分别为ClusterRole和ClusterRoleBinding,且没有指定命名空间。
由于ServiceAccount是某个命名空间下的资源,因此需要指明是对哪个命名空间下的ServiceAccount绑定集群角色的。
应用模板后,使用常规用户exampleuser以及ServiceAccount的exampleserviceaccount可以访问任何命名空间下的Pod资源,不再仅 限于default命名空间。
上述示例是将ClusterRole与ClusterRoleBinding关联在一起了, 在实际使用过程中也可以将ClusterRole与RoleBinding关联在一起。 因为ClusterRole是不限制命名空间的,所以如果想既给某个认证主体绑定 ClusterRole,又想限制它能够使用的命名空间, 就可以将它与 RoleBinding关联以达到限定效果。可以修改模板来实现该功能, 修改后的代码如下所示。
clusterpodreader-v2.yml
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: clusterpodreader
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: podreaderbinding
namespace: default
subjects:
- kind: User
name: exampleuser
apiGroup: ""
- kind: ServiceAccount
name: exampleserviceaccount
namespace: default
apiGroup: ""
roleRef:
kind: ClusterRole
name: clusterpodreader
apiGroup: ""
这段代码与上一个示例有几处区别。
两个示例的关键字分别为ClusterRole和RoleBinding。ClusterRole没有指定命名空间,但RoleBinding指定命名空间为 default(如果没有指定命名空间,默认也为default)。
因为已经通过RoleBinding指定了命名空间,所以无须再给ServiceAccount指明命名空间。
应用模板后,使用常规用户的exampleuser以及ServiceAccount的exampleserviceaccount只能访问default命名空间下的Pod资源。