前言
在進行授權(Authorization) 之前,一定要先完成認證(Authentication) 的過程,而認證的說明可以參考上一篇文章。
k8s 對於 REST API request 的屬性要求是通用的,因此可以與企業中 or 公有雲平台中現存的管理控制系統進行整合。
而在 k8s 中,負責對 API request 進行授權的是 API server,藉由檢查所有的 request attribute 並查詢所有的 policy 來決定是否允許或拒絕 API request 的存取。
預設情況下所有權限都是預設關閉的
k8s 支援同時多個授權機制,並且為循序式的進行檢查,若有任何一個授權機制通過檢查,就會馬上允許存取,若是沒有通過任何的授權機制檢查,此 API request 就會被拒絕存取;而被拒絕存取的 API request 都會收到 HTTP 403 error。
名詞釋疑
NameSpace
用來進行資源的虛擬隔離之用,在 k8s 剛建立好的初期會有預設的 default
& kube-system
兩個 namespace
User Account & Service Account
User Account & Service Account 是用來區別作用的範圍,但會有以下的差別:
User Account 是用來辨識使用者,而 Service Account 則是用來辨識 k8s 中的各種服務
User Account 對應人的身份,因此是跨 namespace;而 Service Account 對應的是 service 的身份,因此是與 namespace 有相關
Request Attributes
上面有提到,API server 會檢查 API request attribute 來決定是否進行授權存取,在 k8s 有以下 API request attributes:
user, group, extra(額外的 key/value 資訊)
API、Request Path(/api, /healthz), API request verb(get, list, create, update, patch, watch … etc)
HTTP request verb(get, post, put, delete)
Resource, Subresource (存取 resource 時需要的資訊)
Namespace
API group (存取 resource 時需要的資訊)
Authorization Modules
目前 k8s 支援以下幾種 Authorization Modules:
此模組是為了授權在每一個 node 上的 kubelet 所發出的 API request 所設計出來的,讓 kubelet 的 API request 可進行特定的權限控制;例如對於以下的 resource 的讀取的權限:
另外透過 NodeRestriction 的 plugin,可以針對以下 resource 進行寫入:
node (status)
pod (status)
event
未來可能還會繼續透過 Node Authorization 來對於 kubelet 進行更細膩的權限控管
此種方式就是在 master node 上保留一份 policy 文件,指定不同的使用者對於 resource 的存取權限,不彈性也不容易擴充,修改了 policy 文件之後還需要重新啟動 master node。
RBAC 是目前 k8s 預設會啟動的 authorization module。
在 RBAC API 中定義了 resource target,用來描述使用者以及 resource 之間的權限關係:
Role:定義在特定 namespace 下的 resource 的存取權限
RoleBinding: 設定哪些使用者(or service account)與 role 綁定而擁有存取權限
ClusterRole:定義在整個 k8s cluster 下的 resource 的存取權限
ClusterRoleBinding:設定哪些使用者(or service account)與 role 綁定而擁有存取權限
接著以下以 role kubernetes-dashboard-minimal 做個簡單的示範:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| root@kube-master0:~ NAMESPACE NAME AGE default pod-reader 4d kube-public system:controller:bootstrap-signer 5d kube-system extension-apiserver-authentication-reader 5d kube-system kubernetes-dashboard-minimal 5d ..... (略)
root@kube-master0:~ NAMESPACE NAME AGE kube-public system:controller:bootstrap-signer 5d kube-system kubernetes-dashboard-minimal 5d ..... (略)
root@kube-master0:~ Name: kubernetes-dashboard-minimal Labels: <none> Annotations: kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"rbac.authorization.k8s.io/v1","kind":"Role","metadata":{"annotations":{},"name":"kubernetes-dashboard-minimal","namespace":"kube-system"... PolicyRule: Resources Non-Resource URLs Resource Names Verbs --------- ----------------- -------------- ----- configmaps [] [kubernetes-dashboard-settings] [get update] configmaps [] [] [create] secrets [] [kubernetes-dashboard-certs] [get update delete] secrets [] [kubernetes-dashboard-key-holder] [get update delete] secrets [] [] [create] services [] [heapster] [proxy] services/proxy [] [heapster] [get] services/proxy [] [http:heapster:] [get] services/proxy [] [https:heapster:] [get]
root@kube-master0:~ Name: kubernetes-dashboard-minimal Labels: <none> Annotations: kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"rbac.authorization.k8s.io/v1","kind":"RoleBinding","metadata":{"annotations":{},"name":"kubernetes-dashboard-minimal","namespace":"kube-... Role: Kind: Role Name: kubernetes-dashboard-minimal Subjects: Kind Name Namespace ---- ---- --------- ServiceAccount kubernetes-dashboard kube-system
|
接著以 clusterole system:controller:deployment-controller 做示範:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
|
root@kube-master0:~ NAME AGE admin 5d calico-node 5d cluster-admin 5d ..... (略) system:controller:deployment-controller 5d ..... (略)
root@kube-master0:~ Name: system:controller:deployment-controller Labels: kubernetes.io/bootstrapping=rbac-defaults Annotations: rbac.authorization.kubernetes.io/autoupdate=true PolicyRule: Resources Non-Resource URLs Resource Names Verbs --------- ----------------- -------------- ----- events [] [] [create patch update] pods [] [] [get list update watch] deployments.apps [] [] [get list update watch] deployments.apps/finalizers [] [] [update] deployments.apps/status [] [] [update] replicasets.apps [] [] [create delete get list patch update watch] deployments.extensions [] [] [get list update watch] deployments.extensions/finalizers [] [] [update] deployments.extensions/status [] [] [update] replicasets.extensions [] [] [create delete get list patch update watch]
root@kube-master0:~ NAME AGE ..... (略) system:controller:deployment-controller 5d ..... (略)
root@kube-master0:~ Name: system:controller:deployment-controller Labels: kubernetes.io/bootstrapping=rbac-defaults Annotations: rbac.authorization.kubernetes.io/autoupdate=true Role: Kind: ClusterRole Name: system:controller:deployment-controller Subjects: Kind Name Namespace ---- ---- --------- ServiceAccount deployment-controller kube-system
|
API server 已經預先建立了一系列的 ClusterRole & ClusteRoleBinding,名稱都以 system 開頭,並涵蓋了維持系統正常服務所需要的所有權限,因此整個 k8s cluster 都可以在 RBAC 的基礎下進行權限的管理與授權。
這也代表著隨意對 system 開頭的 ClusteRole 修改,可能會造成系統無法正常運作。
此模式是管理者在外部提供 HTTPS 授權服務,並設定 API server 透過與外部服務互動的方式進行授權。
檢查 API 存取權限
kubectl 提供了 auth can-i
命令,可用來查詢當前的使用者有沒有特定 resource 的存取權限:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
root@kube-master0:~ yes
root@kube-master0:~ yes
root@kube-master0:~ yes
|
References