kubernetes認(rèn)證鑒權(quán)內(nèi)容淺析
概要
你有沒(méi)有想過(guò)在執(zhí)行 kubectl 命令的時(shí)候,kube-apiserver 是怎么認(rèn)證你的身份的?
身份認(rèn)證過(guò)后是怎么鑒別你是否有權(quán)限操作所訪問(wèn)的API資源的,如果想通過(guò) API 訪問(wèn) kube-apiserver 接口,如何通過(guò)認(rèn)證鑒權(quán)?
如果一個(gè)集群同時(shí)要給運(yùn)維、開(kāi)發(fā)、測(cè)試使用,而且各自的資源和操作互不影響應(yīng)該怎么給用戶配置權(quán)限?
如果這些問(wèn)題你都了然于胸,那么你可以跳過(guò)本文,否則本文將帶你學(xué)習(xí) kubernetes 中的認(rèn)證鑒權(quán)規(guī)則。
通過(guò)本文你將學(xué)習(xí)到以下知識(shí)點(diǎn):
- kubeconfig 文件的結(jié)構(gòu)
- RBAC 鑒權(quán)原理
- 通過(guò) API 訪問(wèn) kube-apiserver 如何進(jìn)行鑒權(quán)
kubeconfig文件的結(jié)構(gòu)
kubectl 作為操作 k8s 的一個(gè)客戶端工具,只要為 kubectl 提供連接 apiserver 的配置kubeconfig文件,kubectl 可以在任何地方操作該集群,當(dāng)然,若 kubeconfig 文件中配置多個(gè)集群,kubectl 也可以輕松地在多個(gè)集群之間切換。下面是kubeconfig文件結(jié)構(gòu):
apiVersion: v1 clusters: - cluster: certificate-authority-data: xxx server: https://127.0.0.1:6443 name: kubernetes contexts: - context: cluster: kubernetes user: kubernetes-admin name: kubernetes-admin@kubernetes users: - name: kubernetes-admin user: client-certificate-data: xxxxx client-key-data: xxxxx current-context: kubernetes-admin@kubernetes kind: Config preferences: {}
主要包括:clusters、contexts、users 三部分,這三個(gè)單詞都是復(fù)數(shù)形式的,暗示他們是數(shù)組結(jié)構(gòu),也就是可以配置多個(gè),這為多集群(kubectl連接到不同集群)和多用戶(同一個(gè)集群不同用戶)切換提供了便利。
clusters
certificate-authority-data 是集群的CA證書(shū),kubectl 使用該配置對(duì) kube-apiserver 返回的服務(wù)端證書(shū)做校驗(yàn),用于客戶端校驗(yàn)服務(wù)端的證書(shū)有效性。這里拓展下,當(dāng)你在瀏覽器輸入baidu.com時(shí),為了建立安全鏈接,baidu服務(wù)器會(huì)返回服務(wù)端證書(shū),因?yàn)榉祷氐姆?wù)端證書(shū)是權(quán)威機(jī)構(gòu)CA簽發(fā)的,本地瀏覽器或操作系統(tǒng)內(nèi)置了權(quán)威機(jī)構(gòu)的CA,所以可以在本地找到CA對(duì)返回的服務(wù)端做合法性驗(yàn)證,但是一般我們部署的k8s集群使用的都是自簽發(fā)的證書(shū),在本地是找不到對(duì)應(yīng)的CA證書(shū)對(duì)kube-apiserver返回的證書(shū),所以需要配置集群的CA。server 表示集群的地址;name 表示集群的名字,該名字在后面的contexts會(huì)被用來(lái)關(guān)聯(lián)集群信息。
contexts
kubectl 運(yùn)行時(shí)候的上下文信息,cluster(就是上面 clusters 中cluster的名字)和 user 分別表示在當(dāng)前上下文下使用的是哪個(gè)用戶連接到哪個(gè)集群;name 表示上下文的名字,如果需要切換上下文,可以使用 kubectl config use-context {context name} 進(jìn)行切換,切換后kubectl就會(huì)使用該上下文中定義的用戶去訪問(wèn)對(duì)應(yīng)的集群。
users
client-certificate-data 用于 kubectl 和 kube-apiserver 進(jìn)行雙向認(rèn)證加密的客戶端證書(shū),當(dāng) kubectl 和 kube-apiserver 進(jìn)行https連接時(shí),kubectl會(huì)把該證書(shū)發(fā)送給 kube-apiserver ,后續(xù) kubectl 使用私鑰 client-key-data 加密數(shù)據(jù)發(fā)送給 kube-apiserver時(shí),kube-apiserver收到數(shù)據(jù)后使用 client-certificate-data 進(jìn)行解密獲得明文數(shù)據(jù)。
實(shí)際上,在k8s中沒(méi)有User(用戶)概念的,或者說(shuō)沒(méi)有User這樣的資源對(duì)象,kubeconfig文件的中User實(shí)際上是管理員給用戶簽發(fā)證書(shū)(users字段中的client-certificate-data)的時(shí)候使用的csr文件中指定的CN,如:
{ "CN": "david", "hosts": ["david.com"], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "ST": "Beijing", "L": "Beijing", "O": "k8s", "OU": "System" } ] }
kubectl在和kube-apiserver建立https連接后,kube-apiserver會(huì)取CN字段作為User(k8s本身不維護(hù)User信息),進(jìn)而進(jìn)行后續(xù)的鑒權(quán)工作。具體如何為用戶簽發(fā)證書(shū),可以參考該文章,本文不作發(fā)散。
給用戶簽發(fā)完證書(shū)后,管理員就獲得了該用戶的證書(shū)(client-certificate-data)和私鑰(client-key-data),然后就可以給該用戶生成kubeconfig文件了,kubectl提供了kubectl config命令就行添加,如下:
# 添加集群信息 kubectl config set-cluster {cluster_name} \ --certificate-authority=ca.crt \ --embed-certs=true \ --server=https://172.11.11.13:6443 \ --kubeconfig=config
# 添加用戶信息 kubectl config set-credentials {username} \ --client-certificate=username.crt \ --client-key=username.key \ --embed-certs=true \ --kubeconfig=config
# 添加上下文信息 kubectl config set-context {context_name}\ --cluster={cluster_name} \ --user={username} \ --kubeconfig=config
serviceAccount
上面說(shuō)了kubeconfig文件是給用戶在操作kubectl的時(shí)候認(rèn)證使用的,但是如果進(jìn)程(如集群內(nèi)的容器)想訪問(wèn)集群資源的話,用這種方式不太方便了,所以 serviceAccount 的概念應(yīng)運(yùn)而生,見(jiàn)名思意,服務(wù)賬號(hào)它存在的初衷就是給服務(wù)使用而不是給人用的。
當(dāng)在集群中創(chuàng)建一個(gè) serviceAccount 后,集群會(huì)自動(dòng)在對(duì)應(yīng)的namespace下生成一個(gè)secret,內(nèi)容形式如下:
apiVersion: v1 data: ca.crt: xxx namespace: xxxxx token: xxxxxx kind: Secret metadata: xxxx type: kubernetes.io/service-account-token
- ca.crt:簽發(fā)kube-apiserver證書(shū)的ca證書(shū),客戶端使用該ca去校驗(yàn)kube-apiserver證書(shū)。
- token:該token實(shí)際為一個(gè)jwt,可以使用 jwt.io/ 查看實(shí)際的內(nèi)容,token中 service-account.name 指定了用戶的實(shí)際身份,為認(rèn)證和鑒權(quán)提供了信息。
- namespace:serviceAccount所屬的namespace。
每一個(gè)namespace下面,集群都會(huì)創(chuàng)建一個(gè)默認(rèn)的serviceAccount和對(duì)應(yīng)的secret,不過(guò)該secret沒(méi)有操作集群資源的權(quán)限。
如果想要在Pod內(nèi)使用自己創(chuàng)建的sa的secret,可以在deploy中指定sa即可,如:
apiVersion: v1 kind: Deploy metadata: (...) spec: containers: - image: nginx (...) serviceAccountName: {name}
這樣創(chuàng)建出來(lái)的Pod,Pod內(nèi)的容器目錄/var/run/secrets/kubernetes.io/serviceaccount/下便會(huì)出現(xiàn)三個(gè)文件:
$ ls -al /var/run/secrets/kubernetes.io/serviceaccount/ total 4 drwxrwxrwt 3 root root 140 May 10 2022 . drwxr-xr-x 3 root root 4096 May 10 2022 .. lrwxrwxrwx 1 root root 13 May 10 2022 ca.crt -> ..data/ca.crt lrwxrwxrwx 1 root root 16 May 10 2022 namespace -> ..data/namespace lrwxrwxrwx 1 root root 12 May 10 2022 token -> ..data/token
如果想要驗(yàn)證創(chuàng)建的sa對(duì)應(yīng)的secret有沒(méi)有權(quán)限訪問(wèn)集群的資源,可以使用如下命令:
# CACERT也可以不使用,代替的是在curl命令中加上-k選項(xiàng) CACERT="xxx" TOKEN="xxx" namespace="xxx" APISERVER="xxxx" curl --cacert ${CACERT} --header "Authorization: Bearer ${TOKEN}" -X GET ${APISERVER}/api/v1/namespaces/${namespace}/pods
但是,有了sa后只能讓kube-apiserver知道你是誰(shuí),并不知道你有沒(méi)有權(quán)限去操作某些資源,簡(jiǎn)而言之,目前完成的是認(rèn)證步驟。就好比,進(jìn)小區(qū)需要刷門禁卡,如果你是這個(gè)小區(qū)的人,那么你就可以進(jìn)入該小區(qū),但是進(jìn)入小區(qū)后想要進(jìn)入對(duì)應(yīng)的房間,還需要進(jìn)一步識(shí)別你的身份,如鑰匙、指紋、人臉識(shí)別等手段。所以,kube-apiserver還需要對(duì)請(qǐng)求做進(jìn)一步的鑒權(quán),才能確定是否放行。那么kubernetes是使用什么方式鑒權(quán)的呢?答案就是:RBAC。
RBAC
RBAC(Role-Based Access Control),基于角色的訪問(wèn)控制。角色可以由命名空間(namespace)內(nèi)的 Role 對(duì)象定義,而整個(gè) Kubernetes 集群范圍內(nèi)有效的角色則通過(guò) ClusterRole 對(duì)象實(shí)現(xiàn)。
Role
Role在k8s里面也是一種資源,表示能對(duì)某個(gè)命名空間的什么資源做什么操作。一個(gè) Role 對(duì)象只能用于授予對(duì)某一單一命名空間中資源的訪問(wèn)權(quán)限。以下示例描述了 default 命名空間中的一個(gè) Role 對(duì)象的定義,用于授予對(duì) pod 的讀訪問(wèn)權(quán)限:
kind: Role apiVersion: rbac.authorization.k8s.io/v1beta1 metadata: namespace: default name: namespace-pod-get rules: - apiGroups: [""] resources: ["pods"] verbs: ["get", "watch", "list"]
ClusterRole
ClusterRole 對(duì)象可以授予與 Role 對(duì)象相同的權(quán)限,但由于它們屬于集群范圍對(duì)象, 也可以使用它們授予對(duì)以下幾種資源的訪問(wèn)權(quán)限:
- 集群范圍資源(例如節(jié)點(diǎn),即 node)
- 非資源類型 endpoint(例如”/healthz”)
- 跨所有命名空間的命名空間范圍資源(例如 pod,需要運(yùn)行命令 kubectl get pods --all-namespaces 來(lái)查詢集群中所有的 pod)
kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1beta1 metadata: # 由于 ClusterRole 是集群范圍對(duì)象,所以這里不需要定義 "namespace" 字段 name: cluster-pod-get rules: - apiGroups: [""] resources: ["pods"] verbs: ["get", "watch", "list"]
Role和ClusterRole都表示能對(duì)什么資源做什么操作,也就是權(quán)限范圍。但是缺少一個(gè)主體,即誰(shuí)有這個(gè)權(quán)限。單獨(dú)的Role和ClusterRole存在是沒(méi)有意義的,必須有一個(gè)主體去跟它做綁定才能發(fā)揮作用。于是和Role和ClusterRole對(duì)應(yīng)的就有RoleBinding和ClusterRoleBinding。
kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1beta1 metadata: name: fetch-pods namespace: default subjects: - kind: User name: test apiGroup: rbac.authorization.k8s.io roleRef: kind: Role name: namespace-pod-get apiGroup: rbac.authorization.k8s.io
- subjects: 主體,表示誰(shuí)要和Role綁定。這里的Kind可以有三個(gè)選擇,User、ServiceAccount或Group,其中最常用的是前面兩種。
- ServiceAccount: 有沒(méi)有發(fā)現(xiàn),這里和前面講的ServiceAccount產(chǎn)生關(guān)聯(lián)了,前面我們說(shuō)ServiceAccount只能說(shuō)明你是誰(shuí),并沒(méi)有說(shuō)明你有什么權(quán)限,這里我們做了角色綁定后,那么ServiceAccount的權(quán)限也就有了。
- User: 就是上文提到過(guò)的證書(shū)請(qǐng)求文件csr中的CN字段指定的值,做了綁定后,也就是User具有相關(guān)權(quán)限了。
- Group: 可以是上文提到過(guò)的證書(shū)請(qǐng)求文件csr中的O字段指定的值或者name為system:開(kāi)頭指定的一些系統(tǒng)保留組,具體可以看官方文檔具體有哪些組可以使用。
- roleRef: 角色引用,表示上述的主體和什么角色做綁定,如果是RoleBinding那么此處的角色Kind就是Role,而ClusterRoleBinding則此處的角色Kind就是ClusterRole;name 表示跟哪個(gè)Role綁定。
通過(guò)角色綁定后,服務(wù)賬號(hào)或者是用戶,都具有了Role中指定的集群資源操作權(quán)限。
以上就是kubernetes認(rèn)證鑒權(quán)內(nèi)容淺析的詳細(xì)內(nèi)容,更多關(guān)于kubernetes認(rèn)證鑒權(quán)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
k8s入門實(shí)戰(zhàn)deployment使用詳解
這篇文章主要為大家介紹了k8s入門實(shí)戰(zhàn)deployment使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03RFO SIG之openEuler AWS AMI 制作詳解
這篇文章主要為大家介紹了RFO SIG之openEuler AWS AMI 制作詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10再分享6個(gè)可無(wú)限激活阿里云盤(pán)邀請(qǐng)碼,不信你不能激活阿里云盤(pán)
這篇文章主要分享6個(gè)可無(wú)限激活的阿里云盤(pán)邀請(qǐng)碼,不信你不能激活阿里云盤(pán),需要的朋友可以參考下2020-11-11在AWS-EC2中安裝Minikube集群的詳細(xì)過(guò)程
這篇文章主要介紹了在AWS-EC2中安裝Minikube集群,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-06-06某集團(tuán)任意文件下載到虛擬主機(jī)getshell的方法
這篇文章主要介紹了某集團(tuán)任意文件下載到虛擬主機(jī)getshell的方法,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2017-01-01CentOS 7.9 升級(jí)內(nèi)核 kernel-ml-5.6.14版本的方法
這篇文章主要介紹了CentOS 7.9 升級(jí)內(nèi)核 kernel-ml-5.6.14版本,默認(rèn)內(nèi)核版本為3.10.0,現(xiàn)升級(jí)到 5.6.14 版本,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-10-10Hadoop 2.x與3.x 22點(diǎn)比較,Hadoop 3.x比2.x的改進(jìn)
本文介紹了Hadoop3版本中添加的新功能,Hadoop 2和Hadoop 3的區(qū)別,在這篇文章中,我們將討論Hadoop 2.x與Hadoop 3.x之間的比較。感興趣的朋友跟隨小編一起看一下2018-09-09