容器編排系統K8s之訪問控制--RBAC授權

1874發表於2020-12-31

  前文我們瞭解了k8s上的訪問控制機制,主要對訪問控制中的第一關使用者認證做了相關說明以及常規使用者的配置檔案的製作,回顧請參考:https://www.cnblogs.com/qiuhom-1874/p/14207381.html;今天我們來了解下k8s上的訪問控制第二關RBAC授權相關話題;

  在k8s上授權的機制有很多,最常用的有ABAC和RBAC;ABAC(attribute based access control)這種是基於屬性做訪問控制;RBAC(role based access control)這種是基於角色做訪問控制;所謂基於屬性做訪問控制是指,對k8s上的資源的某種屬性做授權,授權給相關使用者對該資源的某個屬性有什麼許可權;同樣的邏輯基於角色做訪問控制就是指把k8s上的資源,授權給對應角色有什麼許可權;那角色和使用者有什麼關係呢?對於RBAC授權模型來說,在k8s上使用者是沒法直接關聯資源;它是通過角色物件來實現對資源的授權;使用者授權是通過角色繫結物件來關聯到對應角色;只要使用者繫結到對應角色,那麼該使用者就擁有繫結角色上的所有許可權;比如,在k8s上有一個角色名為pod-reader,這個角色能夠對default名稱空間下的pod資源有隻讀許可權;對其他名稱空間任何資源沒有任何許可權;如果一個使用者繫結到該角色上,對應使用者就有對default名稱空間下的pod資源擁有隻讀許可權,對其他名稱空間任何資源沒有任何許可權;對於k8s上的資源來說,資源有兩個級別,一個是名稱空間級別的資源,一個是叢集級別的資源;比如pod,svc,pvc等等這些資源都是名稱空間級別資源,它們的存在必須是在某個名稱空間下;對於類似像pv,node,ns這些資源就是叢集級別資源,它們的存在不依賴任何名稱空間;這樣一來對於角色而言就有名稱空間級別的角色,也有叢集級別角色;名稱空間級別的角色就是用來定義特定名稱空間下的資源許可權,叢集級別角色就是用來定義整個叢集上的資源許可權;在k8s上這兩種角色分別叫role和clusterrole;role和clusterrole都是k8s上的資源,我們要給某個使用者授權,首先把對應角色資源例項化為一個角色物件,然後把使用者和角色物件繫結起來即可;使用者怎麼繫結到角色上呢?在k8s上繫結這個操作也是通過資源物件實現的;繫結也有兩種,一種是rolebinding,一種是clusterrolebinding;rolebinding是名稱空間級別資源,它主要用來把對應使用者和對應名稱空間上的角色(role)做繫結;對應使用者就能擁有對應角色在對應名稱空間下對應資源的許可權;clusterrolebinding主要用來把使用者繫結到叢集級別角色(clusterrole)上,對應使用者就能擁有對整個叢集上的對應角色擁有的對應資源的許可權;簡單講角色(role/clusterrole)就是用來定義資源的許可權,rolebinding和clusterrolebinding是用來關聯使用者和角色的關係;如下圖所示;

  提示:這裡需要注意一點,clusterrole是包含名稱空間級別的role;也就是說clusterrole既可以用clusterrolebinding來繫結,也可以用rolebinding來繫結,如果rolebinding繫結的是一個叢集級別的角色(clusterrole)那麼對應繫結至clusterrole的使用者的許可權就會縮小到對應名稱空間下,而非整個叢集,原因是rolebinding是名稱空間級別資源;

   檢視apiserver啟用授權外掛

  提示:apiserver配置啟用RBAC外掛需要用--authorization-mode選項來指定對應啟用的授權外掛,在k8s1.6以後的版本,預設apiserver會啟用Node和RBAC授權外掛;

  建立角色

  使用陳述時命令create,建立角色的語法格式

Usage:
  kubectl create role NAME --verb=verb --resource=resource.group/subresource
[--resource-name=resourcename] [--dry-run=server|client|none] [options]

  提示:以上create role表示建立的是名稱空間級別的角色,如果沒有指定其名稱空間表示預設名稱空間;--verb是用來指定對應的許可權,比如get,list,watch等等;--resource使用來指定資源資源型別,比如pods,services,daemonsets,replicasets等等;--resource-name用來指定對應具體的資源的名稱;如果要指定名稱空間使用-n選項指定即可;預設不指定表示default名稱空間;

  示例:使用陳述時命令建立名為pod-reader的角色,該角色擁有對default名稱空間下的pod資源有list,get和watch許可權;

[root@master01 ~]# kubectl create role pod-reader --verb=list --verb=get --verb=watch --resource=pods 
role.rbac.authorization.k8s.io/pod-reader created
[root@master01 ~]# kubectl get role
NAME         CREATED AT
pod-reader   2020-12-31T11:27:39Z
[root@master01 ~]# kubectl describe role pod-reader
Name:         pod-reader
Labels:       <none>
Annotations:  <none>
PolicyRule:
  Resources  Non-Resource URLs  Resource Names  Verbs
  ---------  -----------------  --------------  -----
  pods       []                 []              [list get watch]
[root@master01 ~]# 

  提示:可以看到pod-reader角色對pods資源有list,get,watch許可權;

  使用陳述式命令建立clusterrole

  命令使用語法格式

Usage:
  kubectl create clusterrole NAME --verb=verb --resource=resource.group
[--resource-name=resourcename] [--dry-run=server|client|none] [options]

  提示:使用語法和建立名稱空間級別的角色一樣,不同的是指定建立的是clusterrole;

  示例:建立一個名為cluster-pods-reader角色,擁有對叢集所有名稱空間下的pods和servers資源有get,list,watch許可權;

[root@master01 ~]# kubectl create clusterrole cluster-pods-reader --verb=get --verb=list --verb=watch --resource=pods --resource=services
clusterrole.rbac.authorization.k8s.io/cluster-pods-reader created
[root@master01 ~]# kubectl get clusterrole cluster-pods-reader
NAME                  CREATED AT
cluster-pods-reader   2020-12-31T11:35:03Z
[root@master01 ~]# kubectl describe clusterrole cluster-pods-reader
Name:         cluster-pods-reader
Labels:       <none>
Annotations:  <none>
PolicyRule:
  Resources  Non-Resource URLs  Resource Names  Verbs
  ---------  -----------------  --------------  -----
  pods       []                 []              [get list watch]
  services   []                 []              [get list watch]
[root@master01 ~]# 

  提示:可以看到cluster-pods-reader角色有對pods資源和services資源有get,list,watch許可權;

  建立rolebinding

  命令語法格式

Usage:
  kubectl create rolebinding NAME --clusterrole=NAME|--role=NAME [--user=username]
[--group=groupname] [--serviceaccount=namespace:serviceaccountname] [--dry-run=server|client|none]
[options]

  提示:建立rolebinding需要指定對應的名稱,指定clusterrole或者role角色的名稱,指定對應的使用者名稱稱,或者對應的組名;如果對應使用者是sa賬號,需要用--serviceaccount選項來指定對應sa的名稱;sa的名稱由名稱空間:sa名稱;如果要指定名稱空間使用-n選項指定即可;預設不指定表示default名稱空間;

  示例:建立名為tom-pods-reader的rolebinding,其中指定對應tom使用者繫結至pod-reader角色

[root@master01 ~]# kubectl create rolebinding  tom-pods-reader --role=pod-reader --user=tom 
rolebinding.rbac.authorization.k8s.io/tom-pods-reader created
[root@master01 ~]# kubectl get rolebinding
NAME              ROLE              AGE
tom-pods-reader   Role/pod-reader   5s
[root@master01 ~]# kubectl describe rolebinding tom-pods-reader
Name:         tom-pods-reader
Labels:       <none>
Annotations:  <none>
Role:
  Kind:  Role
  Name:  pod-reader
Subjects:
  Kind  Name  Namespace
  ----  ----  ---------
  User  tom   
[root@master01 ~]# 

  提示;這裡沒有顯示名稱空間是那個名稱空間;預設沒有顯示就是default名稱空間;

  驗證:使用tom使用者的配置檔案,看看是否可以列出default名稱空間下的pod列表呢?

[root@master01 ~]# kubectl config view --kubeconfig=/tmp/myk8s.config
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: DATA+OMITTED
    server: https://192.168.0.41:6443
  name: myk8s
contexts:
- context:
    cluster: myk8s
    user: tom
  name: tom@myk8s
current-context: tom@myk8s
kind: Config
preferences: {}
users:
- name: tom
  user:
    client-certificate-data: REDACTED
    client-key-data: REDACTED
    username: tom
[root@master01 ~]# kubectl get pod --kubeconfig=/tmp/myk8s.config    
NAME             READY   STATUS    RESTARTS   AGE
nginx-pod-demo   1/1     Running   1          44h
web-0            1/1     Running   2          2d21h
web-1            1/1     Running   2          2d21h
web-2            1/1     Running   2          2d21h
web-3            1/1     Running   3          2d21h
[root@master01 ~]# 

  提示:可以看到使用tom使用者的配置檔案,使用kubectl工具載入對應配置檔案,在default名稱空間下是可以正常列出pod列表;

  驗證:使用tom的配置檔案看看是否列出kube-system名稱空間下的pod列表呢?

[root@master01 ~]# kubectl get pod -n kube-system --kubeconfig=/tmp/myk8s.config 
Error from server (Forbidden): pods is forbidden: User "tom" cannot list resource "pods" in API group "" in the namespace "kube-system"
[root@master01 ~]# 

  提示:可以看到對應tom使用者是沒有許可權列出kube-system名稱空間下的pod資源;

  建立clusterrolebinding

  命令使用語法格式

Usage:
  kubectl create clusterrolebinding NAME --clusterrole=NAME [--user=username] [--group=groupname]
[--serviceaccount=namespace:serviceaccountname] [--dry-run=server|client|none] [options]

  提示:使用方式和建立rolebinding一樣,不同的是clusterrolebinding不能關聯role角色;

  示例:建立名為tom-all-pod-reader的clusterrolebinding,並關聯cluster-pods-reader角色和tom使用者;

[root@master01 ~]# kubectl create clusterrolebinding tom-all-pod-reader --clusterrole=cluster-pods-reader --user=tom
clusterrolebinding.rbac.authorization.k8s.io/tom-all-pod-reader created
[root@master01 ~]# kubectl get clusterrolebinding tom-all-pod-reader
NAME                 ROLE                              AGE
tom-all-pod-reader   ClusterRole/cluster-pods-reader   20s
[root@master01 ~]# kubectl describe clusterrolebinding tom-all-pod-reader
Name:         tom-all-pod-reader
Labels:       <none>
Annotations:  <none>
Role:
  Kind:  ClusterRole
  Name:  cluster-pods-reader
Subjects:
  Kind  Name  Namespace
  ----  ----  ---------
  User  tom   
[root@master01 ~]# 

  驗證:使用tom使用者配置檔案檢視kube-system名稱空間下的pod資源列表

[root@master01 ~]# kubectl get pod -n kube-system --kubeconfig=/tmp/myk8s.config 
NAME                                       READY   STATUS    RESTARTS   AGE
coredns-7f89b7bc75-k9gdt                   1/1     Running   18         23d
coredns-7f89b7bc75-kp855                   1/1     Running   16         23d
etcd-master01.k8s.org                      1/1     Running   22         23d
kube-apiserver-master01.k8s.org            1/1     Running   17         23d
kube-controller-manager-master01.k8s.org   1/1     Running   19         23d
kube-flannel-ds-cx8d5                      1/1     Running   20         23d
kube-flannel-ds-jz6r4                      1/1     Running   11         12d
kube-flannel-ds-ndzl6                      1/1     Running   21         23d
kube-flannel-ds-rjtn9                      1/1     Running   23         23d
kube-flannel-ds-zgq92                      1/1     Running   20         23d
kube-proxy-cr8j8                           1/1     Running   13         11d
kube-proxy-h8fzw                           1/1     Running   8          11d
kube-proxy-jfzfh                           1/1     Running   9          11d
kube-proxy-rq8wl                           1/1     Running   8          11d
kube-proxy-sj72v                           1/1     Running   8          11d
kube-scheduler-master01.k8s.org            1/1     Running   19         23d
[root@master01 ~]# kubectl get pod  --kubeconfig=/tmp/myk8s.config               
NAME             READY   STATUS    RESTARTS   AGE
nginx-pod-demo   1/1     Running   1          44h
web-0            1/1     Running   2          2d21h
web-1            1/1     Running   2          2d21h
web-2            1/1     Running   2          2d21h
web-3            1/1     Running   3          2d22h
[root@master01 ~]# kubectl get svc --kubeconfig=/tmp/myk8s.config
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   3d1h
nginx        ClusterIP   None         <none>        80/TCP    3d
[root@master01 ~]# kubectl get svc -n kube-system --kubeconfig=/tmp/myk8s.config
NAME       TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)                  AGE
kube-dns   ClusterIP   10.96.0.10   <none>        53/UDP,53/TCP,9153/TCP   23d
[root@master01 ~]# 

  提示:可以看到把tom使用者用clusterrolebinding關聯到對應clusterrole角色上,就擁有對應角色上的許可權;

  驗證:使用tom配置檔案檢視pv或node叢集級別資源,看看是否可以正常列出?

[root@master01 ~]# kubectl get pv --kubeconfig=/tmp/myk8s.config
Error from server (Forbidden): persistentvolumes is forbidden: User "tom" cannot list resource "persistentvolumes" in API group "" at the cluster scope
[root@master01 ~]# kubectl get node --kubeconfig=/tmp/myk8s.config
Error from server (Forbidden): nodes is forbidden: User "tom" cannot list resource "nodes" in API group "" at the cluster scope
[root@master01 ~]# 

  提示:使用tom使用者的配置檔案檢視pv和node資源,apiserver直接拒絕了;原因是對應的clusterrole角色上沒有檢視pv和node的許可權;所以對應使用者也就沒有相應的檢視許可權;

  示例:建立rolebinding,把tom使用者關聯到clusterrole型別角色cluster-pods-reader

[root@master01 ~]# kubectl create rolebinding tom-rolebinding-clusterrole --clusterrole=cluster-pods-reader --user=tom 
rolebinding.rbac.authorization.k8s.io/tom-rolebinding-clusterrole created
[root@master01 ~]# kubectl get rolebinding
NAME                          ROLE                              AGE
tom-pods-reader               Role/pod-reader                   20m
tom-rolebinding-clusterrole   ClusterRole/cluster-pods-reader   12s
[root@master01 ~]# kubectl describe rolebinding tom-rolebinding-clusterrole
Name:         tom-rolebinding-clusterrole
Labels:       <none>
Annotations:  <none>
Role:
  Kind:  ClusterRole
  Name:  cluster-pods-reader
Subjects:
  Kind  Name  Namespace
  ----  ----  ---------
  User  tom   
[root@master01 ~]# 

  驗證:使用tom配置檔案,看看現在tom使用者是否還有對應kube-system中的pod資源有列出許可權呢?

[root@master01 ~]# kubectl get pods -n kube-system --kubeconfig=/tmp/myk8s.config
NAME                                       READY   STATUS    RESTARTS   AGE
coredns-7f89b7bc75-k9gdt                   1/1     Running   18         23d
coredns-7f89b7bc75-kp855                   1/1     Running   16         23d
etcd-master01.k8s.org                      1/1     Running   22         23d
kube-apiserver-master01.k8s.org            1/1     Running   17         23d
kube-controller-manager-master01.k8s.org   1/1     Running   19         23d
kube-flannel-ds-cx8d5                      1/1     Running   20         23d
kube-flannel-ds-jz6r4                      1/1     Running   11         12d
kube-flannel-ds-ndzl6                      1/1     Running   21         23d
kube-flannel-ds-rjtn9                      1/1     Running   23         23d
kube-flannel-ds-zgq92                      1/1     Running   20         23d
kube-proxy-cr8j8                           1/1     Running   13         11d
kube-proxy-h8fzw                           1/1     Running   8          11d
kube-proxy-jfzfh                           1/1     Running   9          11d
kube-proxy-rq8wl                           1/1     Running   8          11d
kube-proxy-sj72v                           1/1     Running   8          11d
kube-scheduler-master01.k8s.org            1/1     Running   19         23d
[root@master01 ~]# 

  提示:這裡還是能夠列出kube-system名稱空間下的pod,其原因是我們沒有刪除之前的clusterrolebinding,所以對應tom使用者還有對kube-system的許可權;

  驗證:刪除clusterrolebinding tom-all-pod-reader 看看tom使用者是否還有對kube-system中的pod列出許可權呢?

[root@master01 ~]# kubectl get clusterrolebinding tom-all-pod-reader
NAME                 ROLE                              AGE
tom-all-pod-reader   ClusterRole/cluster-pods-reader   14m
[root@master01 ~]# kubectl delete clusterrolebinding tom-all-pod-reader
clusterrolebinding.rbac.authorization.k8s.io "tom-all-pod-reader" deleted
[root@master01 ~]# kubectl get rolebinding
NAME                          ROLE                              AGE
tom-pods-reader               Role/pod-reader                   27m
tom-rolebinding-clusterrole   ClusterRole/cluster-pods-reader   7m7s
[root@master01 ~]# kubectl get pods -n kube-system --kubeconfig=/tmp/myk8s.config
Error from server (Forbidden): pods is forbidden: User "tom" cannot list resource "pods" in API group "" in the namespace "kube-system"
[root@master01 ~]# 

  提示:可以看到此時tom使用者就沒有對kube-system名稱空間下的pod有列出許可權了;

  驗證:使用tom使用者配置檔案,檢視default名稱空間下的pods和service資源,看看是否有許可權?

[root@master01 ~]# kubectl get pods  --kubeconfig=/tmp/myk8s.config              
NAME             READY   STATUS    RESTARTS   AGE
nginx-pod-demo   1/1     Running   1          45h
web-0            1/1     Running   2          2d22h
web-1            1/1     Running   2          2d22h
web-2            1/1     Running   2          2d22h
web-3            1/1     Running   3          2d22h
[root@master01 ~]# kubectl get svc  --kubeconfig=/tmp/myk8s.config    
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   3d1h
nginx        ClusterIP   None         <none>        80/TCP    3d
[root@master01 ~]# 

  提示:可以看到tom使用者在default名稱空間下能夠正常列出pod和service資源;從上面的示例可以看到當rolebinding繫結的是一個clusterrole,對應clusterrole的許可權就會降低至對應rolebinding的名稱空間;

  使用資源清單建立角色

  示例:使用資源清單建立role-demo角色

[root@master01 ~]# cat role-demo.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: role-demo
  namespace: testing
rules:
- apiGroups: [""]
  resources: ["pods","pods/log","services"]
  verbs: ["get","list","watch"]
  
[root@master01 ~]# 

  提示:role資源沒有spec欄位,它的群組是rbac.authorization.k8s.io/v1,對應型別為Role;metadata欄位中的name用於指定對應role的名稱;namespace使用者指定對應的名稱空間;roles欄位用來描述對資源和許可權,該欄位為一個列表物件,一個物件必須有apiGroup,resources和verbs欄位;其中apiGroup欄位用來描述對應資源所屬群組,預設不寫任何群組表示核心群組v1;如果是匹配所有群組可以寫成“*”;該欄位是一個列表型別資料,所以必須用中括號將其括起來,即便沒有值;resources欄位用來描述對應的資源,這裡的資源如果可以使用複數形式的必須使用複數形式;所謂複數是指對應資源名稱單詞的複數形式;該欄位也是一個列表,可以使用中括號,也可以直接使用-開頭寫對應的值;verbs欄位用來描述對應的許可權,該欄位也是一個列表,可以使用中括號或者“-”開頭從下一行直接寫值的方式;上述資源清單表示建立一個名為role-demo的角色在testing名稱空間;對應角色擁有對該名稱空間下的pod,pods/log和services資源有get,list,watch許可權;

  建立名稱空間並應用配置清單

[root@master01 ~]# kubectl get ns
NAME              STATUS   AGE
default           Active   23d
ingress-nginx     Active   9d
kube-node-lease   Active   23d
kube-public       Active   23d
kube-system       Active   23d
[root@master01 ~]# kubectl create ns testing
namespace/testing created
[root@master01 ~]# kubectl apply -f role-demo.yaml
role.rbac.authorization.k8s.io/role-demo created
[root@master01 ~]# kubectl get role -n testing
NAME        CREATED AT
role-demo   2020-12-31T12:46:53Z
[root@master01 ~]# kubectl describe role role-demo -n testing
Name:         role-demo
Labels:       <none>
Annotations:  <none>
PolicyRule:
  Resources  Non-Resource URLs  Resource Names  Verbs
  ---------  -----------------  --------------  -----
  pods/log   []                 []              [get list watch]
  pods       []                 []              [get list watch]
  services   []                 []              [get list watch]
[root@master01 ~]# 

  示例:使用資源清單建立rolebinding

[root@master01 ~]# cat rolebinding-demo.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: rolebinding-demo
  namespace: testing
roleRef:
  kind: Role
  name: role-demo
  apiGroup: rbac.authorization.k8s.io
subjects:
- kind: User
  apiGroup: rbac.authorization.k8s.io
  name: tom
  
[root@master01 ~]# 

  提示:使用資源清單建立rolebinding,需要用roleRef欄位來指定引用的role或clusterrole,該欄位為一個物件,其中kind指定對應角色的型別,Role表示引用名稱空間級別的role;ClusterRole表示引用叢集級別角色clusterrole;apiGroup是用來描述對應角色的不帶版本api群組;subjects欄位用來描述對應使用者或組,該欄位為一個列表物件;其中kind欄位用來表示對應的是使用者還是使用者組;User表示使用者,Group表示使用者組;ServiceAccount表示是一個sa使用者;apiGroup用來指定對應不帶版本的api群組;name用來指定使用者名稱或組名或sa名;上述資源清單表示把tom使用者和role-demo角色做關聯,即授權tom使用者擁有role-demo角色的許可權;

  驗證:在未應用資源清單前使用tom使用者的配置檔案檢視testing名稱空間下的pod資源

[root@master01 ~]# kubectl get pods -n testing --kubeconfig=/tmp/myk8s.config
Error from server (Forbidden): pods is forbidden: User "tom" cannot list resource "pods" in API group "" in the namespace "testing"
[root@master01 ~]# 

  提示:在未應用上述資源清單,tom使用者對testing名稱空間的資源沒有任何許可權;

  應用資源清單

[root@master01 ~]# kubectl apply -f rolebinding-demo.yaml         
rolebinding.rbac.authorization.k8s.io/rolebinding-demo created
[root@master01 ~]# kubectl get rolebinding -n testing
NAME               ROLE             AGE
rolebinding-demo   Role/role-demo   31s
[root@master01 ~]# kubectl describe rolebinding rolebinding-demo -n testing
Name:         rolebinding-demo
Labels:       <none>
Annotations:  <none>
Role:
  Kind:  Role
  Name:  role-demo
Subjects:
  Kind  Name  Namespace
  ----  ----  ---------
  User  tom   
[root@master01 ~]# kubectl get pods -n testing --kubeconfig=/tmp/myk8s.config
No resources found in testing namespace.
[root@master01 ~]# 

  提示:可以看到應用資源清單以後,再次使用tom使用者的配置檔案檢視testing名稱空間下的pod資源,就沒有提示沒有許可權拒絕,只是告訴我們對應名稱空間下沒有pod資源;

  示例:使用資源清單建立clusterrole

[root@master01 ~]# cat clusterrole-demo.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: clusterrole-demo
rules:
- apiGroups: [""]
  resources: ["pods","nodes","PersistentVolume"]
  verbs: ["get","list","watch","create","delete"]
[root@master01 ~]# 

  提示:使用資源清單建立clusterrole和建立role是一樣的格式,不同的是對應kind的值不同,不需要指定名稱空間;其他的都一樣;

  應用資源清單

[root@master01 ~]# kubectl apply -f clusterrole-demo.yaml
clusterrole.rbac.authorization.k8s.io/clusterrole-demo created
[root@master01 ~]# kubectl get clusterrole clusterrole-demo
NAME               CREATED AT
clusterrole-demo   2020-12-31T13:23:48Z
[root@master01 ~]# kubectl describe clusterrole clusterrole-demo
Name:         clusterrole-demo
Labels:       <none>
Annotations:  <none>
PolicyRule:
  Resources         Non-Resource URLs  Resource Names  Verbs
  ---------         -----------------  --------------  -----
  PersistentVolume  []                 []              [get list watch create delete]
  nodes             []                 []              [get list watch create delete]
  pods              []                 []              [get list watch create delete]
[root@master01 ~]# 

  示例:使用資源清單建立clusterrolebinding

[root@master01 ~]# cat clusterrolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: clusterrolebinding-demo
roleRef:
  kind: ClusterRole
  name: clusterrole-demo
  apiGroup: rbac.authorization.k8s.io
subjects:
- kind: User
  apiGroup: rbac.authorization.k8s.io
  name: tom
  
[root@master01 ~]# 

  提示:使用資源清單建立clusterrolebinding和建立rolebinding的格式一樣,不同的是建立clusterrolebinding不需要指定名稱空間,對應kind值為ClusterRoleBinding;其他欄位的使用方式和role一樣;上述資源清單表示把tom使用者和clusterrole-demo角色做關聯;

  驗證:在沒有應用資源清單前使用tom配置檔案檢視kube-system名稱空間下的pod資源

[root@master01 ~]# kubectl get pods -n kube-system --kubeconfig=/tmp/myk8s.config
Error from server (Forbidden): pods is forbidden: User "tom" cannot list resource "pods" in API group "" in the namespace "kube-system"
[root@master01 ~]# 

  提示:沒有應用資源清單前使用tom使用者的配置檔案檢視kube-system名稱空間下的pod資源,是被apiserver拒絕的;

  應用配置清單

[root@master01 ~]# kubectl apply -f clusterrolebinding.yaml
clusterrolebinding.rbac.authorization.k8s.io/clusterrolebinding-demo created
[root@master01 ~]# kubectl get clusterrolebinding clusterrolebinding-demo
NAME                      ROLE                           AGE
clusterrolebinding-demo   ClusterRole/clusterrole-demo   15s
[root@master01 ~]# kubectl describe clusterrolebinding clusterrolebinding-demo
Name:         clusterrolebinding-demo
Labels:       <none>
Annotations:  <none>
Role:
  Kind:  ClusterRole
  Name:  clusterrole-demo
Subjects:
  Kind  Name  Namespace
  ----  ----  ---------
  User  tom   
[root@master01 ~]# kubectl get pods -n kube-system --kubeconfig=/tmp/myk8s.config           
NAME                                       READY   STATUS    RESTARTS   AGE
coredns-7f89b7bc75-k9gdt                   1/1     Running   18         23d
coredns-7f89b7bc75-kp855                   1/1     Running   16         23d
etcd-master01.k8s.org                      1/1     Running   22         23d
kube-apiserver-master01.k8s.org            1/1     Running   17         23d
kube-controller-manager-master01.k8s.org   1/1     Running   19         23d
kube-flannel-ds-cx8d5                      1/1     Running   20         23d
kube-flannel-ds-jz6r4                      1/1     Running   11         13d
kube-flannel-ds-ndzl6                      1/1     Running   21         23d
kube-flannel-ds-rjtn9                      1/1     Running   23         23d
kube-flannel-ds-zgq92                      1/1     Running   20         23d
kube-proxy-cr8j8                           1/1     Running   13         11d
kube-proxy-h8fzw                           1/1     Running   8          11d
kube-proxy-jfzfh                           1/1     Running   9          11d
kube-proxy-rq8wl                           1/1     Running   8          11d
kube-proxy-sj72v                           1/1     Running   8          11d
kube-scheduler-master01.k8s.org            1/1     Running   19         23d
[root@master01 ~]# 

  提示:可以看到應用資源清單以後,再使用tom使用者的配置檔案檢視kube-system名稱空間下的pod就可以正常列出了,說明對應tom使用者授權成功;

  檢視系統預設的clusterrole

[root@master01 ~]# kubectl get clusterrole
NAME                                                                   CREATED AT
admin                                                                  2020-12-08T06:39:13Z
cluster-admin                                                          2020-12-08T06:39:13Z
cluster-pods-reader                                                    2020-12-31T11:35:03Z
clusterrole-demo                                                       2020-12-31T13:23:48Z
edit                                                                   2020-12-08T06:39:13Z
flannel                                                                2020-12-08T06:59:56Z
kubeadm:get-nodes                                                      2020-12-08T06:39:15Z
nginx-ingress-clusterrole                                              2020-12-21T15:16:13Z
system:aggregate-to-admin                                              2020-12-08T06:39:13Z
system:aggregate-to-edit                                               2020-12-08T06:39:13Z
system:aggregate-to-view                                               2020-12-08T06:39:13Z
system:auth-delegator                                                  2020-12-08T06:39:13Z
system:basic-user                                                      2020-12-08T06:39:13Z
system:certificates.k8s.io:certificatesigningrequests:nodeclient       2020-12-08T06:39:13Z
system:certificates.k8s.io:certificatesigningrequests:selfnodeclient   2020-12-08T06:39:13Z
system:certificates.k8s.io:kube-apiserver-client-approver              2020-12-08T06:39:13Z
system:certificates.k8s.io:kube-apiserver-client-kubelet-approver      2020-12-08T06:39:13Z
system:certificates.k8s.io:kubelet-serving-approver                    2020-12-08T06:39:13Z
system:certificates.k8s.io:legacy-unknown-approver                     2020-12-08T06:39:13Z
system:controller:attachdetach-controller                              2020-12-08T06:39:13Z
system:controller:certificate-controller                               2020-12-08T06:39:13Z
system:controller:clusterrole-aggregation-controller                   2020-12-08T06:39:13Z
system:controller:cronjob-controller                                   2020-12-08T06:39:13Z
system:controller:daemon-set-controller                                2020-12-08T06:39:13Z
system:controller:deployment-controller                                2020-12-08T06:39:13Z
system:controller:disruption-controller                                2020-12-08T06:39:13Z
system:controller:endpoint-controller                                  2020-12-08T06:39:13Z
system:controller:endpointslice-controller                             2020-12-08T06:39:13Z
system:controller:endpointslicemirroring-controller                    2020-12-08T06:39:13Z
system:controller:expand-controller                                    2020-12-08T06:39:13Z
system:controller:generic-garbage-collector                            2020-12-08T06:39:13Z
system:controller:horizontal-pod-autoscaler                            2020-12-08T06:39:13Z
system:controller:job-controller                                       2020-12-08T06:39:13Z
system:controller:namespace-controller                                 2020-12-08T06:39:13Z
system:controller:node-controller                                      2020-12-08T06:39:13Z
system:controller:persistent-volume-binder                             2020-12-08T06:39:13Z
system:controller:pod-garbage-collector                                2020-12-08T06:39:13Z
system:controller:pv-protection-controller                             2020-12-08T06:39:13Z
system:controller:pvc-protection-controller                            2020-12-08T06:39:13Z
system:controller:replicaset-controller                                2020-12-08T06:39:13Z
system:controller:replication-controller                               2020-12-08T06:39:13Z
system:controller:resourcequota-controller                             2020-12-08T06:39:13Z
system:controller:root-ca-cert-publisher                               2020-12-08T06:39:13Z
system:controller:route-controller                                     2020-12-08T06:39:13Z
system:controller:service-account-controller                           2020-12-08T06:39:13Z
system:controller:service-controller                                   2020-12-08T06:39:13Z
system:controller:statefulset-controller                               2020-12-08T06:39:13Z
system:controller:ttl-controller                                       2020-12-08T06:39:13Z
system:coredns                                                         2020-12-08T06:39:15Z
system:discovery                                                       2020-12-08T06:39:13Z
system:heapster                                                        2020-12-08T06:39:13Z
system:kube-aggregator                                                 2020-12-08T06:39:13Z
system:kube-controller-manager                                         2020-12-08T06:39:13Z
system:kube-dns                                                        2020-12-08T06:39:13Z
system:kube-scheduler                                                  2020-12-08T06:39:13Z
system:kubelet-api-admin                                               2020-12-08T06:39:13Z
system:monitoring                                                      2020-12-08T06:39:13Z
system:node                                                            2020-12-08T06:39:13Z
system:node-bootstrapper                                               2020-12-08T06:39:13Z
system:node-problem-detector                                           2020-12-08T06:39:13Z
system:node-proxier                                                    2020-12-08T06:39:13Z
system:persistent-volume-provisioner                                   2020-12-08T06:39:13Z
system:public-info-viewer                                              2020-12-08T06:39:13Z
system:service-account-issuer-discovery                                2020-12-08T06:39:13Z
system:volume-scheduler                                                2020-12-08T06:39:13Z
view                                                                   2020-12-08T06:39:13Z
[root@master01 ~]# 

  提示:以system開頭的都是系統預設建立的clusterrole角色;這些角色都是用來給對應元件授權用的,比如,system:kube-dns就是用來給kube-dns這個pod在apiserver上驗證授權需要使用的角色;system:kube-controller-manager這個角色就是用來kube-controller-manager這個pod在apiserver上擁有的許可權;kube-controller-manager這個pod向apiserver驗證時,首先把對應的證書傳送給apiserver,apiserver通過識別對應證書中CN的名字來確定對應的使用者名稱;如果對應使用者名稱是system:kube-controller-manager,那麼對應kube-controller-manager這個pod就擁有對應該角色的所有許可權;如果我們手動部署的k8s叢集,對應controller-manager的證書中CN名稱不是system:kube-controller-manager,那麼我們手動部署的k8s叢集將不能正常工作,對於其他元件也是類似的邏輯;除了內建了以system開頭的很多clusterrole,k8s為了方便我們授權,它還內建了4個特殊的clusterrole,分別是cluster-admin,admin,edit和view;其中cluster-admin是擁有對整個叢集的所有資源擁有所有許可權,預設這個角色被clusterrolebinding繫結在system:master這個組上;對應kuberctl使用的證書檔案中O的資訊就是system:master,所以我們使用kubectl載入預設的配置檔案可以操作整個叢集上的所有資源;admin角色也是一個管理員許可權,不同於cluster-admin,admin角色一般用於通過rolebinding來實現對特有名稱空間的管理員授權;edit和view也是類似的邏輯,主要用於通過rolebinding來實現特有名稱空間下的特定管理員;比如快速授權某個使用者在某個名稱空間下擁有隻讀許可權,那麼我們就可以把對應使用者通過rolebinding將其繫結至view這個clusterrole角色上;如果只允許某個使用者擁有對應名稱空間下的所有資源的修改許可權,就可以把對應使用者通過rolebinding繫結到edit這個clusterrole角色上;當然以上幾個角色也可以通過clusterrolebinding來繫結,用clusterrolebinding來繫結,對應使用者就是對應整個叢集的所有資源;有了上述4個內建的clusterrole,我們就可以快速的將某個使用者授權為特定的角色:

  檢視kubectl預設證書中的資訊

  複製配置檔案中的client-certificate-data 對應的被base64編碼處理過的資訊,然後通過base64 -d將其解密,然後使用openssl x509  -text -noout 來檢視對應證書中的資訊

  提示:可以看到當前kubectl的證書中O=system:master CN=kubernetes-admin;之所以kubectl能夠管理叢集資源是因為對應證書中的O=system:master,該資訊直接對應k8s上的叢集角色cluster-admin;對應叢集角色就是通過clusterrolebinding繫結到system:master組;所以kubectl就擁有對k8s整個叢集資源的管控;

  示例:授權tom使用者為叢集管理員

[root@master01 ~]# cat tom-clusterrolebinding-cluster-admin.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: tom-cluster-admin
roleRef:
  kind: ClusterRole
  name: cluster-admin
  apiGroup: rbac.authorization.k8s.io
subjects:
- kind: User
  apiGroup: rbac.authorization.k8s.io
  name: tom
  
[root@master01 ~]# 

  提示:上述資源表示通過clusterrolebinding授權tom使用者擁有cluster-admin角色的所有許可權,即叢集管理員;

  應用資源清單

[root@master01 ~]# kubectl apply -f tom-clusterrolebinding-cluster-admin.yaml
clusterrolebinding.rbac.authorization.k8s.io/tom-cluster-admin created
[root@master01 ~]# kubectl get clusterrolebinding tom-cluster-admin
NAME                ROLE                        AGE
tom-cluster-admin   ClusterRole/cluster-admin   21s
[root@master01 ~]# kubectl describe clusterrolebinding tom-cluster-admin
Name:         tom-cluster-admin
Labels:       <none>
Annotations:  <none>
Role:
  Kind:  ClusterRole
  Name:  cluster-admin
Subjects:
  Kind  Name  Namespace
  ----  ----  ---------
  User  tom   
[root@master01 ~]# 

  驗證:使用tom使用者配置檔案,管理叢集資源

[root@master01 ~]# kubectl get all --kubeconfig=/tmp/myk8s.config
NAME                 READY   STATUS    RESTARTS   AGE
pod/nginx-pod-demo   1/1     Running   1          47h
pod/web-0            1/1     Running   2          3d
pod/web-1            1/1     Running   2          3d
pod/web-2            1/1     Running   2          3d
pod/web-3            1/1     Running   3          3d

NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   3d3h
service/nginx        ClusterIP   None         <none>        80/TCP    3d3h

NAME                   READY   AGE
statefulset.apps/web   4/4     3d3h
[root@master01 ~]# kubectl delete all --all  --kubeconfig=/tmp/myk8s.config
pod "nginx-pod-demo" deleted
pod "web-0" deleted
pod "web-1" deleted
pod "web-2" deleted
pod "web-3" deleted
service "kubernetes" deleted
service "nginx" deleted
statefulset.apps "web" deleted
[root@master01 ~]# kubectl apply -f statefulset-demo.yaml 
service/nginx created
statefulset.apps/web created
[root@master01 ~]# kubectl get all --kubeconfig=/tmp/myk8s.config          
NAME        READY   STATUS    RESTARTS   AGE
pod/web-0   1/1     Running   0          9s
pod/web-1   1/1     Running   0          6s
pod/web-2   1/1     Running   0          4s

NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   85s
service/nginx        ClusterIP   None         <none>        80/TCP    9s

NAME                   READY   AGE
statefulset.apps/web   3/3     9s
[root@master01 ~]# 

  提示:可以看到我們使用tom配置檔案和預設配置檔案是一樣的效果,瞬間tom使用者就變成了叢集管理;

  刪除tom-cluster-admin這個clusterrolebinding

[root@master01 ~]# kubectl delete -f tom-clusterrolebinding-cluster-admin.yaml 
clusterrolebinding.rbac.authorization.k8s.io "tom-cluster-admin" deleted
[root@master01 ~]# 

  授權tom使用者只讀ingress-nginx名稱空間下的所有資源擁有隻讀許可權

[root@master01 ~]# cat tom-ingress-nginx-view.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: tom-ingress-nginx-view
  namespace: ingress-nginx
roleRef:
  kind: ClusterRole
  name: view
  apiGroup: rbac.authorization.k8s.io
subjects:
- kind: User
  apiGroup: rbac.authorization.k8s.io
  name: tom
  
[root@master01 ~]# 

  提示:上述配置表示通過ingress-nginx名稱 空間下的rolebinding把tom使用者繫結至view這個clusterrole上;即對應tom使用者對ingress-nginx名稱空間下的所有資源只有只讀許可權;

  應用資源配置清單

[root@master01 ~]# kubectl apply -f tom-ingress-nginx-view.yaml
rolebinding.rbac.authorization.k8s.io/tom-ingress-nginx-view created
[root@master01 ~]# kubectl get rolebinding -n ingress-nginx
NAME                              ROLE                      AGE
nginx-ingress-role-nisa-binding   Role/nginx-ingress-role   9d
tom-ingress-nginx-view            ClusterRole/view          22s
[root@master01 ~]# kubectl describe rolebinding tom-ingress-nginx-view -n ingress-nginx
Name:         tom-ingress-nginx-view
Labels:       <none>
Annotations:  <none>
Role:
  Kind:  ClusterRole
  Name:  view
Subjects:
  Kind  Name  Namespace
  ----  ----  ---------
  User  tom   
[root@master01 ~]# 

  驗證:使用tom使用者配置檔案管理ingress-nginx名稱空間下的資源

[root@master01 ~]# kubectl get pods -n ingress-nginx --kubeconfig=/tmp/myk8s.config             
NAME                                        READY   STATUS    RESTARTS   AGE
nginx-ingress-controller-5466cb8999-dzn5d   1/1     Running   0          33s
[root@master01 ~]# kubectl get pods --kubeconfig=/tmp/myk8s.config
Error from server (Forbidden): pods is forbidden: User "tom" cannot list resource "pods" in API group "" in the namespace "default"
[root@master01 ~]# kubectl delete pod nginx-ingress-controller-5466cb8999-dzn5d -n ingress-nginx --kubeconfig=/tmp/myk8s.config
Error from server (Forbidden): pods "nginx-ingress-controller-5466cb8999-dzn5d" is forbidden: User "tom" cannot delete resource "pods" in API group "" in the namespace "ingress-nginx"
[root@master01 ~]#

  提示:可以看到現在tom使用者只能檢視ingress-nginx名稱空間下的資源,不能檢視default名稱空間下的資源,其次對ingress-nginx名稱空間下的pod資源沒有刪除許可權;

 

相關文章