kubectl認證配置流程
在 linux 系統中可能會包含很多使用者,且不同使用者有不同的許可權,若需要為不同的使用者設定不同的操作K8s的許可權,就需要用到 K8s 的 rbac 機制。下面以建立一個 user 使用者,為其設定在 default namespace 下的只讀許可權。
我們執行 kubectl 命令時會需要 kube-apiserver 的認證和授權,即利用使用者的證書和 rbac 機制,因此若對系統使用者進行許可權控制,首先需要為使用者建立證書。
證書建立
首先建立一個使用者組和普通使用者
groupadd usergroup
useradd user -g usergroup -m
複製程式碼
為使用者建立證書有兩種方式,可以使用 K8s 推薦的 cfssl,也可以用 openssl。
openssl 建立證書
我們預設 K8s 部署時所建立的認證相關的金鑰和證書都儲存在/etc/kubernetes/ssl/
中。
- 生成私鑰
openssl genrsa -out user.key 2048
複製程式碼
- 生成簽名
export CA_DNAME="/CN=user/OU=Sysem/O=group:view/L=Beijing/ST=Beijing/C=CN"
openssl req -new -key user.key -subj $CA_DNAME -out user.csr
複製程式碼
其中 CA_DNAME 顯示簽名的所有者,CN 為名字, 3. 生成證書
openssl x509 -req -CA /etc/kubernetes/ssl/ca.crt -CA /etc/kubernetes/ssl/ca.key -CAcreateserial -in user.csr -out user.crt -day 365
複製程式碼
cfssl 建立證書
配置 K8s 上下文
切換到 user 使用者後,配置訪問的叢集
kubectl config set-cluster <yourCluster> \
--certificate-authority=/etc/kubernetes/ssl/ca.crt \
--embed-certs=true \
--server=<your apiserver>
複製程式碼
其中 certificate-authority 使用的是 K8s 生成的證書
cluster name 可以通過
kubectl config get-clusters
獲取 apiserver 通過kubectl cluster-info
獲取
配置認證證書
kubectl config set-credentials user\
--client-certificate=user.crt \
--client-key=user.key \
--embed-cert=true
複製程式碼
注意,此處的 user 並非系統使用者名稱,而是 CA_DNAME 中的使用者名稱,即在K8s的 rbac 中認證的名字。OU為組,同樣關聯 K8s rbac 認證的組
配置上下文
kubectl config set-context contextName \
--cluster=<your clustername> \
--user=user # 此處user 仍是 CA_DNAME 中的使用者名稱
複製程式碼
這樣就配置好 user 使用者的 kubectl 訪問的上下文了。上下文資訊預設儲存在了 $HOME/.kube/config
中。
這幾步中其實可以看出 K8s 的認證與系統使用者名稱及其所在組毫無關係,K8s 只關心使用者通過 kubectl 訪問時所攜帶的證書,即 config 檔案中所包含的認證資訊。因此如果使用者有權指定 root 使用者下的 .kube/config
作為上下文配置,則可以擁有所有許可權。
K8s rbac 配置
K8s 中使用 RBAC 授權器為使用者授權,相關資源有 Role
ClusterRole
RoleBinding
ClusterRoleBinding
Role & ClusterRole
Role
和ClusterRole
用於描述角色許可權的,即配置角色對於資源的可操作許可權,Role
可只屬於某個namespace,ClusterRole
隸屬於全域性。
一個 Role
物件只能用於授予對某一單一名稱空間中資源的訪問許可權。 以下示例描述了”default”名稱空間中的一個Role物件的定義,用於授予對pod的讀訪問許可權:
kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
namespace: default
name: pod-reader
rules:
- apiGroups: [""] # 空字串""表明使用core API group
resources: ["pods"]
verbs: ["get", "watch", "list"]
複製程式碼
ClusterRole
物件可以授予與Role物件相同的許可權,但由於它們屬於叢集範圍物件, 也可以使用它們授予對以下幾種資源的訪問許可權:
- 叢集範圍資源(例如節點,即node)
- 非資源型別endpoint(例如”/healthz”)
- 跨所有名稱空間的名稱空間範圍資源(例如pod,需要執行命令kubectl get pods --all-namespaces來查詢叢集中所有的pod)
在本例中,若使用
ClusterRole
,則如下所示:
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: global-pod-reader
rules:
- apiGroups: [""] # 空字串""表明使用core API group
resources: ["pods"]
verbs: ["get", "list"]
複製程式碼
RoleBinding & ClusterRoleBinding
角色繫結將一個角色中定義的各種許可權授予一個或者一組使用者。 角色繫結包含了一組相關主體(即subject,包括使用者——User、使用者組——Group、或者服務賬戶——Service Account)以及對被授予角色的引用。 在名稱空間中可以通過RoleBinding
物件授予許可權,而叢集範圍的許可權授予則通過ClusterRoleBinding
物件完成。
RoleBinding
可以引用在同一名稱空間內定義的Role
物件。 下面我們定義RoleBinding
物件在”default”名稱空間中將”pod-reader”角色授予使用者”user”。 這一授權將允許使用者”user”從”default”名稱空間中讀取pod。
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: read-pods
namespace: default
subjects:
- kind: User
name: user
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
複製程式碼
若使用 ClusterRoleBinding
,則如下所示:
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: read-pod-global
namespace: default # 這裡表明的是許可權的作用域,而非所屬哪個namespace,若沒有這個欄位,則表明作用域為全域性。
subjects:
- kind: User # 此處也可以更換為 Group ,對應之前 CA_DNAME 中的 OU
name: user
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: global-pod-reader
apiGroup: rbac.authorization.k8s.io
複製程式碼
在K8s中,系統包含預設的使用者,如下
ClusterRole | ClusterRoleBinding | info |
---|---|---|
cluster-admin | system:masters group | 超級使用者許可權,允許對任何資源執行任何操作。 在ClusterRoleBinding中使用時,可以完全控制叢集和所有名稱空間中的所有資源。 在RoleBinding中使用時,可以完全控制RoleBinding所在名稱空間中的所有資源,包括名稱空間自己。 |
admin | None | 管理員許可權,利用RoleBinding在某一名稱空間內部授予。 在RoleBinding中使用時,允許針對名稱空間內大部分資源的讀寫訪問, 包括在名稱空間內建立角色與角色繫結的能力。 但不允許對資源配額(resource quota)或者名稱空間本身的寫訪問。 |
edit | None | 允許對某一個名稱空間內大部分物件的讀寫訪問,但不允許檢視或者修改角色或者角色繫結。 |
view | None | 允許對某一個名稱空間內大部分物件的只讀訪問。 不允許檢視角色或者角色繫結。 由於可擴散性等原因,不允許檢視secret資源。 |
參考自https://jimmysong.io/kubernetes-handbook/concepts/rbac.html
總結
至此我們已經實現了通過 rbac 對系統使用者的許可權控制,對於使用者的許可權,可以使用 kubectl auth can-i <verbs> <resource>
的命令進行驗證。
此處個人推薦一本 ebook,kubernetes handbook。