十二,k8s集群訪問控制之RBAC授權


角色訪問控制RBAC (Role-Based Access Control)

常用的授權插件:

  1. Node:節點認證
  2. ABAC:基於屬性的訪問控制
  3. RBAC:基於角色的訪問控制
  4. Webhook:基於HTTP回調機制

RBAC控制:

RBAC 主要的功能是提供基於角色(Role)的訪問控制許可(permission)

解釋: 讓一個用戶扮演一個角色(Role),而角色(Role)擁有某些操作的權限,那么這么用戶就擁有了該角色的操作權限。

所以說,之后的所有的操作許可,都是直接授權給角色(Role),而不是直接授權給用戶。

對象
對象列表
虛擬對象,通常是URL,非對象資源,

對某個對象施加的一種行為,成為 Action。

role 和 clusterrole

在RBAC API中,一個角色包含了一套表示一組權限的規則。 權限以純粹的累加形式累積(沒有”否定”的規則)。 角色可以由命名空間(namespace)內的Role對象定義,而整個Kubernetes集群范圍內有效的角色則通過ClusterRole對象實現。

role中,定義對象和動作,決定此role的權限邊界。
在role中,只能定義那些對象的動作被允許,不能定義決絕。
意思就是說,只要沒有定義允許的,都會被拒絕。

角色分為兩種:

1. role         名稱空間級別角色
2. clusterrole  集群級別角色

rolebinding 和 clusterrolebinding

用於用戶和角色之間的綁定關系。role和useraccount或service account之間的綁定

綁定分為兩種:

1. rolebinding          名稱空間界別的角色綁定,針對的邊界是名稱空間
2. clusterrolebinding   集群級別的基色綁定,針對的變邊界是集群

問題: 當使用rolebinding 來對 user1 綁定 clusterrole,那么 user1 的權限是?

解答: user1 的權限還是局限於名稱空間,因為使用的是 rolebinding 來綁定的,突破不來名稱空間。

公共角色 clusterrole

常規做法

每個名稱空間下,user都通過rolebinding綁定role,定義一個ClusterRole擁有集群級別的操作權限,通過ClusterRolebinding與user綁定,該用戶user就有了集群級別的操作權限

便捷做法

假設再有多個pod情況下,如果此時定義好一個 clusterrole 集群角色和對應的權限,使用 Rolebinding 對集群角色 clusterrole 進行綁定,那么所有的名稱空間都可以不用定義自己的 role ,直接使用 clusterrole即可。

以上幾種關系的示意圖

user 創建測試

創建role案例

幫助:

[root@master ~]# kubectl create role --help
Create a role with single rule.

Examples:
  # Create a Role named "pod-reader" that allows user to perform "get", "watch" and "list" on pods
  kubectl create role pod-reader --verb=get --verb=list --verb=watch --resource=pods
  
  # Create a Role named "pod-reader" with ResourceName specified
  kubectl create role pod-reader --verb=get --resource=pods --resource-name=readablepod --resource-name=anotherpod
  
  # Create a Role named "foo" with API Group specified
  kubectl create role foo --verb=get,list,watch --resource=rs.extensions
  
  # Create a Role named "foo" with SubResource specified
  kubectl create role foo --verb=get,list,watch --resource=pods,pods/status
  1. 通過 --dry-run 參數,使命令不是真正執行,只是模擬測試命令是否正常。
  2. 通過 -o yaml 以 yaml 格式輸出

那么下面使用這兩個參數,導出一個 yaml 格式的文件。

[root@master rbac]# kubectl create role pods-reader --verb=get,list,watch --resource=pods --dry-run
role.rbac.authorization.k8s.io/pods-reader created (dry run)
[root@master rbac]# kubectl create role pods-reader --verb=get,list,watch --resource=pods --dry-run -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  creationTimestamp: null
  name: pods-reader
rules:
- apiGroups:
  - ""
  resources:
  - pods
  verbs:
  - get
  - list
  - watch
[root@master rbac]# kubectl create role pods-reader --verb=get,list,watch --resource=pods --dry-run -o yaml > role-demo.yaml
[root@master rbac]# ll
total 4
-rw-r--r-- 1 root root 193 Aug 21 16:56 role-demo.yaml
[root@master rbac]# cat role-demo.yaml 
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  creationTimestamp: null
  name: pods-reader
rules:
- apiGroups:
  - ""
  resources:
  - pods
  verbs:
  - get
  - list
  - watch

創建 role

[root@master rbac]# kubectl apply -f role-demo.yaml 
role.rbac.authorization.k8s.io/pods-reader created
[root@master rbac]# kubectl get role
NAME          AGE
pods-reader   2s
[root@master rbac]# kubectl describe role pods-reader
Name:         pods-reader
Labels:       <none>
Annotations:  kubectl.kubernetes.io/last-applied-configuration:
                {"apiVersion":"rbac.authorization.k8s.io/v1","kind":"Role","metadata":{"annotations":{},"name":"pods-reader","namespace":"default"},"rules...
PolicyRule:
  Resources  Non-Resource URLs  Resource Names  Verbs
  ---------  -----------------  --------------  -----
  pods       []                 []              [get list watch]    # 這里顯示的權限等詳細信息

在之前創建了一個用戶 jerry,此時就可以來綁定剛剛創建的role了。

rolebinding 綁定 jerry用戶

使用相同的方式:

[root@master rbac]# kubectl create rolebinding jerry-read-pods --role=pods-reader --user=jerry --dry-run -o yaml > rolebinding-demo.yaml
[root@master rbac]# cat rolebinding-demo.yaml 
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  creationTimestamp: null
  name: jerry-read-pods
roleRef:            #  表示引用那個角色(role)
  apiGroup: rbac.authorization.k8s.io
  kind: Role            #表示綁定角色為role
  name: pods-reader     # 綁定的role名稱
subjects:               # 綁定的用戶,類型可以為user,group,ServiceAccount
- apiGroup: rbac.authorization.k8s.io
  kind: User           #user,group,ServiceAccount三種類型均可
  name: jerry           # 綁定的具體用戶名

創建:

[root@master rbac]# kubectl apply -f rolebinding-demo.yaml 
rolebinding.rbac.authorization.k8s.io/jerry-read-pods created
[root@master rbac]# kubectl get rolebinding
NAME              AGE
jerry-read-pods   5s
[root@master rbac]# kubectl describe rolebinding/jerry-read-pods
Name:         jerry-read-pods
Labels:       <none>
Annotations:  kubectl.kubernetes.io/last-applied-configuration:
                {"apiVersion":"rbac.authorization.k8s.io/v1","kind":"RoleBinding","metadata":{"annotations":{},"creationTimestamp":null,"name":"jerry-read...
Role:
  Kind:  Role
  Name:  pods-reader
Subjects:
  Kind  Name   Namespace
  ----  ----   ---------
  User  jerry

測試 jerry 權限

此時切換到 jerry 用戶下進行測試權限:

[root@master rbac]# kubectl config use-context jerry@kubernetes
Switched to context "jerry@kubernetes".
[root@master rbac]# kubectl get pods
NAME          READY   STATUS    RESTARTS   AGE
pod-sa-demo   1/1     Running   0          5d3h
[root@master rbac]# kubectl delete pods/pod-sa-demo
Error from server (Forbidden): pods "pod-sa-demo" is forbidden: User "jerry" cannot delete resource "pods" in API group "" in the namespace "default"
[root@master rbac]# kubectl get pods -n kube-system
Error from server (Forbidden): pods is forbidden: User "jerry" cannot list resource "pods" in API group "" in the namespace "kube-system"

從上面演示可以看出,只有查看名稱空間為default 的權限,沒有其它等刪除的權限,也查看不來其它名稱空間的資源。

clusterrole 測試

定義方式和 role 幾乎相同,查看幫助如下:

[root@master ~]# kubectl create clusterrole --help
Create a ClusterRole.

Examples:
  # Create a ClusterRole named "pod-reader" that allows user to perform "get", "watch" and "list" on pods
  kubectl create clusterrole pod-reader --verb=get,list,watch --resource=pods
  
  # Create a ClusterRole named "pod-reader" with ResourceName specified
  kubectl create clusterrole pod-reader --verb=get --resource=pods --resource-name=readablepod
--resource-name=anotherpod
  
  # Create a ClusterRole named "foo" with API Group specified
  kubectl create clusterrole foo --verb=get,list,watch --resource=rs.extensions
  
  # Create a ClusterRole named "foo" with SubResource specified
  kubectl create clusterrole foo --verb=get,list,watch --resource=pods,pods/status
  
  # Create a ClusterRole name "foo" with NonResourceURL specified
  kubectl create clusterrole "foo" --verb=get --non-resource-url=/logs/*
  
  # Create a ClusterRole name "monitoring" with AggregationRule specified
  kubectl create clusterrole monitoring --aggregation-rule="rbac.example.com/aggregate-to-monitoring=true"

創建 clusterrole

[root@master rbac]# kubectl create clusterrole cluster-reader --verb=get,list,watch --resource=pods --dry-run -o yaml > clusterrole-demo.yaml
[root@master rbac]# cat clusterrole-demo.yaml 
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  creationTimestamp: null
  name: cluster-reader
rules:
- apiGroups:
  - ""
  resources:
  - pods
  verbs:
  - get
  - list
  - watch
[root@master rbac]# kubectl apply -f clusterrole-demo.yaml 
clusterrole.rbac.authorization.k8s.io/cluster-reader created
[root@master rbac]# kubectl describe clusterrole/cluster-reader
Name:         cluster-reader
Labels:       <none>
Annotations:  kubectl.kubernetes.io/last-applied-configuration:
                {"apiVersion":"rbac.authorization.k8s.io/v1","kind":"ClusterRole","metadata":{"annotations":{},"creationTimestamp":null,"name":"cluster-re...
PolicyRule:
  Resources  Non-Resource URLs  Resource Names  Verbs
  ---------  -----------------  --------------  -----
  pods       []                 []              [get list watch]

測試綁定jerry用戶

之前jerry綁定了一個role,此時需要把這個rolebinding刪除,然后在綁定clusterrole

[root@master rbac]# kubectl create clusterrolebinding jerry-read-all-pods --clusterrole=cluster-reader --user=jerry --dry-run -o yaml > clusterrolebinding-demo.yaml
[root@master rbac]# cat clusterrolebinding-demo.yaml 
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  creationTimestamp: null
  name: jerry-read-all-pods
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-reader
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: User
  name: jerry
[root@master rbac]# kubectl apply -f clusterrolebinding-demo.yaml 
clusterrolebinding.rbac.authorization.k8s.io/jerry-read-all-pods created
[root@master rbac]# kubectl describe clusterrolebinding/jerry-read-all-pods
Name:         jerry-read-all-pods
Labels:       <none>
Annotations:  kubectl.kubernetes.io/last-applied-configuration:
                {"apiVersion":"rbac.authorization.k8s.io/v1beta1","kind":"ClusterRoleBinding","metadata":{"annotations":{},"creationTimestamp":null,"name"...
Role:
  Kind:  ClusterRole
  Name:  cluster-reader
Subjects:
  Kind  Name   Namespace
  ----  ----   ---------
  User  jerry

測試jerry權限

切換至 jerry,然后進行訪問測試:

[root@master rbac]# kubectl get pods
NAME          READY   STATUS    RESTARTS   AGE
pod-sa-demo   1/1     Running   0          5d4h
[root@master rbac]# kubectl get pods -n kube-system
NAME                                        READY   STATUS    RESTARTS   AGE
coredns-5c98db65d4-8mzfz                    1/1     Running   0          43d
coredns-5c98db65d4-spjx8                    1/1     Running   0          43d
etcd-master.kubernetes                      1/1     Running   0          43d
kube-apiserver-master.kubernetes            1/1     Running   0          43d
kube-controller-manager-master.kubernetes   1/1     Running   0          43d
kube-flannel-ds-amd64-4szk7                 1/1     Running   0          43d
kube-flannel-ds-amd64-b4ssp                 1/1     Running   1          43d
kube-flannel-ds-amd64-nmklz                 1/1     Running   0          43d
kube-flannel-ds-amd64-wjczq                 1/1     Running   0          43d
kube-proxy-8fqsz                            1/1     Running   0          43d
kube-proxy-bkrw4                            1/1     Running   0          43d
kube-proxy-n75g8                            1/1     Running   1          43d
kube-proxy-rmckk                            1/1     Running   0          43d
kube-scheduler-master.kubernetes            1/1     Running   0          43d
kubernetes-dashboard-7d75c474bb-8kzrl       1/1     Running   0          9d
[root@master rbac]# kubectl get service
Error from server (Forbidden): services is forbidden: User "jerry" cannot list resource "services" in API group "" in the namespace "default"
[root@master rbac]# kubectl get service -n kube-system
Error from server (Forbidden): services is forbidden: User "jerry" cannot list resource "services" in API group "" in the namespace "kube-system"

從上面測試可以看出:

  1. 可以訪問default名稱空間的pods資源,但不能訪問service資源。
  2. 可以訪問 kube-system 名稱空間的資源, 也不能訪問 kube-system 名稱空間 service資源。

測試rolebinding綁定clusterrole

先刪除jerry剛剛binding的clusterrolebinding

[root@master rbac]# kubectl delete -f clusterrolebinding-demo.yaml 
clusterrolebinding.rbac.authorization.k8s.io "jerry-read-all-pods" deleted
[root@master rbac]# kubectl config use-context jerry@kubernetes
Switched to context "jerry@kubernetes".
[root@master rbac]# kubectl get pods
Error from server (Forbidden): pods is forbidden: User "jerry" cannot list resource "pods" in API group "" in the namespace "default"

可以看到,刪除clusterrolebinding后,jerry用戶沒有get權限。

下面使用rolebinding綁定clusterrole

[root@master rbac]# kubectl create rolebinding jerry-read-pods --clusterrole=cluster-reader --user=jerry --dry-run
rolebinding.rbac.authorization.k8s.io/jerry-read-pods created (dry run)
[root@master rbac]# kubectl create rolebinding jerry-read-pods --clusterrole=cluster-reader --user=jerry --dry-run -o yaml > rolebinding-clusterrole-demo.yaml
[root@master rbac]# cat rolebinding-clusterrole-demo.yaml 
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding                           # 這里的類型是rolebinding
metadata:
  name: jerry-read-pods
  namespace: default                        # 編輯增加可訪問的名稱空間
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole                         # 而這里綁定的是clusterrole
  name: cluster-reader
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: User
  name: jerry                               # 綁定的用戶
[root@master rbac]# kubectl apply -f rolebinding-clusterrole-demo.yaml 
rolebinding.rbac.authorization.k8s.io/jerry-read-pods created

測試訪問

[root@master rbac]# kubectl get pods
NAME          READY   STATUS    RESTARTS   AGE
pod-sa-demo   1/1     Running   0          5d19h
[root@master rbac]# kubectl get pods -n kube-system
Error from server (Forbidden): pods is forbidden: User "jerry" cannot list resource "pods" in API group "" in the namespace "kube-system"

測試只能訪問 default 名稱空間的資源,而不能訪問其他名稱空間的資源。

clusterrole admin 默認角色

在clusterrole 中,有兩個默認的admin角色,admin、cluster-admin

這兩個都是集群角色的管理員,那么當集群中有多個名稱空間的時候,就不需要手動去創建管理員角色,直接可以使用admin的角色機型rolebinding,這樣省去了很多重復工作。

測試綁定

測試把 clusterrole 的 admin 角色綁定到 jerry 用戶上。

之前已經綁定了一個clusterrole,此時再次綁定,不受影響,相當於一人身兼多職。

[root@master rbac]# kubectl create rolebinding defult-ns-admin --clusterrole=admin --user=jerry
rolebinding.rbac.authorization.k8s.io/defult-ns-admin created
[root@master rbac]# kubectl config use-context jerry@kubernetes         # 切換到jerry用戶
Switched to context "jerry@kubernetes".
[root@master rbac]# kubectl get pods                                    # 能夠讀
NAME          READY   STATUS    RESTARTS   AGE
pod-sa-demo   1/1     Running   0          5d20h
[root@master rbac]# kubectl delete pods pod-sa-demo
pod "pod-sa-demo" deleted                                               # 刪除成功
[root@master rbac]# kubectl get pods
No resources found.
[root@master rbac]# kubectl get pods -n kube-system                     # 但這里不能訪問其他名稱空間
Error from server (Forbidden): pods is forbidden: User "jerry" cannot list resource "pods" in API group "" in the namespace "kube-system" 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM