本文主要基于Kubernetes1.21.9和Linux操作系統(tǒng)CentOS7.4。
(資料圖片僅供參考)
服務(wù)器版本 | docker軟件版本 | Kubernetes(k8s)集群版本 | CPU架構(gòu) |
---|---|---|---|
CentOS Linux release 7.4.1708 (Core) | Docker version 20.10.12 | v1.21.9 | x86_64 |
Kubernetes集群架構(gòu):k8scloude1作為master節(jié)點(diǎn),k8scloude2,k8scloude3作為worker節(jié)點(diǎn)。
服務(wù)器 | 操作系統(tǒng)版本 | CPU架構(gòu) | 進(jìn)程 | 功能描述 |
---|---|---|---|---|
k8scloude1/192.168.110.130 | CentOS Linux release 7.4.1708 (Core) | x86_64 | docker,kube-apiserver,etcd,kube-scheduler,kube-controller-manager,kubelet,kube-proxy,coredns,calico | k8s master節(jié)點(diǎn) |
k8scloude2/192.168.110.129 | CentOS Linux release 7.4.1708 (Core) | x86_64 | docker,kubelet,kube-proxy,calico | k8s worker節(jié)點(diǎn) |
k8scloude3/192.168.110.128 | CentOS Linux release 7.4.1708 (Core) | x86_64 | docker,kubelet,kube-proxy,calico | k8s worker節(jié)點(diǎn) |
Kubernetes作為目前最流行的容器編排平臺(tái)之一,提供了強(qiáng)大的安全性能。在Kubernetes集群中,訪(fǎng)問(wèn)控制是保障集群安全的重要組成部分。其中,權(quán)限管理是訪(fǎng)問(wèn)控制的核心。本篇博客將介紹Kubernetes中的權(quán)限管理機(jī)制之RBAC鑒權(quán)。
使用RBAC鑒權(quán)的前提是已經(jīng)有一套可以正常運(yùn)行的Kubernetes集群,關(guān)于Kubernetes(k8s)集群的安裝部署,可以查看博客《Centos7 安裝部署Kubernetes(k8s)集群》https://www.cnblogs.com/renshengdezheli/p/16686769.html。
三.Kubernetes訪(fǎng)問(wèn)控制用戶(hù)使用 kubectl、客戶(hù)端庫(kù)或構(gòu)造 REST 請(qǐng)求來(lái)訪(fǎng)問(wèn) Kubernetes API。 用戶(hù)賬戶(hù)和 Kubernetes 服務(wù)賬號(hào)都可以被鑒權(quán)訪(fǎng)問(wèn) API。 當(dāng)請(qǐng)求到達(dá) API 時(shí),它會(huì)經(jīng)歷多個(gè)階段,如下圖所示:
整體過(guò)程簡(jiǎn)述:請(qǐng)求發(fā)起方進(jìn)行K8s API請(qǐng)求,建立 TLS 后,經(jīng)過(guò)Authentication(認(rèn)證)、Authorization(鑒權(quán))、AdmissionControl(準(zhǔn)入控制)三個(gè)階段的校驗(yàn),最后把請(qǐng)求轉(zhuǎn)化為對(duì)K8s對(duì)象的變更操作持久化至etcd中。
關(guān)于Authentication(認(rèn)證)詳細(xì)內(nèi)容請(qǐng)查看博客《Kubernetes(k8s)訪(fǎng)問(wèn)控制:身份認(rèn)證》。
四.鑒權(quán)簡(jiǎn)介在Kubernetes中,鑒權(quán)(Authorization)是指檢查用戶(hù)是否有權(quán)限執(zhí)行請(qǐng)求所需的操作的過(guò)程。鑒權(quán)機(jī)制由Kubernetes API server實(shí)現(xiàn),并可以支持RBAC(基于角色的訪(fǎng)問(wèn)控制)、ABAC(基于屬性的訪(fǎng)問(wèn)控制)和Node鑒權(quán)等多種方式。
RBAC/ABAC/Node鑒權(quán)區(qū)別:
RBAC(Role-Based Access Control):基于角色的訪(fǎng)問(wèn)控制。RBAC允許管理員定義一系列角色,每個(gè)角色包含一組權(quán)限和資源。然后,將用戶(hù)或者服務(wù)賬戶(hù)與相應(yīng)的角色綁定起來(lái)。這樣,用戶(hù)或者服務(wù)賬戶(hù)就可以訪(fǎng)問(wèn)其相應(yīng)的角色包含的資源和權(quán)限了。RBAC是Kubernetes推薦的鑒權(quán)方式。ABAC(Attribute-Based Access Control):基于屬性的訪(fǎng)問(wèn)控制。ABAC允許管理員定義一系列策略,每個(gè)策略包含多個(gè)屬性,例如用戶(hù)身份、資源類(lèi)型、操作類(lèi)型等。當(dāng)一個(gè)請(qǐng)求被發(fā)送到API server時(shí),API server會(huì)檢查該請(qǐng)求是否滿(mǎn)足所有匹配的策略。Node鑒權(quán):在Kubernetes中,每個(gè)節(jié)點(diǎn)都有主機(jī)名和IP地址。Node鑒權(quán)是指Kubernetes API server根據(jù)節(jié)點(diǎn)信息對(duì)請(qǐng)求進(jìn)行授權(quán)的過(guò)程??梢允褂肗ode鑒權(quán)來(lái)限制哪些節(jié)點(diǎn)可以訪(fǎng)問(wèn)某些資源。在本篇博客中,我們將重點(diǎn)介紹RBAC鑒權(quán)。
五.配置客戶(hù)端機(jī)器如下是我們的kubernetes集群。
[root@k8scloude1 ~]# kubectl get nodes -o wideNAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIMEk8scloude1 Ready control-plane,master 67d v1.21.0 192.168.110.130 CentOS Linux 7 (Core) 3.10.0-693.el7.x86_64 docker://20.10.12k8scloude2 Ready 67d v1.21.0 192.168.110.129 CentOS Linux 7 (Core) 3.10.0-693.el7.x86_64 docker://20.10.12k8scloude3 Ready 67d v1.21.0 192.168.110.128 CentOS Linux 7 (Core) 3.10.0-693.el7.x86_64 docker://20.10.12
先準(zhǔn)備一臺(tái)機(jī)器作為訪(fǎng)問(wèn)k8s集群的客戶(hù)端,機(jī)器etcd1作為客戶(hù)端,不是k8s集群的一部分。
訪(fǎng)問(wèn)k8s集群需要客戶(hù)端工具kubectl,下面安裝kubectl,--disableexcludes=kubernetes 表示禁掉除了這個(gè)之外的別的倉(cāng)庫(kù)。
[root@etcd1 ~]# yum -y install kubectl-1.21.0-0 --disableexcludes=kubernetes
配置kubectl命令自動(dòng)補(bǔ)全。
[root@etcd1 ~]# vim /etc/profile[root@etcd1 ~]# grep source /etc/profilesource <(kubectl completion bash)
使配置生效。
[root@etcd1 ~]# source /etc/profile[root@etcd1 ~]# kubectl get nodeThe connection to the server localhost:8080 was refused - did you specify the right host or port?
六.設(shè)置k8s集群允許所有請(qǐng)求訪(fǎng)問(wèn)kubernetes默認(rèn)的授權(quán)模式為:authorization-mode=Node,RBAC。
[root@k8scloude1 ~]# ls /etc/kubernetes/manifests/kube-apiserver.yaml /etc/kubernetes/manifests/kube-apiserver.yaml[root@k8scloude1 ~]# grep authorization-mode /etc/kubernetes/manifests/kube-apiserver.yaml - --authorization-mode=Node,RBAC
設(shè)置k8s允許所有請(qǐng)求訪(fǎng)問(wèn)。
[root@k8scloude1 ~]# vim /etc/kubernetes/manifests/kube-apiserver.yaml [root@k8scloude1 ~]# grep authorization-mode /etc/kubernetes/manifests/kube-apiserver.yaml #- --authorization-mode=Node,RBAC - --authorization-mode=AlwaysAllow
重啟kubelet使配置生效。
[root@k8scloude1 ~]# systemctl restart kubelet[root@k8scloude1 ~]# systemctl status kubelet● kubelet.service - kubelet: The Kubernetes Node Agent Loaded: loaded (/usr/lib/systemd/system/kubelet.service; enabled; vendor preset: disabled) Drop-In: /usr/lib/systemd/system/kubelet.service.d └─10-kubeadm.conf Active: active (running) since 五 2022-03-18 18:36:24 CST; 11s ago Docs: https://kubernetes.io/docs/ Main PID: 28054 (kubelet) Memory: 42.4M CGroup: /system.slice/kubelet.service └─28054 /usr/bin/kubelet --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf --config=/var/lib/kubelet/config.yaml --network-plugin=cni --pod-in...
當(dāng)- --authorization-mode=AlwaysAllow 設(shè)置為允許所有請(qǐng)求之后,客戶(hù)端機(jī)器可以隨意訪(fǎng)問(wèn)所有資源。
kctest這個(gè)自定義的kubeconfig文件博客《Kubernetes(k8s)訪(fǎng)問(wèn)控制:身份認(rèn)證》已經(jīng)詳細(xì)講解過(guò)了,這里就不贅述了。
在etcd1機(jī)器上可以訪(fǎng)問(wèn)任何資源。
[root@etcd1 ~]# kubectl get nodes --kubeconfig=kctest NAME STATUS ROLES AGE VERSIONk8scloude1 Ready control-plane,master 68d v1.21.0k8scloude2 Ready 68d v1.21.0k8scloude3 Ready 68d v1.21.0[root@etcd1 ~]# kubectl get pod -A --kubeconfig=kctest NAMESPACE NAME READY STATUS RESTARTS AGEingress-nginx ingress-nginx-admission-create-2lg57 0/1 Completed 0 31dingress-nginx ingress-nginx-admission-patch-hd7p4 0/1 Completed 1 31dingress-nginx ingress-nginx-controller-59b8bf5fdc-t2f7z 1/1 Running 14 31dkube-system calico-kube-controllers-6b9fbfff44-4jzkj 1/1 Running 78 68dkube-system calico-node-bdlgm 1/1 Running 38 68dkube-system calico-node-hx8bk 1/1 Running 38 68dkube-system calico-node-nsbfs 1/1 Running 38 68dkube-system coredns-545d6fc579-7wm95 1/1 Running 38 68dkube-system coredns-545d6fc579-87q8j 1/1 Running 38 68dkube-system etcd-k8scloude1 1/1 Running 38 68dkube-system kube-apiserver-k8scloude1 0/1 Running 1 8m36skube-system kube-controller-manager-k8scloude1 1/1 Running 45 68dkube-system kube-proxy-599xh 1/1 Running 38 68dkube-system kube-proxy-lpj8z 1/1 Running 38 68dkube-system kube-proxy-zxlk9 1/1 Running 38 68dkube-system kube-scheduler-k8scloude1 1/1 Running 45 68dkube-system metrics-server-bcfb98c76-n4fnb 1/1 Running 42 60dmetallb-system controller-7dcc8764f4-qdwl2 1/1 Running 24 34dmetallb-system speaker-892pm 1/1 Running 16 34dmetallb-system speaker-jfccb 1/1 Running 16 34dmetallb-system speaker-nkrgk 1/1 Running 16 34dvolume nfs-client-provisioner-76c576954d-5x7t2 1/1 Running 16 57d
七.設(shè)置k8s集群拒絕所有請(qǐng)求訪(fǎng)問(wèn)設(shè)置k8s拒絕所有請(qǐng)求訪(fǎng)問(wèn)。
[root@k8scloude1 ~]# vim /etc/kubernetes/manifests/kube-apiserver.yaml #設(shè)置為拒絕所有請(qǐng)求[root@k8scloude1 ~]# grep authorization-mode /etc/kubernetes/manifests/kube-apiserver.yaml #- --authorization-mode=Node,RBAC - --authorization-mode=AlwaysDeny
重啟kubelet使配置生效。
[root@k8scloude1 ~]# systemctl restart kubelet
設(shè)置為拒絕所有請(qǐng)求 - --authorization-mode=AlwaysDeny之后,客戶(hù)端機(jī)器訪(fǎng)問(wèn)不了了。
[root@etcd1 ~]# kubectl get pod -A --kubeconfig=kctest error: the server doesn"t have a resource type "pod"[root@etcd1 ~]# kubectl get nodes --kubeconfig=kctest error: the server doesn"t have a resource type "nodes"[root@etcd1 ~]# kubectl get node --kubeconfig=kctest error: the server doesn"t have a resource type "node"
設(shè)置為拒絕所有請(qǐng)求 - --authorization-mode=AlwaysDeny之后,admin管理員用戶(hù)無(wú)影響,其他用戶(hù)訪(fǎng)問(wèn)不了。
[root@k8scloude1 ~]# kubectl get nodeNAME STATUS ROLES AGE VERSIONk8scloude1 Ready control-plane,master 68d v1.21.0k8scloude2 Ready 68d v1.21.0k8scloude3 Ready 68d v1.21.0
八.RBAC授權(quán)RBAC支持基于角色的授權(quán),即將一組權(quán)限分配給一個(gè)角色,再將該角色分配給一個(gè)或多個(gè)用戶(hù)或服務(wù)賬戶(hù)。在Kubernetes中,RBAC鑒權(quán)由以下三個(gè)部分組成:
Role:針對(duì)特定命名空間(Namespace)內(nèi)的資源定義一組操作權(quán)限。RoleBinding:將Role和Subject(User或ServiceAccount)關(guān)聯(lián)起來(lái),以便Subject能夠執(zhí)行Role所定義的操作。ClusterRole和ClusterRoleBinding:類(lèi)似于上述兩個(gè)對(duì)象,但作用于整個(gè)集群。8.1 role,rolebinding想要使用RBAC授權(quán),需要恢復(fù)- --authorization-mode=Node,RBAC,想要查看什么,都是我們敲命令獲取,其實(shí)有很多我們看不到的操作(比如master和worker之間交互查詢(xún),審計(jì)等等),- --authorization-mode=Node 表示允許worker向master查詢(xún)相應(yīng)信息,想要--authorization-mode=Node生效,--enable-admission-plugins=NodeRestriction準(zhǔn)入控制器要開(kāi)啟。
[root@k8scloude1 ~]# vim /etc/kubernetes/manifests/kube-apiserver.yaml [root@k8scloude1 ~]# grep authorization-mode /etc/kubernetes/manifests/kube-apiserver.yaml - --authorization-mode=Node,RBAC #- --authorization-mode=AlwaysDeny
重啟kubelet使配置生效。
[root@k8scloude1 ~]# systemctl restart kubelet
管理員擁有所有權(quán)限,查看管理員的權(quán)限就可以知道k8s有哪些權(quán)限。
[root@k8scloude1 ~]# kubectl describe clusterrole cluster-adminName: cluster-adminLabels: kubernetes.io/bootstrapping=rbac-defaultsAnnotations: rbac.authorization.kubernetes.io/autoupdate: truePolicyRule: Resources Non-Resource URLs Resource Names Verbs --------- ----------------- -------------- ----- *.* [] [] [*] [*] [] [*]
可以看到admin角色對(duì)各種資源Resources的權(quán)限Verbs。
[root@k8scloude1 ~]# kubectl describe clusterrole adminName: adminLabels: kubernetes.io/bootstrapping=rbac-defaultsAnnotations: rbac.authorization.kubernetes.io/autoupdate: truePolicyRule: Resources Non-Resource URLs Resource Names Verbs --------- ----------------- -------------- ----- rolebindings.rbac.authorization.k8s.io [] [] [create delete deletecollection get list patch update watch] roles.rbac.authorization.k8s.io [] [] [create delete deletecollection get list patch update watch] ...... services/proxy [] [] [get list watch create delete deletecollection patch update] bindings [] [] [get list watch] events [] [] [get list watch] limitranges [] [] [get list watch] namespaces/status [] [] [get list watch] namespaces [] [] [get list watch] persistentvolumeclaims/status [] [] [get list watch] pods/log [] [] [get list watch] pods/status [] [] [get list watch] replicationcontrollers/status [] [] [get list watch] ...... pods.metrics.k8s.io [] [] [get list watch] ingresses.networking.k8s.io/status [] [] [get list watch] poddisruptionbudgets.policy/status [] [] [get list watch] serviceaccounts [] [] [impersonate create delete deletecollection patch update get list watch]
8.1.1 給test用戶(hù)授予對(duì)pod的get和list權(quán)限注意:RBAC不是直接把權(quán)限授予用戶(hù),而是把權(quán)限都放在角色role里,再把角色role綁定rolebinding到用戶(hù),這樣用戶(hù)就具有了相應(yīng)的權(quán)限,注意對(duì)于命名空間ns1里的角色role1,命名空間ns2不能使用。
除了role,還有clusterrole,role是歸屬于某一個(gè)namespace,clusterrole是全局生效的,clusterrole除了可以使用rolebinding綁定之外,還可以使用clusterrolebingding綁定,rolebinding歸屬于某一個(gè)命名空間,clusterrolebingding全局生效。
查看角色role。
[root@k8scloude1 ~]# kubectl get roleNo resources found in safe namespace.[root@k8scloude1 ~]# cd safe/
我們使用yaml文件的方式創(chuàng)建角色role :kubectl create role role1 --verb=get,list --resource=pods --dry-run=client -o yaml > role1.yaml。
--verb=get,list指定權(quán)限為get和list,--resource=pods表示權(quán)限作用在pod上。
[root@k8scloude1 safe]# kubectl create role role1 --verb=get,list --resource=pods --dry-run=client -o yaml > role1.yaml
查看yaml文件,功能為:在 Kubernetes 集群中創(chuàng)建一個(gè)叫做 "role1" 的角色(Role),該角色具有操作(Kubernetes Pod)的權(quán)限。
[root@k8scloude1 safe]# vim role1.yaml [root@k8scloude1 safe]# cat role1.yaml apiVersion: rbac.authorization.k8s.io/v1kind: Rolemetadata: creationTimestamp: null #name: role1: 該角色的名稱(chēng)為 "role1"。 name: role1#rules: 角色的規(guī)則部分定義了角色能夠執(zhí)行的操作列表。 rules:#- apiGroups: [""]: apiGroups 字段指定資源所屬的 API 組(或者不屬于任何組)。在本例中,Pod 不屬于任何 API 組,所以值為空字符串。- apiGroups: - "" #resources: ["pods"]: resources 字段指定角色能夠訪(fǎng)問(wèn)的資源列表。在本例中,只有 Pod 是被授權(quán)的資源。 resources: - pods #verbs: ["get", "list"]: verbs 字段列出了角色可用的動(dòng)詞列表。在本例中,角色可以執(zhí)行 "get" 和 "list" 操作。這意味著此角色可以查看 Pod 的詳細(xì)信息和列表信息。 verbs: - get - list
生成role。
[root@k8scloude1 safe]# kubectl apply -f role1.yaml role.rbac.authorization.k8s.io/role1 created
查看role。
[root@k8scloude1 safe]# kubectl get roleNAME CREATED ATrole1 2022-03-19T09:52:13Z
查看role的權(quán)限:對(duì)pod具有g(shù)et list權(quán)限。
[root@k8scloude1 safe]# kubectl describe role role1 Name: role1Labels: Annotations: PolicyRule: Resources Non-Resource URLs Resource Names Verbs --------- ----------------- -------------- ----- pods [] [] [get list]
把角色role1綁定到test用戶(hù)上,test用戶(hù)不屬于任何命名空間。
[root@k8scloude1 safe]# kubectl create rolebinding rolebind1 --role=role1 --user=testrolebinding.rbac.authorization.k8s.io/rolebind1 created
查看rolebinding。
[root@k8scloude1 safe]# kubectl get rolebindingNAME ROLE AGErolebind1 Role/role1 110s
查看rolebind1的描述信息。
[root@k8scloude1 safe]# kubectl describe rolebinding rolebind1 Name: rolebind1Labels: Annotations: Role: Kind: Role Name: role1Subjects: Kind Name Namespace ---- ---- --------- User test
在客戶(hù)端進(jìn)行權(quán)限測(cè)試,把角色role1綁定給test用戶(hù)之后,客戶(hù)端具有了safe命名空間里pod的查詢(xún)權(quán)限。
[root@etcd1 ~]# kubectl get pods --kubeconfig=kctest -n safeNo resources found in safe namespace.
客戶(hù)端不具有default命名空間里pod的查詢(xún)權(quán)限。
[root@etcd1 ~]# kubectl get pods --kubeconfig=kctest Error from server (Forbidden): pods is forbidden: User "test" cannot list resource "pods" in API group "" in the namespace "default"
8.1.2 增加對(duì)pod的創(chuàng)建權(quán)限如下是使用nginx鏡像創(chuàng)建pod的配置文件。
[root@etcd1 ~]# cat pod.yaml apiVersion: v1kind: Podmetadata: labels: test: podtest name: podtestspec: #當(dāng)需要關(guān)閉容器時(shí),立即殺死容器而不等待默認(rèn)的30秒優(yōu)雅停機(jī)時(shí)長(zhǎng)。 terminationGracePeriodSeconds: 0 containers: - name: nginx image: nginx #imagePullPolicy: IfNotPresent:表示如果本地已經(jīng)存在該鏡像,則不重新下載;否則從遠(yuǎn)程 Docker Hub 下載該鏡像 imagePullPolicy: IfNotPresent
現(xiàn)在想在客戶(hù)端創(chuàng)建一個(gè)pod,用戶(hù)test只對(duì)pod有g(shù)et ,list權(quán)限,沒(méi)有創(chuàng)建pod權(quán)限,創(chuàng)建失敗。
[root@etcd1 ~]# kubectl apply -f pod.yaml -n safe --kubeconfig=kctest Error from server (Forbidden): error when creating "pod.yaml": pods is forbidden: User "test" cannot create resource "pods" in API group "" in the namespace "safe"
修改yaml文件,添加pod的create權(quán)限。
[root@k8scloude1 safe]# vim role1.yaml [root@k8scloude1 safe]# cat role1.yaml apiVersion: rbac.authorization.k8s.io/v1kind: Rolemetadata: creationTimestamp: null name: role1rules:- apiGroups: - "" resources: - pods #添加了創(chuàng)建權(quán)限create verbs: - get - list - create
應(yīng)用role。
[root@k8scloude1 safe]# kubectl apply -f role1.yaml role.rbac.authorization.k8s.io/role1 configured
現(xiàn)在role1具有了對(duì)pod的get list create權(quán)限。
[root@k8scloude1 safe]# kubectl describe role role1 Name: role1Labels: Annotations: PolicyRule: Resources Non-Resource URLs Resource Names Verbs --------- ----------------- -------------- ----- pods [] [] [get list create]
role1添加pod的create權(quán)限之后,成功在客戶(hù)端創(chuàng)建pod。
[root@etcd1 ~]# kubectl apply -f pod.yaml -n safe --kubeconfig=kctest pod/podtest created[root@etcd1 ~]# kubectl get pod -n safe --kubeconfig=kctest NAME READY STATUS RESTARTS AGEpodtest 1/1 Running 0 22s
8.1.3 增加對(duì)pod的刪除權(quán)限用戶(hù)test沒(méi)有pod刪除權(quán)限。
[root@etcd1 ~]# kubectl delete pod podtest -n safe --kubeconfig=kctest Error from server (Forbidden): pods "podtest" is forbidden: User "test" cannot delete resource "pods" in API group "" in the namespace "safe"
給角色role1增加刪除pod的權(quán)限。
[root@k8scloude1 safe]# vim role1.yaml [root@k8scloude1 safe]# cat role1.yaml apiVersion: rbac.authorization.k8s.io/v1kind: Rolemetadata: creationTimestamp: null name: role1rules:- apiGroups: - "" resources: - pods #增加刪除權(quán)限delete verbs: - get - list - create - delete
應(yīng)用role。
[root@k8scloude1 safe]# kubectl apply -f role1.yaml role.rbac.authorization.k8s.io/role1 configured
現(xiàn)在role1具有了對(duì)pod的get list create delete權(quán)限。
[root@k8scloude1 safe]# kubectl describe role role1 Name: role1Labels: Annotations: PolicyRule: Resources Non-Resource URLs Resource Names Verbs --------- ----------------- -------------- ----- pods [] [] [get list create delete]
給角色role1增加刪除pod的權(quán)限之后,客戶(hù)端成功刪除了pod。
[root@etcd1 ~]# kubectl delete pod podtest -n safe --kubeconfig=kctest pod "podtest" deleted[root@etcd1 ~]# kubectl get pod -n safe --kubeconfig=kctest No resources found in safe namespace.
8.1.4 增加對(duì)svc的get list create delete權(quán)限test用戶(hù)沒(méi)有對(duì)services的list權(quán)限。
[root@etcd1 ~]# kubectl get svc -n safe --kubeconfig=kctest Error from server (Forbidden): services is forbidden: User "test" cannot list resource "services" in API group "" in the namespace "safe"
修改yaml文件,對(duì)role1添加service的get list create delete權(quán)限,注意:services不能簡(jiǎn)寫(xiě)。
[root@k8scloude1 safe]# vim role1.yaml [root@k8scloude1 safe]# cat role1.yaml apiVersion: rbac.authorization.k8s.io/v1kind: Rolemetadata: creationTimestamp: null name: role1rules:- apiGroups: - "" #資源里增加services resources: - pods - services verbs: - get - list - create - delete
應(yīng)用role。
[root@k8scloude1 safe]# kubectl apply -f role1.yaml role.rbac.authorization.k8s.io/role1 configured
查看角色的描述信息,角色role1增加了services的get list create delete權(quán)限。
[root@k8scloude1 safe]# kubectl describe role role1 Name: role1Labels: Annotations: PolicyRule: Resources Non-Resource URLs Resource Names Verbs --------- ----------------- -------------- ----- pods [] [] [get list create delete] services [] [] [get list create delete]
給角色role1增加了services的get list create delete權(quán)限之后,客戶(hù)端可以查詢(xún)svc了。
[root@etcd1 ~]# kubectl get svc -n safe --kubeconfig=kctest No resources found in safe namespace.
8.1.5 增加對(duì)deployments的get list create delete權(quán)限客戶(hù)端沒(méi)有對(duì)deployments的list權(quán)限。
[root@etcd1 ~]# kubectl get deploy -n safe --kubeconfig=kctest Error from server (Forbidden): deployments.apps is forbidden: User "test" cannot list resource "deployments" in API group "apps" in the namespace "safe"
修改yaml文件,給role1添加deployments的get list create delete權(quán)限。
[root@k8scloude1 safe]# vim role1.yaml [root@k8scloude1 safe]# cat role1.yaml apiVersion: rbac.authorization.k8s.io/v1kind: Rolemetadata: creationTimestamp: null name: role1rules:- apiGroups: - "" resources: - pods - services - deployments verbs: - get - list - create - delete
應(yīng)用role。
[root@k8scloude1 safe]# kubectl apply -f role1.yaml role.rbac.authorization.k8s.io/role1 configured
查看角色的描述信息,角色role1增加了deployments的get list create delete權(quán)限。
[root@k8scloude1 safe]# kubectl describe role role1 Name: role1Labels: Annotations: PolicyRule: Resources Non-Resource URLs Resource Names Verbs --------- ----------------- -------------- ----- deployments [] [] [get list create delete] pods [] [] [get list create delete] services [] [] [get list create delete]
給角色role1增加了deployments的get list create delete權(quán)限之后,客戶(hù)端還是沒(méi)有對(duì)deployments的list權(quán)限。
[root@etcd1 ~]# kubectl get deploy -n safe --kubeconfig=kctest Error from server (Forbidden): deployments.apps is forbidden: User "test" cannot list resource "deployments" in API group "apps" in the namespace "safe"
給角色role1增加了deployments的get list create delete權(quán)限之后,客戶(hù)端還是沒(méi)有對(duì)deployments的list權(quán)限,原因?yàn)椋?strong>pod,service對(duì)應(yīng)的apiVersion為v1,deploy對(duì)應(yīng)的apiVersion為apps/v1。
apiVersion的結(jié)構(gòu)有 xx ,yy/zz ,對(duì)于xx結(jié)構(gòu),apiGroups寫(xiě)為:apiGroups:"",對(duì)于yy/zz結(jié)構(gòu),apiGroups寫(xiě)為:apiGroups:"yy"。
如果apiGroups只寫(xiě)為“”,不寫(xiě)"apps"則pods,services生效,deployments不生效,因?yàn)闆](méi)有父級(jí),如果apiGroups只寫(xiě)為"apps",不寫(xiě)""則pods,services不生效,deployments生效,因?yàn)閜ods,services沒(méi)有父級(jí)。
下面才是正確的寫(xiě)法,修改yaml文件。
[root@k8scloude1 safe]# vi role1.yaml [root@k8scloude1 safe]# cat role1.yaml apiVersion: rbac.authorization.k8s.io/v1kind: Rolemetadata: creationTimestamp: null name: role1rules:#- apiGroups: ["apps"]: apiGroups 字段指定資源所屬的 API 組(或者不屬于任何組)。在本例中,deployments 屬于 apps/v1 組,所以值為apps。- apiGroups: - "" - "apps" resources: - pods - services - deployments verbs: - get - list - create - delete
應(yīng)用role。
[root@k8scloude1 safe]# kubectl apply -f role1.yaml role.rbac.authorization.k8s.io/role1 configured
查看role1的描述信息。
[root@k8scloude1 safe]# kubectl describe role role1 Name: role1Labels: Annotations: PolicyRule: Resources Non-Resource URLs Resource Names Verbs --------- ----------------- -------------- ----- deployments [] [] [get list create delete] pods [] [] [get list create delete] services [] [] [get list create delete] deployments.apps [] [] [get list create delete] pods.apps [] [] [get list create delete] services.apps [] [] [get list create delete]
給role1添加deployment的get list create delete權(quán)限之后,客戶(hù)端可以查詢(xún)deploy了。
[root@etcd1 ~]# kubectl get deploy -n safe --kubeconfig=kctest No resources found in safe namespace.
如下是使用Nginx鏡像創(chuàng)建deploy的yaml文件。
[root@etcd1 ~]# cat nginx.yaml apiVersion: apps/v1kind: Deploymentmetadata: creationTimestamp: null labels: app: nginx name: nginxspec: #5個(gè)副本 replicas: 5 selector: matchLabels: app: nginx strategy: {} template: metadata: creationTimestamp: null labels: app: nginx spec: #當(dāng)需要關(guān)閉容器時(shí),立即殺死容器而不等待默認(rèn)的30秒優(yōu)雅停機(jī)時(shí)長(zhǎng)。 terminationGracePeriodSeconds: 0 containers: - image: nginx name: nginx #imagePullPolicy: IfNotPresent:表示如果本地已經(jīng)存在該鏡像,則不重新下載;否則從遠(yuǎn)程 Docker Hub 下載該鏡像 imagePullPolicy: IfNotPresent resources: {}status: {}
在客戶(hù)端創(chuàng)建deploy,由于被授權(quán)了,deploy創(chuàng)建成功。
[root@etcd1 ~]# kubectl apply -f nginx.yaml -n safe --kubeconfig=kctest deployment.apps/nginx created[root@etcd1 ~]# kubectl get deploy -n safe --kubeconfig=kctest NAME READY UP-TO-DATE AVAILABLE AGEnginx 5/5 5 5 23s[root@etcd1 ~]# kubectl get pod -n safe --kubeconfig=kctest NAME READY STATUS RESTARTS AGEnginx-6cf858f6cf-62m8t 1/1 Running 0 72snginx-6cf858f6cf-74nzb 1/1 Running 0 72snginx-6cf858f6cf-bw84g 1/1 Running 0 72snginx-6cf858f6cf-cmj95 1/1 Running 0 72snginx-6cf858f6cf-fzs4l 1/1 Running 0 72s
剛才給role1添加deployments權(quán)限寫(xiě)的不好,如下為優(yōu)化后的寫(xiě)法:
[root@k8scloude1 safe]# vim role1.yaml #對(duì)于給role1添加權(quán)限還可以有另一種寫(xiě)法(這種方法更好),如下[root@k8scloude1 safe]# cat role1.yaml apiVersion: rbac.authorization.k8s.io/v1kind: Rolemetadata: creationTimestamp: null name: role1rules:- apiGroups: - "" resources: - pods - services verbs: - get - list - create - delete- apiGroups: - "apps" resources: - deployments verbs: - get - list - create - delete
8.1.6 增加對(duì)deployments的patch權(quán)限把nginx的deploy的副本數(shù)變?yōu)?,發(fā)現(xiàn)用戶(hù)test沒(méi)有deployments/scale的patch權(quán)限。
[root@etcd1 ~]# kubectl scale deploy nginx --replicas=2 -n safe --kubeconfig=kctest Error from server (Forbidden): deployments.apps "nginx" is forbidden: User "test" cannot patch resource "deployments/scale" in API group "apps" in the namespace "safe"
修改yaml文件,添加deployments/scale的patch權(quán)限。
[root@k8scloude1 safe]# vim role1.yaml [root@k8scloude1 safe]# cat role1.yaml apiVersion: rbac.authorization.k8s.io/v1kind: Rolemetadata: creationTimestamp: null name: role1rules:- apiGroups: - "" resources: - pods - services - deployments verbs: - get - list - create - delete- apiGroups: - "apps" resources: - deployments - deployments/scale verbs: - get - list - create - delete - patch
應(yīng)用role。
[root@k8scloude1 safe]# kubectl apply -f role1.yaml role.rbac.authorization.k8s.io/role1 configured
查看role1的描述信息。
[root@k8scloude1 safe]# kubectl describe role role1 Name: role1Labels: Annotations: PolicyRule: Resources Non-Resource URLs Resource Names Verbs --------- ----------------- -------------- ----- deployments.apps/scale [] [] [get list create delete patch] deployments.apps [] [] [get list create delete patch] deployments [] [] [get list create delete] pods [] [] [get list create delete] services [] [] [get list create delete]
添加deployments/scale的patch權(quán)限之后,客戶(hù)端可以修改副本數(shù)了。
[root@etcd1 ~]# kubectl scale deploy nginx --replicas=2 -n safe --kubeconfig=kctest deployment.apps/nginx scaled[root@etcd1 ~]# kubectl get deploy -n safe --kubeconfig=kctest NAME READY UP-TO-DATE AVAILABLE AGEnginx 2/2 2 2 7m19s
刪除deploy。
[root@etcd1 ~]# kubectl delete -f nginx.yaml -n safe --kubeconfig=kctest deployment.apps "nginx" deleted[root@etcd1 ~]# kubectl get deploy -n safe --kubeconfig=kctest No resources found in safe namespace.
8.2 clusterrole,clusterrolebinding上面做的權(quán)限都是role,rolebinding,下面開(kāi)始clusterrole,clusterrolebinding。
刪除role。
[root@k8scloude1 safe]# kubectl get roleNAME CREATED ATrole1 2022-03-19T09:52:13Z[root@k8scloude1 safe]# kubectl delete -f role1.yaml role.rbac.authorization.k8s.io "role1" deleted[root@k8scloude1 safe]# kubectl get roleNo resources found in safe namespace.
刪除rolebinding。
[root@k8scloude1 safe]# kubectl get rolebindingNAME ROLE AGErolebind1 Role/role1 25h[root@k8scloude1 safe]# kubectl delete rolebinding rolebind1 rolebinding.rbac.authorization.k8s.io "rolebind1" deleted[root@k8scloude1 safe]# kubectl get rolebindingNo resources found in safe namespace.
8.2.1 test用戶(hù)授予對(duì)Pod、Service 、Deployment 的get 和 create 權(quán)限生成創(chuàng)建clusterrole的yaml文件,--verb指定權(quán)限,--resource指定作用的資源。
[root@k8scloude1 safe]# kubectl create clusterrole clusterrole1 --verb=get,create --resource=pod,svc,deploy --dry-run=client -o yaml >clusterrole1.yaml
查看ClusterRole的yaml文件,功能為:在 Kubernetes 集群中創(chuàng)建一個(gè)叫做 "clusterrole1" 的集群角色(ClusterRole),該角色具有對(duì) Pod、Service 和 Deployment 資源的操作權(quán)限。
使用這個(gè) YAML 文件在 Kubernetes 中創(chuàng)建 "clusterrole1" 集群角色后,該角色將能夠訪(fǎng)問(wèn) Pod、Service 和 Deployment 資源,并且具有 get 和 create 操作權(quán)限。
[root@k8scloude1 safe]# vim clusterrole1.yaml [root@k8scloude1 safe]# cat clusterrole1.yaml apiVersion: rbac.authorization.k8s.io/v1#kind: ClusterRole: ClusterRole 是 Kubernetes 集群級(jí)別的角色授權(quán)機(jī)制,與 Role 類(lèi)似,但是它可以跨命名空間使用。kind: ClusterRolemetadata: creationTimestamp: null name: clusterrole1rules:- apiGroups: - "" resources: - pods - services verbs: - get - create- apiGroups: - apps resources: - deployments verbs: - get - create
應(yīng)用clusterrole。
[root@k8scloude1 safe]# kubectl apply -f clusterrole1.yaml clusterrole.rbac.authorization.k8s.io/clusterrole1 created
查看clusterrole。
[root@k8scloude1 safe]# kubectl get clusterrole | grep clusterrole1clusterrole1 2022-03-20T11:24:36Z
kubernetes集群自帶的clusterrole有很多。
[root@k8scloude1 safe]# kubectl get clusterrole | wc -l75
把集群角色clusterrole1使用clusterrolebinding綁定給用戶(hù)test。
[root@k8scloude1 safe]# kubectl create clusterrolebinding clusterrolebinding1 --clusterrole=clusterrole1 --user=testclusterrolebinding.rbac.authorization.k8s.io/clusterrolebinding1 created
查看clusterrolebinding。
[root@k8scloude1 safe]# kubectl get clusterrolebinding | grep clusterrolebinding1clusterrolebinding1 ClusterRole/clusterrole1 25s[root@k8scloude1 safe]# kubectl get clusterrolebinding | wc -l60
查看集群綁定的描述信息。
[root@k8scloude1 safe]# kubectl describe clusterrolebinding clusterrolebinding1Name: clusterrolebinding1Labels: Annotations: Role: Kind: ClusterRole Name: clusterrole1Subjects: Kind Name Namespace ---- ---- --------- User test
查看集群角色的描述信息。
[root@k8scloude1 safe]# kubectl describe clusterrole clusterrole1 Name: clusterrole1Labels: Annotations: PolicyRule: Resources Non-Resource URLs Resource Names Verbs --------- ----------------- -------------- ----- pods [] [] [get create] services [] [] [get create] deployments.apps [] [] [get create]
8.2.2 增加list權(quán)限在客戶(hù)端進(jìn)行測(cè)試,設(shè)置了clusterrole,clusterrolebinding之后,發(fā)現(xiàn)用戶(hù)test沒(méi)有對(duì)deploy的list權(quán)限。
[root@etcd1 ~]# kubectl get deploy -n safe --kubeconfig=kctest Error from server (Forbidden): deployments.apps is forbidden: User "test" cannot list resource "deployments" in API group "apps" in the namespace "safe"
修改yaml文件,增加list權(quán)限。
[root@k8scloude1 safe]# vim clusterrole1.yaml #添加list權(quán)限[root@k8scloude1 safe]# cat clusterrole1.yaml apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRolemetadata: creationTimestamp: null name: clusterrole1rules:- apiGroups: - "" resources: - pods - services verbs: - get - create - list- apiGroups: - apps resources: - deployments verbs: - get - create - list
應(yīng)用clusterrole。
[root@k8scloude1 safe]# kubectl apply -f clusterrole1.yaml clusterrole.rbac.authorization.k8s.io/clusterrole1 configured
查看clusterrole1的描述信息。
[root@k8scloude1 safe]# kubectl describe clusterrole clusterrole1 Name: clusterrole1Labels: Annotations: PolicyRule: Resources Non-Resource URLs Resource Names Verbs --------- ----------------- -------------- ----- pods [] [] [get create list] services [] [] [get create list] deployments.apps [] [] [get create list]
clusterrole1添加了list權(quán)限之后,客戶(hù)端可以get信息了。
[root@etcd1 ~]# kubectl get deploy -n safe --kubeconfig=kctest No resources found in safe namespace.[root@etcd1 ~]# kubectl get deploy -n default --kubeconfig=kctest No resources found in default namespace.
可以發(fā)現(xiàn),clusterrolebinding全局生效,在所有namespace里都生效。
[root@etcd1 ~]# kubectl get deploy -n kube-system --kubeconfig=kctest NAME READY UP-TO-DATE AVAILABLE AGEcalico-kube-controllers 1/1 1 1 70dcoredns 2/2 2 2 70dmetrics-server 1/1 1 1 69d
九.總結(jié)在本篇博客中,我們介紹了Kubernetes中的權(quán)限管理機(jī)制之RBAC鑒權(quán)。通過(guò)創(chuàng)建Role、RoleBinding、ClusterRole和ClusterRoleBinding等對(duì)象,管理員可以有效地控制用戶(hù)和服務(wù)賬戶(hù)的訪(fǎng)問(wèn)權(quán)限,保障集群的安全性。
除了RBAC、ABAC和Node鑒權(quán)外,Kubernetes還支持Webhook鑒權(quán)、Service Account Token Volume Projection等多種鑒權(quán)方式。同時(shí),在進(jìn)行權(quán)限管理時(shí),管理員還需注意以下事項(xiàng):
避免為用戶(hù)授予過(guò)多的權(quán)限。確保所有操作都可以被審計(jì)和跟蹤。定期審核訪(fǎng)問(wèn)權(quán)限,確保其符合組織政策和最佳實(shí)踐。標(biāo)簽: