作者:陳亦帥,中國(guó)移動(dòng)云能力中心軟件研發(fā)工程師,專(zhuān)注于云原生、微服務(wù)、算力網(wǎng)絡(luò)等
前言
本文介紹K8s中的鑒權(quán)模塊。對(duì)其4種鑒權(quán)模式都進(jìn)行了概述講解。結(jié)合例子著重對(duì)大家日常中使用最多的RBAC鑒權(quán)模式進(jìn)行了說(shuō)明。
鑒權(quán)概述
《搞懂K8s認(rèn)證》中,我們提到不論是通過(guò)kubectl客戶端還是REST請(qǐng)求訪問(wèn)K8s集群,最終都需要經(jīng)過(guò)API Server來(lái)進(jìn)行資源的操作并通過(guò)Etcd。整個(gè)過(guò)程如下圖1所示,可以分成4個(gè)階段:

請(qǐng)求發(fā)起方進(jìn)行K8s API請(qǐng)求,經(jīng)過(guò)Authentication
(認(rèn)證)、Authorization
(鑒權(quán))、AdmissionControl
(準(zhǔn)入控制)三個(gè)階段的校驗(yàn),最后把請(qǐng)求轉(zhuǎn)化為對(duì)K8s對(duì)象的變更操作持久化至etcd
中。
其中認(rèn)證主要解決的是請(qǐng)求來(lái)源能否訪問(wèn)的問(wèn)題。即通過(guò)了認(rèn)證,那么可以認(rèn)為它是一個(gè)合法的請(qǐng)求對(duì)象。那么如何去決定請(qǐng)求對(duì)象能訪問(wèn)哪些資源以及對(duì)這些資源能進(jìn)行哪些操作,便是鑒權(quán)所要完成的事情了。
鑒權(quán)的最終目的,是區(qū)分請(qǐng)求對(duì)象,限定操作的影響范圍,讓其使用最小的權(quán)限完成自己所要進(jìn)行操作,從而進(jìn)一步保證安全。權(quán)限控制的劃分方式有許多種,K8s中提供了4種鑒權(quán)模式,分別為Node、ABAC、RBAC和Webhook。
默認(rèn)情況下,我們可以從/etc/kubernates/manifests/kube-apiserver.yaml
文件中查看apiserver
啟動(dòng)時(shí)認(rèn)證模式,片段如圖2所示:

其中可以使用的參數(shù)如表1所示:
參數(shù)配置 | 含義 | 一般的使用場(chǎng)景 |
---|---|---|
--authorization-mode=ABAC | 使用基于屬性的訪問(wèn)控制(ABAC) | 根據(jù)用戶的用戶名或者組名來(lái)控制其對(duì)集群資源的訪問(wèn)權(quán)限,適用于較小的組織或開(kāi)發(fā)團(tuán)隊(duì) |
--authorization-mode=RBAC | 使用基于角色的訪問(wèn)控制(RBAC) | 自定義ServiceAccount,綁定資源根據(jù)角色來(lái)控制資源的訪問(wèn)權(quán)限,適用于較大型的組織或者開(kāi)發(fā)運(yùn)維團(tuán)隊(duì) |
--authorization-mode=Webhook | 使用HTTP回調(diào)模式,允許你使用遠(yuǎn)程REST端點(diǎn)管理鑒權(quán) | 將鑒權(quán)角色交給外部服務(wù)進(jìn)行處理,根據(jù)自身需求,定制和擴(kuò)展鑒權(quán)策略,如自定義Webhook鑒權(quán)模塊對(duì)跨云平臺(tái)的應(yīng)用進(jìn)行集中的的訪問(wèn)控制 |
--authorization-mode=Node | 針對(duì)kubelet發(fā)出的API請(qǐng)求執(zhí)行鑒權(quán) | 驗(yàn)證節(jié)點(diǎn)身份,確保只有經(jīng)過(guò)身份驗(yàn)證且具有所需權(quán)限的Node才能連接到K8s集群 |
--authorization-mode=AlwaysDeny | 阻止所有請(qǐng)求 | 一般僅用作測(cè)試 |
--authorization-mode=AlwaysAllow | 允許所有請(qǐng)求 | 不需要API請(qǐng)求進(jìn)行鑒權(quán)的場(chǎng)景 |
如圖2所示,可以同時(shí)配置多個(gè)鑒權(quán)模塊(多個(gè)模塊之間使用逗號(hào)分隔),排在靠前的模塊優(yōu)先執(zhí)行,任何模式允許或拒接請(qǐng)求,則立即返回該決定,并不會(huì)與其他鑒權(quán)模塊協(xié)商。
Node鑒權(quán)
Node鑒權(quán)是一種特殊用途的鑒權(quán)模式,旨在對(duì)kubelet
發(fā)出API請(qǐng)求進(jìn)行授權(quán)。Node鑒權(quán)允許kubelet
執(zhí)行API的操作分成讀和寫(xiě)兩部分。讀取操作控制范圍為:services、endpoints、nodes、pods
以及綁定到kubelet節(jié)點(diǎn) Pod
相關(guān)的secret、configmap、pvc
和持久卷。寫(xiě)入操作的范圍主要是節(jié)點(diǎn)和節(jié)點(diǎn)狀態(tài)、Pod和Pod狀態(tài)以及事件,若要限制kubelet
只能修改自己的節(jié)點(diǎn),則還需要在Apiserver
啟動(dòng)時(shí),開(kāi)啟NodeRestriction
準(zhǔn)入插件(見(jiàn)圖2第二個(gè)紅框)。
開(kāi)啟Node鑒權(quán)模塊后,kubellet
為了獲取授權(quán),必須使用一個(gè)特定規(guī)則的憑據(jù),如圖3所示:

從圖中我們看到,kubelet
使用了一個(gè)證書(shū)憑據(jù),其中O=system:nodes
表示其所在組,CN=system:node:paas-cnp-k8s-kce-01
表示其用戶名,滿足了Node鑒權(quán)模塊要求的組名必須為system:nodes
,用戶名必須為system:node:<nodeName>
的要求。其中<nodeName>
默認(rèn)由hostname
或kubelet --hostname-override
選項(xiàng)提供指定,其必須與kubelet
提供的主機(jī)名稱(chēng)精確匹配。
system:nodes
是K8s的內(nèi)置用戶組,我們可以通過(guò)其默認(rèn)的ClusterRoleBinding
,如圖4所示:

我們可以發(fā)現(xiàn),它指示指向了system:node
這個(gè)ClusterRole
,并沒(méi)有subjects的內(nèi)容,即其沒(méi)有綁定system:node:paas-cnp-k8s-kce-01
用戶也沒(méi)有綁定system:nodes
組。其正是因?yàn)镵8s基于 Node鑒權(quán)模塊來(lái)限制kubelet只能讀取和修改本節(jié)點(diǎn)上的資源,并不是使用 RBAC來(lái)鑒權(quán)(涉及到部分RBAC的內(nèi)容,下文會(huì)進(jìn)行詳解)。
ABAC鑒權(quán)
基于屬性的訪問(wèn)控制,K8s中可以表述將訪問(wèn)策略授予用戶或者組。與RBAC不同的點(diǎn)在于,其策略是由任何類(lèi)型的屬性(用戶屬性、資源屬性、對(duì)象、環(huán)境等)進(jìn)行描述。
啟用ABAC模式,類(lèi)似于圖2需要在apiserver
啟動(dòng)時(shí)指定--authorization-mode=ABAC
以及--authorization-policy-file=<策略文件路徑>?
。圖5是K8s官網(wǎng)給出的一個(gè)策略樣例文件:

文件中每行都是一個(gè)JSON對(duì)象,其中版本控制屬性"apiVersion"
: "abac.authorization.kubernetes.io/v1beta1"
和"kind": "Policy"
可以理解成固定寫(xiě)法,是被K8s本身所使用,便于以后進(jìn)行版本控制和轉(zhuǎn)換。spec部分,其中user,來(lái)自于--token-auth-file
的用戶字符串,其指定的user名稱(chēng)必須與這個(gè)文件中的字符串相匹配;group,必須與經(jīng)過(guò)身份驗(yàn)證的用戶的一個(gè)組匹配,?system:authenticated
?匹配所有經(jīng)過(guò)身份驗(yàn)證的請(qǐng)求。?system:unauthenticated
?匹配所有未經(jīng)過(guò)身份驗(yàn)證的請(qǐng)求。其他的匹配屬性,主要描述被訪問(wèn)的訪問(wèn),分為資源屬性和非資源屬性(其具體定義可參見(jiàn)官網(wǎng))。readonly
,主要限制是否只允許對(duì)資源進(jìn)行?get、list
和 watch
操作,非資源屬性只進(jìn)行get
操作。
例如:
{"apiVersion":?"abac.authorization.kubernetes.io/v1beta1",?"kind":?"Policy",?"spec":?{"user":?"alice",?"namespace":?"*",?"resource":?"*",?"apiGroup":?"*"}}
表示用戶alice可以對(duì)所有namespace下的所有資源進(jìn)行任何操作;
{"apiVersion":?"abac.authorization.kubernetes.io/v1beta1",?"kind":?"Policy",?"spec":?{"user":?"bob",?"namespace":?"projectCaribou",?"resource":?"pods",?"readonly":?true}}
表示用戶bob只能對(duì)namespace為projectCaribou
的Pod進(jìn)行l(wèi)ist、get和watch操作。
對(duì)于ServiceAccount
的ABAC管控。Service Account
會(huì)自動(dòng)生成一個(gè)ABAC用戶名,其格式為:system:serviceaccount:<namespace>:<serviceaccountname>
,創(chuàng)建新的命名空間時(shí),K8s會(huì)為我們?cè)诋?dāng)前namespace
下創(chuàng)建一個(gè)名為default
的ServiceAccount
,如果現(xiàn)在假定我們需要namespace為test名為default的ServiceAccount
具有該namespace下的全部權(quán)限,則可以添加這樣一條規(guī)則:
{"apiVersion":"abac.authorization.kubernetes.io/v1beta1","kind":"Policy","spec":{"user":"system:serviceaccount:test:default","namespace":"test","resource":"*","apiGroup":"*"}}
我們發(fā)現(xiàn),ABAC雖然對(duì)用戶訪問(wèn)進(jìn)行了一定的劃分,但是如果添加了新的ABAC策略,則需要重啟API Server以使其生效,資源的訪問(wèn)權(quán)限細(xì)粒度也只控制到了是否只讀,當(dāng)用戶規(guī)模增大時(shí),這是遠(yuǎn)遠(yuǎn)不能滿足需求的。對(duì)于較大組織的團(tuán)隊(duì)進(jìn)行更加細(xì)粒度的管控,就需要使用到K8s的RBAC鑒權(quán)模塊了。
RBAC鑒權(quán)
啟用RBAC鑒權(quán),可以如圖2所示,在--authorization-mode的啟動(dòng)參數(shù)中包含RBAC即可。相對(duì)于其他訪問(wèn)控制方式,RBAC具有如下優(yōu)勢(shì):
-
對(duì)集群中的資源和非資源權(quán)限均有完整的覆蓋。 -
RBAC由幾個(gè)API對(duì)象完成。同其他API對(duì)象一樣,可以用kubectl或API進(jìn)行操作和調(diào)整,不必重新啟動(dòng)ApiServer。
K8s的RBAC主要闡述解決了主體(subject)是什么角色的問(wèn)題。其中主體就是K8s中的用戶,包含了常規(guī)用戶(User、Group,平時(shí)常用的kubectl命令都是普通用戶執(zhí)行的)和服務(wù)賬戶(ServiceAccount,主要用于集群進(jìn)程與K8s的API通信)。角色決定了能夠?qū)Y源進(jìn)行什么樣的操作,RBAC中我們可以定義namespace級(jí)別的Role也可以定義集群級(jí)別的ClusterRole。最后K8s再通過(guò)RoleBinding和ClusterRoleBinding把用戶和角色的關(guān)系進(jìn)行關(guān)聯(lián)綁定,其中RoleBinding既可以綁定Role也可以綁定ClusterRole,ClusterRole指定綁定ClusterRole,最終實(shí)現(xiàn)了不同用戶對(duì)不同資源進(jìn)行特定操作的控制。Role針對(duì)特定的命名空間,ClusterRole在整個(gè)集群范圍內(nèi)都生效,所以后者訪問(wèn)范圍也更大,能夠限制訪問(wèn)Node等資源。其關(guān)系圖如圖6所示:

現(xiàn)在假設(shè)你所在部門(mén)使用名為rbac-team的命名空間工作,現(xiàn)在要為部署流水線創(chuàng)建一個(gè)新的ClusterRole名為deployment-clusterrole,且僅允許創(chuàng)建Deployment、StatefulSet、DaemonSet三種資源,同時(shí)在rbac-team這個(gè)命名空間下創(chuàng)建一個(gè)新的ServiceAccount名為cicd-test使用這個(gè)ClusterRole。K8s中我們可以使用kubectl客戶端或者API資源的方式來(lái)實(shí)現(xiàn)這個(gè)RBAC的功能。
Kubectl客戶端方式。
-
第一步,我們可以先執(zhí)行命令: kubectl create clusterrole deployment-clusterrole --verb=create --resource=deployments,statefulsets,daemonsets
創(chuàng)建所需的ClusterRole
,其中--verb
代表可以執(zhí)行的操作,--reasource
代表授權(quán)操作的資源范圍; -
第二步,執(zhí)行命令: kubectl -n rbac-team create serviceaccount cicd-test
創(chuàng)建要求的ServiceAccount
; -
第三步,限于rbac-test中綁定所需權(quán)限,執(zhí)行命令: kubectl -n rbac-team create rolebinding cicd-rolebinding --clusterrole=deployment-clusterrole --serviceaccount=rbac-team:cicd-test
,對(duì)新創(chuàng)建的ServiceAccount
與我們的ClusterRole
進(jìn)行綁定。
Api資源的方式。
-
第一步,準(zhǔn)備ClusterRole的資源描述,創(chuàng)建名為cr-deployment.yaml的文件,如圖7所示:

其中verbs用于限定可執(zhí)行的操作,可配置參數(shù)有:“get”, “l(fā)ist”, “watch”, “create”, “update”, “patch”, “delete”, “exec”。resources
用于限定可訪問(wèn)的資源范圍,可配置參數(shù)有:“services”, “endpoints”, “pods”,“secrets”,“configmaps”,“crontabs”,“deployments”,“jobs”,“nodes”,“rolebindings”,“clusterroles”,“daemonsets”,“replicasets”,“statefulsets”,“horizontalpodautoscalers”,“replicationcontrollers”,“cronjobs”
。apiGroups
用于劃分訪問(wèn)的資源組,可配置參數(shù)有:“”,“apps”, “autoscaling”, “batch”
。
-
第二步,準(zhǔn)備 ServiceAccount
的資源描述,創(chuàng)建名為sa-cicd.yaml
的文件,如圖8所示:

-
第三步,準(zhǔn)備RoleBinding的資源描述,創(chuàng)建名為rb-cicd.yaml的文件,如圖9所示:

將前面兩步的clusterrole
和ServiceAccount
進(jìn)行綁定,其中subjects指明了被授權(quán)的主體,當(dāng)被授權(quán)對(duì)象是User或者Group時(shí),可以使用類(lèi)似如下片段subjects即可(Group的話只需要將kind的值改為Group):
-?kind:?User
???name:?"test-user"
???apiGroup:?rbac.authorization.k8s.io
-
第四步,使用kubectl -f 分別應(yīng)用上述資源,完成主體(subject)、角色的創(chuàng)建與綁定。
當(dāng)K8s的進(jìn)程資源需要使用上述身份憑證進(jìn)行權(quán)限劃分時(shí),只需要在資源聲明文件中進(jìn)行配置即可,如圖9所示:

為特定應(yīng)用的Service Account
賦權(quán)進(jìn)行權(quán)限管控也是最安全的最值得推薦的。
APIServer
默認(rèn)的ClusterRole
和ClusterRoleBinding
對(duì)象,其中很多是以"system:"為前綴的,對(duì)這些對(duì)象的改動(dòng)可能造成集群故障。例如Node鑒權(quán)模塊提到的system:node
,這個(gè)ClusterRole
為kubelet定義了權(quán)限,如果這個(gè)集群角色被改動(dòng)了,kubelet就會(huì)停止工作。
所有默認(rèn)的ClusterRole
和RoleBinding
都會(huì)用標(biāo)簽kubernetes.io/bootstrapping: rbac-defaults
進(jìn)行標(biāo)記。
Webhook鑒權(quán)
啟用Webhook模式的方式與ABAC模式相似,我們需要在apiserver啟動(dòng)時(shí)指定--authorization-mode=ABAC
以及一個(gè)HTTP配置文件用以指定策略嗎,可以通過(guò)參數(shù)--authorization-webhook-config-file=<策略文件路徑>
,策略文件配置使用的是kubeconfig文件的格式。users部分表示APIServer的webhook,cluster代表著遠(yuǎn)程服務(wù)。 圖11部分是K8s官網(wǎng)給出的一個(gè)示例。

當(dāng)進(jìn)行認(rèn)證時(shí),API服務(wù)器會(huì)生成一個(gè)JSON對(duì)象來(lái)描述這個(gè)動(dòng)作,對(duì)于一個(gè)資源類(lèi)型的請(qǐng)求,其內(nèi)容主要包含了需要被訪問(wèn)的資源或請(qǐng)求特征,如圖12所示:

從圖12中我們可以看到,這個(gè)請(qǐng)求是User名為jane,Group為group1、gourp2為主體,請(qǐng)求的資源為命名空間為kittensandpoines
下的pods資源,資源所屬group
為unicorn.example.org
,請(qǐng)求的執(zhí)行操作為get這個(gè)資源信息。若我們的Webhook服務(wù)URL同意了這個(gè)請(qǐng)求,則可以返回如圖13格式的響應(yīng)體。

從圖13中我們可以看出,我們只需要填充SubjectAccessReview的status對(duì)象信息的值即可。若要拒絕請(qǐng)求,則可以返回圖14或圖15的響應(yīng)。


圖14和圖15都是對(duì)請(qǐng)求進(jìn)行拒絕,都給出了拒絕通過(guò)的原因,差別在于圖14的拒絕響應(yīng)中增加了denied:true
的信息,其表示當(dāng)我們配置多了多個(gè)鑒權(quán)模塊的時(shí)候,當(dāng)這個(gè)響應(yīng)返回時(shí)立即拒絕請(qǐng)求。(默認(rèn)當(dāng)存在多個(gè)鑒權(quán)模塊,Webhook拒絕后可以再通過(guò)其他模塊進(jìn)行鑒權(quán),只有當(dāng)其他模塊也不通過(guò)或者不存在時(shí),才禁止訪問(wèn))
對(duì)于非資源的路徑訪問(wèn),生成的JSON請(qǐng)求示例如圖16所示:

總結(jié)
鑒權(quán)主要是解決“誰(shuí)可以對(duì)什么資源進(jìn)行哪些操作”的問(wèn)題。K8s的鑒權(quán)模塊主要有4個(gè),發(fā)生在鑒權(quán)認(rèn)證階段的第二階段。Node模塊主要針對(duì)kubelet需要訪問(wèn)APIServer
的場(chǎng)景; ABAC
主要針對(duì)User
和Group
的常規(guī)用戶,控制力度較粗;RBAC即可以用于常規(guī)用戶也可以針對(duì)ServiceAccount
進(jìn)行管控,且管控力度十分細(xì)膩,是常用的K8s鑒權(quán)方式;Webhook
主要用于定制自定義的鑒權(quán)邏輯,可用于跨云的集中式鑒權(quán)。
參考文獻(xiàn):
https://kubernetes.io/zh-cn/docs/reference/access-authn-authz/node/
https://kubernetes.io/zh-cn/docs/reference/access-authn-authz/abac/
https://kubernetes.io/zh-cn/docs/reference/access-authn-authz/rbac/
https://kubernetes.io/zh-cn/docs/reference/access-authn-authz/webhook/ https://www.cnblogs.com/maiblogs/p/16271997.html
https://cloud.tencent.com/developer/article/2149852文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-833516.html
本文由 mdnice 多平臺(tái)發(fā)布文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-833516.html
到了這里,關(guān)于搞懂K8s的鑒權(quán)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!