
Photo by Andrew Moca on Unsplash
我們共用叢集,但應該如何劃分權限、分配資源?
當不同單位、組織、使用者共用叢集來部署微服務,我們開始顧慮到彼此在資源上的訪問權限,也琢磨著可以怎樣來清楚劃分彼此資源。在叢集使用上,我們可能有協作者一同架構,當然也存在著一般使用者來訪問服務,類似的權限資源劃分我們怎麼解決?
我們可以做個情境假設,當我們安裝一個叢集在公司裡
人物角色
IT 部門 🧔 叢集管理者 A (Cluster Role)
IT 部門 🕵️♂️ 叢集監控者 B (Cluster Role)
Sales 👱♀️ 區域使用者 C (Role)
RD 部門 👨🦱 區域使用者 D (Role)
產品部門 🧑 區域使用者 E (Role)
工廠部門 👦 區域使用者 F (Role)
🧔 A : 我需要監控整個叢集網路狀態,即時處理各部門上架微服務後的問題,當然我也可以部署一些微服務。
A 需要有叢集最高權限
🕵️♂️ B : 我只需要幫忙監控叢集狀態,不做任何修改動作。
B只需要有訪問叢集權限
👱♀️ C : 我需要用到 D的提供的 Service 來介紹銷售
C 需要擁有 D的區域訪問權限
👨🦱 D : 我需要部署架設微服務上叢集,但我們需要架設微服務在自己的伺服器電腦
把 D 的電腦納入叢集節點,並提供 D 區域使用權限
🧑 E : 我需要架設微服務在自己的伺服器電腦及工廠端電腦協作
把兩端電腦加入叢集,並提供 E 區域使用權限
👦 F : 我與 E 一同協作
提供 F 在 E 區使用權限
如上述,透過監控狀態、集中管理、分配權限、協同工作、遠程部署,當一個叢集必須被使用在不同單位、組織時,我們可以透過什麼方式來讓各自單位作業於叢集資源下,又可以各自劃分區塊?
RBAC (Role-base access control) 本身提供了我們一套框架,讓我們可以分配不同角色的權限。讓我們繼續透過一步步操作,了解如何依據這套框架,新建 User 與 Kubernetes 綁定 Rule。

我們可以用 Kubernetes 的角色對照 OS 的權限去結合使用,當我們為 root 時,Cluster 視我為 Kubernetes admin 拿著 root certificates 最高權限,我們再透過 admin 去建立上面的 aserver、alice、bob、chuck 等 user account。如下,紅字部分是我們必須為 OS 創立的 user。

範例 1 建立一個叢集使用者(最高權限)
- root 建立 user
root@example:~# sudo useradd aserver && cd /home/aserver
root@example:~# sudo useradd alice && cd /home/alice
root@example:~# sudo useradd bob && cd /home/bob
root@example:~# sudo useradd chuck && cd /home/chuck
- 建立 private key for user
root@example:~# openssl genrsa -out aserver.key 2048
root@example:~# openssl genrsa -out alice.key 2048
root@example:~# openssl genrsa -out bob.key 2048
root@example:~# openssl genrsa -out chuck.key 2048
- 建立 certificate signing request (CSR)
root@example:~# openssl req -new -key aserver.key -out aserver.csr -subj "/CN=aserver"
root@example:~# openssl req -new -key alice.key -out alice.csr -subj "/CN=alice"
root@example:~# openssl req -new -key bob.key -out bob.csr -subj "/CN=bob"
root@example:~# openssl req -new -key chuck.key -out chuck.csr -subj "/CN=chuck"
- sign public ca for user,為 root 綁定的 user 指定 ca.crt 與 ca.key
root@example:~#
openssl x509 -req -in {user}.csr \
-CA /etc/kubernetes/pki/ca.crt \
-CAkey /etc/kubernetes/pki/ca.key \
-CAcreateserial \
-out {user}.crt -days 5 #時間可以自訂
- 在 /home/{user}/ 下建立 .certs,把 ca 轉到該資料夾

root@example:/home/{user}#
mkdir .certs && mv {user}.crt {user}.key .certs
kubectl config set-credentials {user} \
--client-certificate=/root/.certs/{user}.crt \
--client-key=/root/.certs/{user}.key
kubectl config set-context gemini-context \
--cluster=kubernetes --user={user}
目前只有一個 Kubernetes cluster,幫 user 設置 context 為 {user}-context
- 建立 .kube/config 給予讀取權限
root@example:/home/{user}#
mkdir .kube && vi .kube/config
chown -R {user}: /home/{user}/
export KUBECONFIG=$HOME/.kube/config
.kube/config 內容如下
root@example:/home/{user}/.kube#vi config
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUN5RENDQWJDZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRJeU1ETXlNekF6TXpneU5sb1hEVE15TURNeU1EQXpNemd5Tmxvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTk1GCk42b1pFTlhTdXVmUW9acDAzQVN3UkhlaGE0aDZaTlg5Ym1raHdYODhaeHVTbUxoY2ZNR3RoWit2Qk5WSTRPYlAKQjZtMVF3ckN3WlRvU1lGNTd5cXJPSHhSdEhHcHl5Q2l2czNzRThvTVV2cmd0TWdndUdwd1hDUVp1bzdPeTFlVApSMFFOS3NVR2t5dzVzVlJybXpVa2E3eE1LZzZoa0dmME9yUzZCajQ3ckx6dUVtc3RSZmY5dGxRdkJvQUdlNk1BCjltdEluNnd0b0g3bjJJdzBZcllidzFQeWNZemw5ZmovQnZkc3FqcTVySjZLY04wb05XbHh5ek5tSW1wbnE5U0gKOGNlS1ZKZDcxUFFLejlJYUpsd1NNUlhLMU1sN2Rqd1hkSWt0MURHOUFzbldxT3RwcXZhRkgrMlpRQWc1NGFvUApib0U4WWpSRjVZRkE2S1JlMFNVQ0F3RUFBYU1qTUNFd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFIdlEyYkIzZHI5dExyanRpdXY4MXhtZ2g3anMKSDJQd3JRRVh6blVqWFFBdzZZeHAyL2h4Q3puQmg5Ly9qNEJWVFlzdEJpQm0vL0xnbkQwSndpWnc0RW1MbGFjKwo0NEhBc2pzb3Qvd2Y4VzBhbTMvNlhCYlRlb3UzaVBnQXlvQ0sxOG5oZTZKQW9lVXQzNVhabWo3ZjBPYjE4cWFPCmlhanM2QjMvVUJxUTNTUUtZdWRqT0llcnluUWRxcjd2YUNpRWs0NnBQN1ExT2U1bnFtc0trZVR1bXpUQ29ibXEKWjZuTnMxUUhIUkhGeTZKczZacHpsRXBSZGxOckpqNGY5RW5yM25PV21wMW10Z0NhemJCRUsrZmZDclZRd3lqcwpaeVNKT05KdWl2L1dubXptZnNVUXZXUDhQK01xQzd0KzM2TWRwUzhKZWNFZVY4TVhnbGxWMldGdGlhTT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
server: https://10.18.242.253:6443
name: kubernetes
contexts:
- context:
cluster: kubernetes
user: {user}
name: {user}-context
current-context: {user}-context
kind: Config
preferences: {}
users:
- name: {user}
user:
client-certificate: /home/{user}/.certs/{user}.crt
client-key: /home/{user}/.certs/{user}.key
- 設置 cluster role 或者 role 所有權限
cluster role 範例如下
root@example:~# kubectl apply -f {user}_cr.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: {user}
rules:
- apiGroups:
- '*'
resources:
- '*'
verbs:
- '*'
- nonResourceURLs:
- '*'
verbs:
- '*'
role 範例如下
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: jean
namespace: jean
rules:
- apiGroups:
- '*'
resources:
- '*'
verbs:
- '*'
- 設置 clusterrolebinding、rolebinding 及 service account
clusterrolebinding
root@example:~# kubectl apply -f {user}_crb.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: {user}
subjects:
- kind: ServiceAccount
name: {user}
namespace: kube-system
- kind: User
name: {user}
roleRef:
kind: ClusterRole
name: {user}
apiGroup: rbac.authorization.k8s.io
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: {user}
namespace: kube-system
labels:
kubernetes.io/cluster-service: "true"
rolebinding
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: {user}
namespace: {yournamespace}
subjects:
- kind: ServiceAccount
name: {user}
namespace: {yournamespace}
- kind: User
name: {user}
roleRef:
kind: Role
name: {user}
apiGroup: rbac.authorization.k8s.io
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: {user}
namespace: {yournamespace}
取得 token
root@example:~#
kubectl -n kube-system get secret|grep {user}-token
gemini-token-f5lcp kubernetes.io/service-account-token 3 2m3s
kubectl -n kube-system get secret {user}-token-f5lcp -o jsonpath={.data.token}|base64 -d
eyJhbGciOiJSUzI1NiIsImtpZCI6Il9KYjdtNEFYcjRmMEJBY1dVMEpsVk5GdTF1QVgybWpHdzU5Q182RnhERXcifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJnZW1pbmktdG9rZW4tZjVsY3AiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiZ2VtaW5pIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiZWEyMzQzOTktZWNmNy00YjQwLWE4OTAtODc4MWUyMjBiYjFlIiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50Omt1YmUtc3lzdGVtOmdlbWluaSJ9.edBAfkAQXhyu4G0FVkG-O85_2RSi74dQ2JSK07AH67R1rEB3HVht6ZizpPwoucHaeym2An7GQT051fbUnLCtHJ7iALdK3jMlo62xC8-ONrXItQWm5ErmJNLhWyexENkyMlINTyt-HPN3Q3pwNrWvIVIj8YXanmo95aCbdgLZxhs1gtVIJAM80VyijfA4LT5ZFLYhs6wxAwZDVH7J4Sk6YHH-H8ueaLOZ1wtIzdh22VbNK4LkytBCcbS_bJofzVpkYPtmWtQkUfPTUclt7LdzVq0r14kpidwUBzZSVmUZXK_IyJMSX6sEbX2paMejF0Um0ALqcbdX6zKW8Nx-Pq4jQgroot
把 token 設置到 /home/gemini/config
users:
- name: {user}
user:
client-certificate: /home/{user}/.certs/{user}.crt
client-key: /home/{user}/.certs/{user}.key
token: eyJhbGciOiJSUzI1NiIsImtpZCI6Il9KYjdtNEFYcjRmMEJBY1dVMEpsVk5GdTF1QVgybWpHdzU5Q182RnhERXcifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJnZW1pbmktdG9rZW4tZjVsY3AiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiZ2VtaW5pIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiZWEyMzQzOTktZWNmNy00YjQwLWE4OTAtODc4MWUyMjBiYjFlIiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50Omt1YmUtc3lzdGVtOmdlbWluaSJ9.edBAfkAQXhyu4G0FVkG-O85_2RSi74dQ2JSK07AH67R1rEB3HVht6ZizpPwoucHaeym2An7GQT051fbUnLCtHJ7iALdK3jMlo62xC8-ONrXItQWm5ErmJNLhWyexENkyMlINTyt-HPN3Q3pwNrWvIVIj8YXanmo95aCbdgLZxhs1gtVIJAM80VyijfA4LT5ZFLYhs6wxAwZDVH7J4Sk6YHH-H8ueaLOZ1wtIzdh22VbNK4LkytBCcbS_bJofzVpkYPtmWtQkUfPTUclt7LdzVq0r14kpidwUBzZSVmUZXK_IyJMSX6sEbX2paMejF0Um0ALqcbdX6zKW8Nx-Pq4jQg
可以透過 service account 得到的 token 做 api 訪問
curl --header "Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6Il9KYjdtNEFYcjRmMEJBY1dVMEpsVk5GdTF1QVgybWpHdzU5Q182RnhERXcifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJnZW1pbmktdG9rZW4tZjVsY3AiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiZ2VtaW5pIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiZWEyMzQzOTktZWNmNy00YjQwLWE4OTAtODc4MWUyMjBiYjFlIiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50Omt1YmUtc3lzdGVtOmdlbWluaSJ9.edBAfkAQXhyu4G0FVkG-O85_2RSi74dQ2JSK07AH67R1rEB3HVht6ZizpPwoucHaeym2An7GQT051fbUnLCtHJ7iALdK3jMlo62xC8-ONrXItQWm5ErmJNLhWyexENkyMlINTyt-HPN3Q3pwNrWvIVIj8YXanmo95aCbdgLZxhs1gtVIJAM80VyijfA4LT5ZFLYhs6wxAwZDVH7J4Sk6YHH-H8ueaLOZ1wtIzdh22VbNK4LkytBCcbS_bJofzVpkYPtmWtQkUfPTUclt7LdzVq0r14kpidwUBzZSVmUZXK_IyJMSX6sEbX2paMejF0Um0ALqcbdX6zKW8Nx-Pq4jQg" --insecure -X GET https://10.18.242.253:6443/api/v1/node
結論
上面我們透過 OS 創建 user,搭配 Kubernetes Config 以及 Certificates 來創建 Cluster Role 及 Role 兩種角色,讓 user 擁有 namespace 的權限來做到叢集的共同使用及權限分配,以實現我們需要的模型。
Reference
- 雙子星雲端 Medium
- Users and RBAC authorizations in Kubernetes
- Limiting access to Kubernetes resources with RBAC
- Using RBAC Authorization