【Kubernetes】基於角色的權限控制:RBAC


  Kubernetes中所有的API對象,都保存在Etcd里,對這些API對象的操作,一定都是通過訪問kube-apiserver實現的,原因是需要APIServer來做授權工作。

  在Kubernetes中,負責完成授權(Authorization)工作的機制,就是RBAC:基於角色的訪問控制(Role-Based Access Control)

  RBAC中有三個最基本的概念:

1、Role:角色,它其實是一組規則,定義了一組對Kubernetes API對象的操作權限

  Role本身是一個Kubernetes的API對象,定義如下所示:

kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: mynamespace  ## 指定它能產生作用的Namespace
  name: example-role
rules:    ##  定義權限規則
- apiGroups: [""]
  resources: ["pods"]  ## 對mynamespace下面的Pod對象
  verbs: ["get", "watch", "list"]   ## 進行GET、WATCH、LIST操作

 

2、Subject:被作用者,既可以是“人”,也可以是“機器”,也可以是Kubernetes里定義的“用戶”

3、RoleBinding:定義了“被作用者”和“角色”的綁定關系

  RoleBingding本身也是一個Kubernetes的API對象

kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: example-rolebinding
  namespace: mynamespace
subjects:   ## 被作用者
- kind: User     ## 類型是User
  name: example-user  ## 用戶名是example-user
  apiGroup: rbac.authorization.k8s.io
roleRef:
## 通過roleRef字段,RoleBinding對象可以直接通過名字來引用Role對象,從而定義了被作用者(Subject)和角色(Role)之間的關系
  kind: Role
  name: example-role
  apiGroup: rbac.authorization.k8s.io

  需要注意的是:Role和RoleBinding對象都是Namespaced對象,它們對權限限制規則僅在它們自己的Namespace內有效,roleRef也只能引用當前Namespace里的Role對象

  那對於非Namespaced對象(如: node)或者一個Role想作用於所有的Namespace的時候,又該如何去做授權呢?

  這個時候就必須要使用ClusterRole和ClusterRoleBinding這個組合了,這兩個API對象的用法跟Role和RoleBinding完全一樣,只不過它們的定義里沒有了Namespace字段

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: example-clusterrole
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "watch", "list"]


kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: example-clusterrolebinding
subjects:
- kind: User
  name: example-user
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: example-clusterrole
  apiGroup: rbac.authorization.k8s.io

 

   上面的例子里意味着名叫example-user的用戶擁有對所有Namespace里的Pod進行GET、WATCH和LIST操作的權限。

  如果想要賦予用戶所有權限,那可以給它指定一個verbs字段的全集

verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]

 

   Role對象的Rules字段也可以進一步細化,如可以只針對某一個具體的對象進行權限設置

rules:
- apiGroups: [""]
  resources: ["configmaps"]
  resourceNames: ["my-config"]
  verbs: ["get"]

 

 

  那現在還有一個問題,在Kubernetes中其實並沒有一個叫做“User”的API對象,那這個User從哪里來呢? 

  在Kubernetes的User只是一個授權系統里的邏輯概念,在大多數私有的使用環境中,只需要使用Kubernetes提供的內置“用戶”足夠了。負責管理內置用戶的是ServiceAccount

  首先定義一個ServiceAccount

apiVersion: v1
kind: ServiceAccount
metadata:
  namespace: mynamespace
  name: example-sa

  然后通過編寫RoleBinding的YAML文件,來為這個ServiceAccount分配權限

kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: example-rolebinding
  namespace: mynamespace
subjects:
- kind: ServiceAccount
  name: example-sa
  namespace: mynamespace
roleRef:
  kind: Role
  name: example-role
  apiGroup: rbac.authorization.k8s.io

 

  接着創建這個三個對象

$ kubectl create -f svc-account.yaml
$ kubectl create -f role-binding.yaml
$ kubectl create -f role.yaml


$ kubectl get sa -n mynamespace -o yaml
- apiVersion: v1
  kind: ServiceAccount
  metadata:
    creationTimestamp: 2018-09-08T12:59:17Z
    name: example-sa
    namespace: mynamespace
    resourceVersion: "409327"
    ...
  secrets:
  - name: example-sa-token-vmfg6

  可以看到,Kubernetes會為一個ServiceAccount自動創建並分配一個Secret對象。這個Secret就是ServiceAccount對應的、用來跟APIServer進行交互的授權文件,一般稱為Token。 Token文件的內容一般是證書或者密碼,它以一個Secret對象的方式保存在Etcd中。

  這時候,用戶的Pod就可以聲明使用這個ServiceAccount了

apiVersion: v1
kind: Pod
metadata:
  namespace: mynamespace
  name: sa-token-test
spec:
  containers:
  - name: nginx
    image: nginx:1.7.9
  serviceAccountName: example-sa



$ kubectl describe pod sa-token-test -n mynamespace
Name:               sa-token-test
Namespace:          mynamespace
...
Containers:
  nginx:
    ...
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from example-sa-token-vmfg6 (ro)

 

   如果一個Pod沒有聲明serviceAccountName,Kubernetes會自動在它的Namespace下創建一個名叫default的默認ServiceAccount,然后分配給這個Pod,這個默認的ServiceAccount並沒有關聯任何Role。

  除了 前面使用的User,Kubernetes還有用戶組(Group)的概念

  實際上一個ServiceAccount,在Kubernetes里對應的User的名字是:

system:serviceaccount:<ServiceAccount 名字 >

  那它對應的Group的名字就是

system:serviceaccounts:<Namespace 名字 >

  現在可以在RoleBinding里定義如下的subjects:

subjects:
- kind: Group
  name: system:serviceaccounts:mynamespace  ## Role權限規則作用於Namespace里所有的ServiceAccount
  apiGroup: rbac.authorization.k8s.io


subjects:
- kind: Group
  name: system:serviceaccounts  ## Role權限規則作用於整個系統里所有ServiceAccount
  apiGroup: rbac.authorization.k8s.io

 


免責聲明!

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



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