书籍来源:《CKA/CKAD应试指南:从Docker到Kubernetes完全攻略》
一边学习一边整理老师的课程内容及试验笔记,并与大家分享,侵权即删,谢谢支持!
附上汇总贴:CKA备考实验 | 汇总-CSDN博客
授权一般是基于RBAC(Role Based Access Control,基于角色的访问控制)的方式,即并不会直接把权限授权给用户,而是把几个权限放在一个角色里,然后把角色授权给用户,如图15-1所示。
这里把一系列的权限放在role1里,然后把这个角色授权给用户,此时这个用户就会具有这个角色所有的权限。
把角色授权给用户,这个授权叫作rolebinding,不管是role还是rolebinding,都是基于命名空间的,也就是在哪个命名空间里创建,就在哪个命名空间里生效。
role和rolebinding
为了测试方便,下面创建几个命名空间:ns1、ns3和ns4(如果已经存在则不必创建)。
创建命名空间。
##########实操验证##########
[root@vms10 role]# kubectl create ns ns1
namespace/ns1 created
[root@vms10 role]# kubectl create ns ns3
namespace/ns3 created
[root@vms10 role]# kubectl create ns ns4
namespace/ns4 created
[root@vms10 role]#
- 创建role
步骤1:创建role1.yaml,内容如下。
注意:这个文件可以通过kubectl create role namex --verb=get,watch,list --resource=pods --dry-run=client -o yaml > role1.yaml快速获取,然后修改。
##########实操验证##########
[root@vms10 role]# cat role1.yaml
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: pod-reader
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list"]
[root@vms10 role]#
这里,role的名字为pod-reader。
对于apiGroups,它是role的作用范围,即可以作用到哪些资源上。先看下常见apiversion的类型。
pod: v1;
deployment: apps/v1;
daemonset: apps/v1;
job: batch/v1;
cronjob: batch/v1;
service: v1;
role: http://rbac.authorization.k8s.io/v1;
RoleBinding: http://rbac.authorization.k8.io/v1。
这些apiversion是以“父级/子级”的格式来写的。在定义角色的yaml文件里apiGroups字段,写对应的父级即可,如果没有父级,比如pod的apiversion值为v1,则在apiGroups里写" ",注意引号里没有空格。
role1.yaml里apiGroups的值是" ",意思是可以作用到pod和service这些资源上,因为它们的apiversion值并不存在父级。到底是pod还是service,由下面的resource来指定。
如果apiGroups的值为“apps”的话,意思是可以作用到deployment和daemonset,因为他们的apiversion是apps/v1。到底是deployment还是daemonset,由resource来指定。
如果想同时作用到pod和deployment的话,应该这样写:apiGroups: [" ","apps"] 。
vers用来指定所能使用的权限,包括get、list、create、delete、update等。
所以role1.yaml里定义的角色,对pod具有get、watch、list权限。
步骤2:创建角色。
##########实操验证##########
[root@vms10 role]# kubectl apply -f role1.yaml
role.rbac.authorization.k8s.io/pod-reader created
[root@vms10 role]#
这样就创建了一个名字叫作pod-reader的角色。
步骤3:查看角色。
##########实操验证##########
[root@vms10 role]# kubectl get role
NAME CREATED AT
pod-reader 2023-09-27T07:55:26Z
[root@vms10 role]#
步骤4:查看角色的属性。
##########实操验证##########
[root@vms10 role]# kubectl get role
NAME CREATED AT
pod-reader 2023-09-27T07:55:26Z
[root@vms10 role]#
[root@vms10 role]# kubectl describe role pod-reader
Name: pod-reader
Labels: <none>
Annotations: <none>
PolicyRule:
Resources Non-Resource URLs Resource Names Verbs
--------- ----------------- -------------- -----
pods [] [] [get watch list]
[root@vms10 role]#
这里可以看到,此角色对pod具有get、watch、list权限。
创建role也可以通讨命今行来实现,在CKA的考试里如果要创建角色,可以通过命令行来快速实现,语法如下。
kubectl create role namex --verb=权限1, 权限2 ... --resource=pods,deployments,...
这句话的意思是创建一个名字为namex的角色,对pods、deployment具有权限1、权限2等权限。
- 创建rolebinding
把角色授权给用户,由rolebinding来完成。这里把角色pod-reader授权john用户,就需要创建一个rolebinding。
步骤1:创建role1binding.yaml。
注意:这个文件可以通过kubectl create rolebinding rbind1 --role=pod-reader --user=john --dry-run=client -o yaml > role1binding.yaml获取,然后修改。
##########实操验证##########
[root@vms10 role]# cat role1binding.yaml
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: rbind1
subjects:
- kind: User
name: john
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
[root@vms10 role]#
这里的意思是创建一个名字叫作rbind1的rolebinding,把角色pod-reader授权给john用户,这个也可以使用命令行创建。
kubectl create rolebinding rbind1 --role=pod-reader --user=john
这句话就是创建一个名字为rbind1的rolebinding,把角色pod-reader授权给用户john。
步骤2:创建rolebinding。
##########实操验证##########
[root@vms10 role]# kubectl apply -f role1binding.yaml
rolebinding.rbac.authorization.k8s.io/rbind1 created
[root@vms10 role]#
步骤3:查看现有的rolebinding。
##########实操验证##########
[root@vms10 role]# kubectl get rolebindings
NAME ROLE AGE
rbind1 Role/pod-reader 11s
[root@vms10 role]#
步骤4:查看rbind1的属性。
##########实操验证##########
[root@vms10 role]# kubectl describe rolebindings rbind1
Name: rbind1
Labels: <none>
Annotations: <none>
Role:
Kind: Role
Name: pod-reader
Subjects:
Kind Name Namespace
---- ---- ---------
User john
[root@vms10 role]#
可以看出来,角色pod-reader授权给了john用户。
步骤5:在vms 11上测试(前面已经把kc1拷贝到vms11了)。
##########实操验证##########
[root@vms11 ~]# kubectl --kubeconfig=kc1 get pods -n ns3
Error from server (Forbidden): pods is forbidden: User "john" cannot list resource "pods" in API group "" in the namespace "ns3"
[root@vms11 ~]#
因为授权john只能在当前命名空间(nsrole)里执行,所以在ns3里会出现没有权限的问题。
##########实操验证##########
[root@vms11 ~]# kubectl --kubeconfig=kc1 get pods -n nsrole
No resources found in nsrole namespace.
[root@vms11 ~]#
在nsrole里查询pod就正常了,没有拒绝的提示。
如果查询deployment呢?可以试一下。
##########实操验证##########
[root@vms11 ~]# kubectl --kubeconfig=kc1 get deploy -n nsrole
Error from server (Forbidden): deployments.apps is forbidden: User "john" cannot list resource "deployments" in API group "apps" in the namespace "nsrole"
[root@vms11 ~]#
报错,因为角色pod-reader里只有对pod的操作权限,并没有对deploy的操作权限,所以john只能对pod具有相关的权限,而对deploy没有任何权限。
步骤6:在master上对role1.yaml文件进行修改。
##########实操验证##########
[root@vms10 role]# cat role1.yaml
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: pod-reader
rules:
- apiGroups: ["","apps"]
resources: ["pods","deployments"]
verbs: ["get","watch","list"]
[root@vms10 role]#
[root@vms10 role]# kubectl apply -f role1.yaml
role.rbac.authorization.k8s.io/pod-reader configured
[root@vms10 role]#
这里在resources里加了deployments,意思是角色里添加了管理deployment的权限。如同前面所讲,请务必在apiGroups里把“apps”添加上,否则即使在resources中添加了deployments,也不会生效。
步骤7:再次到vms11上进行测试。
##########实操验证##########
[root@vms11 ~]# kubectl --kubeconfig=kc1 get deploy -n nsrole
No resources found in nsrole namespace.
[root@vms11 ~]#
此时是正常的。
步骤8:测试创建一个deployment。
##########实操验证##########
[root@vms11 ~]# kubectl --kubeconfig=kc1 create deploy web1 --image=nginx -n nsrole
error: failed to create deployment: deployments.apps is forbidden: User "john" cannot create resource "deployments" in API group "apps" in the namespace "nsrole"
[root@vms11 ~]#
因为对deploy只具有查询的权限,并没有给它创建权限。
步骤9:修改role1.yaml。
##########实操验证##########
[root@vms10 role]# cat role1.yaml
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: pod-reader
rules:
- apiGroups: ["","apps"]
resources: ["pods","deployments"]
verbs: ["get","watch","list","create"]
[root@vms10 role]#
应用这个yaml文件。
##########实操验证##########
[root@vms10 role]# kubectl apply -f role1.yaml
role.rbac.authorization.k8s.io/pod-reader configured
[root@vms10 role]#
步骤10:再次测试。
##########实操验证##########
[root@vms11 role]# kubectl --kubeconfig=kc1 create deploy web1 --image=nginx -n nsrole
deployment.apps/web1 created
[root@vms11 role]#
可以看到deployment创建成功了,然后查看deployment。
##########实操验证##########
[root@vms11 ~]# kubectl --kubeconfig=kc1 get deploy -n nsrole
NAME READY UP-TO-DATE AVAILABLE AGE
web1 1/1 1 1 16s
[root@vms11 ~]#
步骤11:现在更新web1的副本数。
##########实操验证##########
[root@vms11 ~]# kubectl --kubeconfig=kc1 scale deployment web1 --replicas=2 -n nsrole
Error from server (Forbidden): deployments.apps "web1" is forbidden: User "john" cannot patch resource "deployments/scale" in API group "apps" in the namespace "nsrole"
[root@vms11 ~]#
更新不了,根据提示应该是对deployments/scale缺少patch权限。
步骤12:继续修改role1.yaml。
##########实操验证##########
[root@vms10 role]# cat role1.yaml
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: pod-reader
rules:
- apiGroups: ["", "apps"]
resources: ["pods", "deployments", "deployments/scale"]
verbs: ["get", "watch", "list", "create", "patch"]
[root@vms10 role]# kubectl apply -f role1.yaml
role.rbac.authorization.k8s.io/pod-reader configured
[root@vms10 role]#
步骤13:回到客户端vms11上验证。
##########实操验证##########
[root@vms11 ~]# kubectl --kubeconfig=kc1 scale deployment web1 --replicas=2 -n nsrole
deployment.apps/web1 scaled
[root@vms11 ~]#
[root@vms11 ~]# kubectl --kubeconfig=kc1 get deploy -n nsrole
NAME READY UP-TO-DATE AVAILABLE AGE
web1 2/2 2 2 6m17s
[root@vms11 ~]#
修改成功,这里要修改副本数的话,必须要添加一个patch的权限才可以。
步骤14:现在删除deployment。
##########实操验证##########
[root@vms11 ~]# kubectl --kubeconfig=kc1 delete deploy web1 -n nsrole
Error from server (Forbidden): deployments.apps "web1" is forbidden: User "john" cannot delete resource "deployments" in API group "apps" in the namespace "nsrole"
[root@vms11 ~]#
没有删除权限,但提示要删除的话,角色必须要对replicasets也具有delete权限才行。
步骤15:继续修改role1.yaml。
##########实操验证##########
[root@vms10 role]# cat role1.yaml
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: pod-reader
rules:
- apiGroups: ["", "apps"]
resources: ["pods", "deployments", "deployments/scale"]
verbs: ["get", "watch", "list", "create", "patch", "delete"]
[root@vms10 role]# kubectl apply -f role1.yaml
role.rbac.authorization.k8s.io/pod-reader configured
[root@vms10 role]#
步骤16:回到vms11上测试。
##########实操验证##########
[root@vms11 ~]# kubectl --kubeconfig=kc1 delete deploy web1 -n nsrole
deployment.apps "web1" deleted
[root@vms11 ~]#
可以看到已经有足够的权限来删除deployment了。
以上可以得到一个结论,就是如果想对哪种资源(比如是pod还是deployment)做某些操作(比如delete或create),那么必须要给角色相关权限才可以。
步骤17:删除role和rolebinding。
##########实操验证##########
[root@vms10 role]# kubectl delete role pod-reader
role.rbac.authorization.k8s.io "pod-reader" deleted
[root@vms10 role]# kubectl delete rolebindings rbind1
rolebinding.rbac.authorization.k8s.io "rbind1" deleted
[root@vms10 role]#
在上面的例子里,在role里授权时对pod和deployment的权限是一样的,如果想把pod和deployment设置不同的权限,可以按如下内容设置。
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: pod-reader
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list"]
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "watch"]
rolebinding也可以通过命令行来快速创建,语法为:
kubectl create role binding名字--role=角色x--user=user 1--user=user 2
这句话的意思是把角色x授权给user 1和user 2。
clusterrole和clusterrolebinding
前面创建的role和rolebinding只能作用于一个具体的命名空间,如果想让角色在所有命名空间都生效的话,需要用到clusterrole和clusterrolebinding。
下面创建一个clusterrole并创建一个clusterrolebinding。
步骤1:创建clusterrole1.yaml,内容如下。
注意:这个文件可以通过kubectl create namex --verb=get,watch,list --resource=deploy --dry-run=client -o yaml > clutsterrole1.yaml快速获取,然后修改。
##########实操验证##########
[root@vms10 role]# cat clusterrole1.yaml
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: pod-reader
rules:
- apiGroups: ["apps"]
resources: ["deployments", "replicasets"]
verbs: ["get", "watch", "list", "create", "update", "delete"]
[root@vms10 role]#
步骤2:创建clusterrole。
##########实操验证##########
[root@vms10 role]# kubectl apply -f clusterrole1.yaml
clusterrole.rbac.authorization.k8s.io/pod-reader created
[root@vms10 role]#
这里就创建了一个名字为pod-reader的clusterrole,此处字段的意义和前面一样,不再赘述。
创建clusterrole也可以通过命令行来实现,在CKA的考试里如果要创建角色,可以通过命令来快速实现,语法如下。
kubectl create clusterrole namex --verb=权限1, 权限2 ... --resource=pods, deployment, ...
这句话的意思是创建一个名字为namex的集群角色,对pods、deployment具有权限1、权限2等权限。
把这个clusterrole授权给john,下面创建一个clusterrolebinding。
步骤3:创建clusterrolebinding1.yaml,内容如下。
注意:这个文件可以通过kubectl create clusterrolebinding cbind1 --clusterrole=pod-reader --user=john --dry-run=client -o yaml > clusterrole1binding.yaml获取,然后修改。
##########实操验证##########
[root@vms10 role]# cat clusterrolebinding1.yaml
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: cbind1
subjects:
- kind: User
name: john
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: pod-reader
apiGroup: rbac.authorization.k8s.io
[root@vms10 role]#
这里是把pod-reader这个clusterrole授权给john用户。
步骤4:创建clusterrolebinding。
##########实操验证##########
[root@vms10 role]# kubectl apply -f clusterrolebinding1.yaml
clusterrolebinding.rbac.authorization.k8s.io/cbind1 created
[root@vms10 role]#
下面开始测试做的授权是否生效。
步骤5:到vms11上进行测试。
##########实操验证##########
[root@vms11 ~]# kubectl --kubeconfig=kc1 get deploy -n ns4
No resources found in ns4 namespace.
[root@vms11 ~]# kubectl --kubeconfig=kc1 get deploy -n ns2
No resources found in ns2 namespace.
[root@vms11 ~]# kubectl --kubeconfig=kc1 get deploy -n ns1
No resources found in ns1 namespace.
[root@vms11 ~]#
可以看到,在所有命名空间里都有权限了。
对于clusterrolebinding来说,也可以使用命令行来创建。
语法为:
kubectl create clusterrolebinding 名字 --role=角色x --user=user1 --user=user2
这句话的意思是把集群角色x授权给user1和user2。
##########实操验证##########
[root@vms10 role]# kubectl delete -f clusterrolebinding1.yaml
clusterrolebinding.rbac.authorization.k8s.io "cbind1" deleted
[root@vms10 role]# kubectl create clusterrolebinding cbind1 --clusterrole=pod-reader --user=john
clusterrolebinding.rbac.authorization.k8s.io/cbind1 created
[root@vms10 role]# cd
[root@vms10 ~]#
这里的意思是,创建一个名字是cbind1的clusterrolebinding,把pod-reader授权给john用户。
注意:clusterrole可以通过binding或者clusterrolebinding绑定到用户。
如果通过binding绑定给用户,在哪个命名空间里创建的binding,则用户只能在那个命名空间具备这个clusterrole里的权限。
如果通过clusterrolebinding绑定给用户,则用户在所有命名空间里都具备这个clusterrole里的权限。
service account
前面讲的用户(比如tom、john等)都是用于登录kubernetes的,这种账户叫作user account。还有另外一种账户可以理解为是kubernetes的内置用户,指定的是pod里的进程以什么身份运行,这种账户叫作service account,简称sa,如图15-2所示。
我们要开发一个应用程序,目的是以web的方式来管理kubernetes。这个程序以pod的方式运行,如图15-2中的pod1,pod1里运行了一个进程,可以接收用户发送的各种请求,比如创建或者删除pod。
当用户从浏览器登录管理界面时,其实是登录到了pod1,通过图形化界面的方式要在ns1命名空间里创建一个podx,这一切实际上都是由pod1里的应用程序来完成。那么pod1里运行的这个进程是否有权限在ns1命名空间里创建pod呢?
我们可以指定pod1里的程序以某个sa身份来运行,然后给这个sa相关权限即可。
sa是基于命名空间隔离的,即不同的命名空间可以有相同的sa名称。下面创建一个sa,然后指定pod以这个sa运行。
以下操作仍然在命名空间nsrole里操作。
步骤1:查看当前命名空间里有多少sa。
##########实操验证##########
[root@vms10 ~]# kubectl get sa
NAME SECRETS AGE
default 1 68m
[root@vms10 ~]#
步骤2:创建名字为app1的sa。
##########实操验证##########
[root@vms10 ~]# kubectl create sa app1
serviceaccount/app1 created
[root@vms10 ~]#
[root@vms10 ~]# kubectl get sa
NAME SECRETS AGE
app1 1 8s
default 1 69m
[root@vms10 ~]#
每创建一个sa,则会自动为它创建一个secret,格式为“sa名-token-xxx”
##########实操验证##########
[root@vms10 ~]# kubectl get secrets | grep app1
app1-token-g4c4w kubernetes.io/service-account-token 3 36s
[root@vms10 ~]#
步骤3:自行创建一个名字为web1的deployment,查看此deployment。
##########实操验证##########
[root@vms10 ~]# kubectl create deploy web1 --image=nginx
deployment.apps/web1 created
[root@vms10 ~]# kubectl get deployments.apps
NAME READY UP-TO-DATE AVAILABLE AGE
web1 1/1 1 1 11s
[root@vms10 ~]#
[root@vms10 ~]# kubectl scale deploy web1 --replicas=3
deployment.apps/web1 scaled
[root@vms10 ~]#
[root@vms10 ~]# kubectl get deployments.apps
NAME READY UP-TO-DATE AVAILABLE AGE
web1 3/3 3 3 99s
[root@vms10 ~]#
要设置deployment里的pod使用app1这个sa运行的话,可以用下面的方法。
kubectl set sa deploy namex sa name
这里是让名字为namex的deployment所创建pod里的进程以saname这个sa的身份运行。
步骤4:设置web1这个deployment所管理pod里的进程,以app1这个sa来运行。
##########实操验证##########
[root@vms10 ~]# kubectl set sa deploy web1 app1
deployment.apps/web1 serviceaccount updated
[root@vms10 ~]#
这会删除原有的pod,然后重新创建新的pod。
步骤5:查看pod。
##########实操验证##########
[root@vms10 ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
web1-56d78fb98c-9f47x 0/1 ContainerCreating 0 6s
web1-56d78fb98c-gffkr 1/1 Running 0 33s
web1-6fbb48567f-4f66r 1/1 Running 0 2m41s
web1-6fbb48567f-gnwm4 0/1 Terminating 0 99s
web1-6fbb48567f-zpw52 1/1 Running 0 99s
[root@vms10 ~]#
步骤6:验证pod是否以指定的sa运行。
##########实操验证##########
[root@vms10 ~]# kubectl describe deployments.apps web1 | grep -i account
Service Account: app1
[root@vms10 ~]#
或者打开kubectl edit deployments.web1之后,直接切换到最后,如图15-3所示。
看到了service Account: app1,就说明pod是以app1这个sa运行了。
步骤7:删除此deployment。
##########实操验证##########
[root@vms10 ~]# kubectl delete deployments web1
deployment.apps "web1" deleted
[root@vms10 ~]#
把角色授权给sa的命令如下。
kubectl create rolebinding 名字 --role=角色x --serviceaccount=命名空间:sa-name
把集群角色授权给sa的命令如下。
kubectl create clusterrolebinding 名字 --clusterrole=角色x --serviceaccount=命名空间:sa-name
意思是把某个角色或者集群角色授权给某命名空间里的sa。