RBAC 與 Kubernetes 的管理模型

May 11, 2022 Nick

Photo by Alvaro Reyes on Unsplash

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 建立一個叢集使用者(最高權限)

  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
  1. 建立 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
  1. 建立 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"
  1. 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 #時間可以自訂
  1. 在 /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

  1. 建立 .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
  1. 設置 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:
  - '*'

  1. 設置 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


雙子星雲端為 CNCF 會員,是 CNCF 所認證的 Kubernetes 服務提供商,在雲端技術擁有十多年以上的經驗,為台灣雲端技術早期領先者。目前為國家級 AI 雲的軟體及 Kubernetes 技術與服務提供商,更是諸多企業與單位導入容器與管理平台的最佳夥伴。

雙子星雲端除了既有的產品 AI Console 與 Gemini API Gateway 之外,也提供企業諮詢與導入雲原生與 Kubernetes 相關技術服務,協助企業擁抱 Cloud Natvive,達到數位轉型的目標。


相關文章

回雙子星技術部落格列表

Gemini AI Console

熱門文章


kubernetes professional service

關於我們

雙子星雲端是混合多雲技術的領導者,是國際認證之 KCSP - Kubernetes 服務提供商,同時也為 CNCF 雲原生計算基金會會員。

雙子星的雲端專家擁有 Kubernetes、OpenStack 與 Google Cloud Platform 等多項證照,我們的軟體至今已為上百家機構和數千台的 CPU/GPU 伺服器提供雲端服務。