01、前言
衆所周知,kubernetes API是kubernetes的核心組件,kubernetes API以REST接口的形式將Pods、Service、Deployment等信息定義爲資源,而這些資源我們又是怎樣操作它們的呢?在kubernetes 1.6之後社區逐漸使用RBAC的認證模式,下面將會詳細介紹這種認證模式。
02、kubernetes的認證機制
1)如何訪問kubernetes API
使用者可以通過kubectl客戶端、各個代碼語言的客戶端庫程序或者通過發送REST請求來訪問kubernetes API接口。
2)Kubernetes API概覽
Kubernetes API是標準的REST格式,kubernetes中所有資源的操作都是通過API操作完成的。爲了消除字段或者重構,kubernetes支持多個API版本,每個版本都有不同的路徑,如/api/v1 or /apis/extensions/v1beta1,而不同的資源在不同的API路徑中,比如ingress在v1bea1中而不是在v1中。不同的API版本也有不同的安全級別。如Alpha版本可能存在bug,同時默認情況下有些功能是禁止的,Bata版本是穩定的經過測試的,所以大家在調用kubernetes API時要注意使用的版本。
3)訪問kubernetes API的過程
如圖所示,首先訪問kubernetes API的主體大致分爲兩類:一類是User Account,以用戶的身份訪問API,另一類是Service Account,主要是kubernetes中的服務程序訪問APi接口,比如創建calico網絡插件、coredns等時會先創建對應的Service Account。Kubernetes API 爲了保證傳輸層安全端口運行在6443上,同時使用證書認證,在構建kubernetes集羣時,會將認證信息寫入到$USER/.kube/config中。
Authentication認證,在TLS第一次建立時,就會開始完成認證操作步驟。身份認證的模塊包括客戶端證書、密碼、Token令牌、JWT Tokens、Bootstrap Tokens等,如果請求認證不能通過,kubernetes會返回HTTP 401狀態碼。雖然kubernetes使用username作爲認證主體,但是不會寫入存儲中。
Authorization授權,當請求通過認證之後,會經過授權操作步驟。一次授權操作必須包括請求者的用戶名、請求的操作動作和受影響的對象,可以理解爲語文語法的主謂賓結構,請求主體、有哪種權限操作、操作對象又是什麼。Kubernetes支持多種授權模式,比如ABAC模式、RBAC模式、Webhook模式等。如果授權沒有通過,會返回HTTP 403狀態碼。
Admission control准入控制,准入控制作爲Authorization授權模式的補充操作,可以對請求對象實現創建、刪除、更新操作,通過准入控制可以更靈活的操作整個認證過程。在完成上述操作後,請求信息會寫入對象存儲中。值得注意的是,在傳統的3A認證中,最後一個爲Accounting記賬或審計,kubernetes面向的是雲原生不是一個雲計算廠商,不會實現記賬系統的模塊,但是可以通過准入控制來完成上述的功能。
03、kubernetes之RBAC模式
1)RBAC模式概述
RBAC的全稱是Role Base Access Control,既是基於角色的訪問控制,它是一種靈活的訪問控制機制,可以將用戶作爲角色,通過角色綁定完成資源的權限分配。由於kubernetes API本身不需要有任何改動,所以在權限控制和重新定義時無需重啓API server端。
RBAC使用rbac.authorization.k8s.io這個API Group,通過這個API Group可以允許用戶動態配置策略,在kubernetes 1.8之後RBAC模式的API版爲rbac.authorization.k8s.io/v1
在apiserver啓動時可以通過--authorization-mode=RBAC啓用RBAC模式
上圖爲RBAC模式的認證結構,在指定的namespace下,用戶主體通過角色綁定將API資源賦予相應的權限。
2)Role和ClusterRole角色和集羣角色
在RBAC的API中,Role包含一組權限的規則,它可以像Role作用於單個namespace,也可以像ClusterRole一樣作用於整個集羣中。
Role和ClusterRole示例對比如下:
Role會指定namespace,然後賦予pods資源類型相應的get、watch、list權限
ClusterRole不需要指定namespace,因爲它作用於整個namespace上。ClusterRole與Role的主要區別有:
-
可以針對集羣資源(如nodes)
-
可以作用於非資源類型endpoints(如/healthz)
-
可以作用於整個namespace上(如kubectl get pods --all-namespaces上的資源)
3)RoleBinding和ClusterRoleBinding綁定角色和集羣角色
RoleBinding或ClusterRoleBinding主要的作用是將主體(如user、serviceaccount等)與Role或ClusterRole進行綁定,這樣就可以使得user、group或serviceAccount主體具有指定角色的權限規則。
如圖所示,subjects爲作用的主體可以爲user或者serviceAccount,roleRef代表與Role或者ClusterRole進行綁定,這樣jane用戶就具有pod-reader對應的權限了。
需要注意的是,如果想通過更改當前Role或者ClusterRole中的規則來改變權限規則,這樣是錯誤的,可以通過刪除現有規則重新綁定的方法來實現。可以使用kubectl auth命令更新現有規則。
可以使用kubectl get role, rolebinding -n kube-system查看現有集羣role使用情況
4)Aggregated ClusterRoles聚會類ClusterRoles
在1.9版本之後,ClusterRoles可以使用aggregationRule規則,將具有相同標籤的規則作爲統一主體完成授權操作。
通過aggregationRule選項,將匹配matchLabels中包含monitoring標籤的規則。
可以通過這種標籤聚會的方式,將多個ClusterRole聚會成統一的規則策略。
04、RBAC模式下的實戰操作
1)創建用戶憑證
使用openssl創建用戶私鑰,如下所示:
#openssl genrsa -out liyinda.key 2048
爲用戶私鑰創建一個證書籤名請求文件,CN代表用戶名,O代表組
#openssl req -new -key liyinda.key -out liyinda.csr -subj "/CN=liyinda/O=liyinda"
通過簽名請求文件向kubernetes的CA生成證書文件crt,有效期爲365天
#openssl x509 -req -in liyinda.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -out liyinda.crt -days 365
查看當前目錄下是否生成證書文件
#liyinda.crt liyinda.csr liyinda.key
通過創建好的證書文件和私鑰文件生成kubernetes集羣憑證
#kubectl config set-credentials liyinda --client-certificate=liyinda.crt --client-key=liyinda.key
通過創建好的憑證爲kubernetes生成上下文context
#kubectl config set-context liyinda-context --cluster=kubernetes --namespace=kube-system --user=liyinda
查看kubernetes集羣憑證信息
#kubectl config view
使用創建好的用戶憑證使用kubectl命令查看默認namespace下的pods,可以發現該用戶沒有對應權限。
#kubectl get pods ——context=liyinda-context
2)創建Role角色
創建user之後,我們定義一個Role的yaml文件來定義權限規則,如下所示:
3)創建RoleBinding綁定角色
創建完Role規則後,就可以將user和Role規則進行綁定,如下所示:
#kubectl apply-f rolebinding.yaml
4)驗證權限
使用之前創建好的上下文來查看名稱爲kube-system的namespace上的pods,可以看到已經添加對應權限。
#kubectl get pods——context=liyinda-context ——namespace=kube-system