角色訪問控制RBAC (Role-Based Access Control)
常用的授權插件:
- Node:節點認證
- ABAC:基於屬性的訪問控制
- RBAC:基於角色的訪問控制
- 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
- 通過
--dry-run
參數,使命令不是真正執行,只是模擬測試命令是否正常。 - 通過
-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"
從上面測試可以看出:
- 可以訪問default名稱空間的pods資源,但不能訪問service資源。
- 可以訪問 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"