iT邦幫忙

2024 iThome 鐵人賽

DAY 13
0
Kubernetes

當 Quarkus 想要騎乘駱駝並用8腳章魚掌控舵手 系列 第 13

Kubernetes 的 Role-Based Access Control

  • 分享至 

  • xImage
  •  

RBAC(Role-Based Access Control),它將權限授予角色(role)上,可以想像它是一個責任。對 RBAC 來說,使用者(User)是一個獨立可存取資源的主體(Subject)。這過程中被允許對一或多個 Object 執行的操作可以稱做許可(Permission),一個使用者可藉由授權而擁有多個 role。

  人
  O
 \|/
 / \         action(verb)
Subject --------------------> Object

RBAC 中 User、Role 和 Permission 關係如下

                            ___________________________
       -----> Role         |       Permissions         |
     /             \       |                           |
User                -----> | Operations -----> Objects |
     \             /       |                           |
       -----> Role         |___________________________|

RBAC 是一個限定操作的機制,用於定義誰(subject)能或不能操作(verb)哪個物件(object)。動作的發出者(subject)可以是一個 User Accoun 或是 Service Account;verb 表示要執行的操作 create、apply、delete、update、patch、edit 和 get 等;object 是指要被操作的目標資源,以 Kubernetes API 來看是以 URL 作為對象。

RBAC 支援 RoleClusterRole 兩種角色,前者是 namespace 級別後者則是集群級別,對這兩類給權限時,需要用到 RoleBindingClusterRoleBinding。RoleBinding 將 role 上的 Permissions 綁定到一個或一組使用者上,此綁定只能隸屬於某一個 namespaceClusterRoleBinding 則用於及群集別。

在一個 namespace 下可以包含多個 RoleRoleBinding 對象,集群級別也是可存在多個 ClusterRoleClusterRoleBinding。一個使用者可以經由 RoleBindingClusterRoleBinding 關連至多個角色,並實現多重授權。

Role 和 RoleBinding

Role 僅是一組 permission 權限的集合,在 Role 類型的 yaml 檔中使用 rules 字段定義授權規則。下面是一個 Kubernetes Dashboard 的 Role 範例,它監視了 secretsconfigmapsservices 資源的權限。

kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
rules:
  # Allow Dashboard to get, update and delete Dashboard exclusive secrets.
  - apiGroups: [""]
    resources: ["secrets"]
    resourceNames: ["kubernetes-dashboard-key-holder", "kubernetes-dashboard-certs", "kubernetes-dashboard-csrf"]
    verbs: ["get", "update", "delete"]
    # Allow Dashboard to get and update 'kubernetes-dashboard-settings' config map.
  - apiGroups: [""]
    resources: ["configmaps"]
    resourceNames: ["kubernetes-dashboard-settings"]
    verbs: ["get", "update"]
    # Allow Dashboard to get metrics.
  - apiGroups: [""]
    resources: ["services"]
    resourceNames: ["heapster", "dashboard-metrics-scraper"]
    verbs: ["proxy"]
  - apiGroups: [""]
    resources: ["services/proxy"]
    resourceNames: ["heapster", "http:heapster:", "https:heapster:", "dashboard-metrics-scraper", "http:dashboard-metrics-scraper"]
    verbs: ["get"]

rules 下定義了規則其字段有。

  1. apiGroups
    包含 API 組的名稱,可以使用列表方式定義,如果以 "" 表示是 core API group。
  2. resource
    要將規範應用的目標資源種類(pods、deployments...),同樣可以列表方式呈現。ResourceAll 表示所有資源
  3. resourceNames
    要將規範應用的目標資源種類下名稱,如果為空表示所有資源
  4. verbs
    資源類型的操作,有 get、list、create、update、patch、watch、proxy、redirect、delete 和 deletecollection
  5. nonResourceURLs
    定義用戶應該有權限訪問的網址列表,非 namespace 級別,因此適用於 ClusterRole 和 ClusterRoleBinding

在範例中 resources: ["services/proxy"] 表示 proxy 是 services 的子資源,因此使用 resource/subre-source 格式呈現。

以下是一個透過 kubectl create role 建立 role 資源的快速方式

kubectl create namespace test
kubectl create role pods-reader --verb="get,list,watch" --resource="pods,pods/log" -n test
kubectl create role service-admin --verb="*" --resource="service,services/*" -n test
role.rbac.authorization.k8s.io/service-admin created

kubectl -n test describe role service-admin
Name:         service-admin
Labels:       <none>
Annotations:  <none>
PolicyRule:
  Resources   Non-Resource URLs  Resource Names  Verbs
  ---------   -----------------  --------------  -----
  services/*  []                 []              [*]
  services    []                 []              [*]

建立 role 後需要綁定 Role-Binding 到 subject 上才有作用。RoleBinding 用於將 Role 中定義的權限賦予一個或一組用戶,它由一組 subject 以及一個要引用來賦予這組 subjectRoleClusterRole 組成。

kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: reader-resource
  namespace: test
subjects: # 要綁定的 subject
  - kind: User
    name: kube-user1
    apiGroup: rbac.authorization.k8s.io
roleRef: # 要綁定的 Role 或 ClusterRole 資源
  kind: Role
  name: pods-reader
  apiGroup: rbac.authorization.k8s.io

透過指令方式

kubectl create rolebinding reader-resource --role=pods-reader --user=kube-user1 -n test
  • subjects
    • apiGroup ServiceAccount 為 "";User 和 Group 為 "rbac.authorization.k8s.io"
    • kind 所屬類別,User、Group 和 ServiceAccount
    • name 名稱
    • namespace 所屬的 namespace,User、Group 須為空
      roleRef 的字段與 subjects 大同小異

Role 和 RoleBinding 屬於 namespace 級別,有時須注意非 namespace 級別的資源,如 PersistentVolumeNameSpaceNode 等,而這些資源就得用 ClusterRoleClusterRoleBinding 進行配置。

ClusterRole 和 ClusterRoleBinding

ClusterRole 能夠管理和 Role 資源一樣的准許權限外,還可以管理集群資源的授權。下面為一個 kubernetes dashboard 範例,由於不屬於 namespace 級別,因此不會有其欄位。

---

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
rules:
  # Allow Metrics Scraper to get metrics from the Metrics server
  - apiGroups: ["metrics.k8s.io"]
    resources: ["pods", "nodes"]
    verbs: ["get", "list", "watch"]

---

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: kubernetes-dashboard
subjects:
  - kind: ServiceAccount
    name: kubernetes-dashboard
    namespace: kubernetes-dashboard

---

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: kubernetes-dashboard
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: kubernetes-dashboard
subjects:
  - kind: ServiceAccount
    name: kubernetes-dashboard
    namespace: kubernetes-dashboard

---

RoleBinding 也能將 subject 綁定 ClusterRole 資源,但權限會被 RoleBinding 所限制,也就是 ClusterRole 所賦予權限只能使用在 RoleBinding 所在的 namespace

系統預設下建立許多的 ClusterRole 資源,以 K3d 環境為例。

$ kubectl get clusterrole 
NAME                                                                   CREATED AT
system:controller:certificate-controller                               2024-08-24T06:46:15Z
system:controller:pvc-protection-controller                            2024-08-24T06:46:15Z
system:controller:pv-protection-controller                             2024-08-24T06:46:15Z
system:controller:ttl-after-finished-controller                        2024-08-24T06:46:15Z
system:controller:root-ca-cert-publisher                               2024-08-24T06:46:15Z
k3s-cloud-controller-manager                                           2024-08-24T06:46:18Z
system:coredns                                                         2024-08-24T06:46:18Z
local-path-provisioner-role                                            2024-08-24T06:46:18Z
system:aggregated-metrics-reader                                       2024-08-24T06:46:18Z
system:metrics-server                                                  2024-08-24T06:46:19Z
clustercidrs-node                                                      2024-08-24T06:46:20Z
system:k3s-controller                                                  2024-08-24T06:46:20Z
view                                                                   2024-08-24T06:46:15Z
edit                                                                   2024-08-24T06:46:15Z
admin                                                                  2024-08-24T06:46:15Z
...

創建使用者與綁定角色範例

下面是非 K3d 環境的方式,是原生 kubeadm 建置的集群環境。

openssl genrsa -out itachi.key 2048
openssl req -new -key itachi.key -out itachi.csr -subj "/CN=itachi/O=test"
sudo openssl x509 -req -in itachi.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key  -CAcreateserial -out itachi.crt -days 30
kubectl config set-credentials itachi --client-certificate itachi.crt --client-key itachi.key
kubectl config set-context itachi-context --cluster=kubernetes --namespace=test --user=itachi
kubectl --context=itachi-context get pod
Error from server (Forbidden): pods is forbidden: User "itachi" cannot list resource "pods" in API group "" in the namespace "test"

發生無權限存取。此時將上述建置的 reader-resource 的 RoleBinding 中 User 設定成 itachi 即可。

kubectl --context=itachi-context get pods
No resources found in test namespace.

刪除使用者

kubectl config unset users.itachi

下個章節將使用 Quarkus 帶來範例。


上一篇
Kubernetes 上的訪問安全控制
下一篇
Quarkus 實現 Hot-reload 之 Downward API 與 RBAC
系列文
當 Quarkus 想要騎乘駱駝並用8腳章魚掌控舵手 31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言