DevOps CICD K8s DockerCreate a new user called john. Grant him access to the cluster. John should have permission to create, list, get, update and delete pods in the development namespace.
這題是有關 RBAC (Role-Based Access Control) 的問題,但是要了解 RBAC,需要先了解一下K8s中的API Groups。首先,一般我們會透過curl https://127.0.0.1:6443/version查看Node的API version(port 6443是default設定);也會透過curl https://127.0.0.1:6443/api/v1/pods查看。這個API路徑/version和/api就是API Groups。K8s會根據API的目的將多個API集合成一個Group,除了/version、/api以外,還有其他如/logs、/apis和/metrics等,每個API Groups都有不同的目的。而負責K8s集群中功能運作的API就是/api和/apis,我們拿出來重點介紹一下。
/api (core group)
負責K8s集群運作的核心功能,舉凡像namespaces、Pods、RCs、Nodes、bindings、Secret、Service等物件
/apis (named group)named group相較於core group更有組織性,像是/apps、/extension、/networking.k8s.io、/storage.k8s.io、authentication.k8s.io及/certificates.k8s.io都算是named group的一員。
在/apps下還有像是/apps/v1/deployments、/apps/v1/replicasets及/statefulsets等;/networking.k8s.io下有/networking.k8s.io/v1/networkpolicies;/certificates.k8s.io下有/certificates.k8s.io/certificatesigningrequests等
這些/apps、/extension、/networking.k8s.io、/storage.k8s.io、authentication.k8s.io及/certificates.k8s.io都是屬於API Group,而/apps/v1/deployments、/apps/v1/replicasets及/statefulsets等則可以稱為是這些group下的resources,每個resources有一系列的actions,表示這些resources可以做的事。這些actions統稱為Verb。Verb包含:
代表可以列出
Deployment、得到Deployment資訊、創建Deployment、刪除Deployment、更新Deployment或查看Deployment等。

那要如何查看有哪些API Group呢? 可以透過curl https://localhost:6443 -k指令
但是會發現遭到fotbidden而無法查看,這是因為curl的目的地是https,需要透過相關認證機制。有兩個方法可以解決:
第一種方法最直接,就是加上https需要的參數,在指令後方加上--key、--cert及--cacert參數即可
第二種方法是透過kubectl proxy命令,在Control Plane節點上以port8001啟動kubectl proxy client。這種方式是直接參考kubeconfig檔案中User的credentials和certificates,就不需要額外輸入認證參數了
第二種方法直接在Control Plane節點上輸入kubectl proxy命令,再開另一視窗輸入curl http://localhost:8001 -k

這樣一來就可以看到有哪些API Group是 avaliable的,若要特別查看哪些是named API Group,可以透過grep篩選:
$ curl http://localhost:8001/apis -k | grep -i "name"

RBAC的概念即是基於角色的訪問控制,以角色做為授權 (Authorization) 的基礎,也就是一種管制訪問 K8s API 的機制。可能有點抽象,我們來看看一個scenario:
假設我們今天是K8s集群的管理者 (Administrator),我們想讓在集群上開發的開發者(developer)有某些權限,例如他可以新增Pod、移除Pod等等。當然我們可以個別限制每個開發者的權限,但是當今天開發者數量很多的時候,我們必須有個統一管理的方法,那就是Role這個物件的功能啦~ 我們為開發者創造一個Role物件,名稱則取為developer,定義檔如下:
$ cat dev-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: developer
rules:
  ## "" indicates the core API group
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list", "create", "update", "delete"]
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get", "watch", "list"]
要注意這邊不再是spec欄位,而是rules
透過 rbac.authorization.k8s.io 這個 API Group 來進行管理配置。
rules包含三個子欄位
API Group name。若此欄空白,則預設為core API
resource進行設定resources進行的操作rules可以一次設定好幾個,以YAML陣列區隔即可。
有了developer 的Role之後,下一步就是將真正的開發者和此Role連結起來,也就是說,讓開發者能成為集群中的 "developer" 這個角色,這就需要仰賴RoleBinding物件了。
RoleBinding的目的即是連接User和Role
RoleBinding範例YAML如下:
$ cat dev-rolebinding.yaml 
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: developer-binding
  namespace: default
subjects:
## You can specify more than one "subject"
- kind: User
  name: dev-user # "name" is case sensitive
  apiGroup: rbac.authorization.k8s.io
roleRef:
  ## "roleRef" specifies the binding to a Role / ClusterRole
  ## this must be Role or ClusterRole
  kind: Role
  ## this must match the name of the Role or ClusterRole you wish to bind to
  name: developer
  apiGroup: rbac.authorization.k8s.io
要注意這邊同樣不是spec欄位,而是subjects和roleRef
subjects 欄位用來描述User的資訊
roleRef 則是要binding的Role資訊
接續前面的scenario,假設你今天是dev-user,你想確認你可以對特定物件做甚麼操作,可以透過以下指令:
## 指令
$ kubectl auth can-i <verb> <resoureces>
## 範例
$ kubectl auth can-i create nodes
no
$ kubectl auth can-i delete pods
yes
若你是管理者,你想檢查開發者可否對特定物件做甚麼操作,則可透過:
$ kubectl auth can-i delete nodes --as dev-user
no
$ kubectl auth can-i create pods --as dev-user
yes
那這題就很簡單啦,創造一個Role和Rolebinding的基本YAML就可以完成囉~
## 建立ns
$ kubectl create ns development
## 建立role
$ kubectl create role developer --resources=pods --verb=creare,list,get,update,delete --namespace=development -o yaml > q12-role.yaml
$ kubectl apply -f q12-role.yaml
## 建立rolebinding
$ kubectl create rolebinding developer-rolebinding --role=developer --user=john --namespace=development -o yaml > q12-rolebinding.yaml
$ kubectl apply -f q12-rolebinding.yaml
今天介紹了比較進階的東西,Role跟Rolebinding,其實可以介紹的還很多,但先了解基本的就可以了,以後有機會再介紹。好啦,今天就到這囉~ 謝謝大家~
You can find me on