kubernetes 1.6 RBAC訪問控制

1、簡介node

以前,Kubernetes中的受權策略主要是ABAC(Attribute-Based Access Control)。對於ABAC,Kubernetes在實現上是比較難用的,並且須要Master Node的SSH和根文件系統訪問權限,受權策略發生變化後還須要重啓API Server。git

Kubernetes 1.6中,RBAC(Role-Based Access Control)基於角色的訪問控制進入Beta階段。RBAC訪問控制策略可使用kubectl或Kubernetes API進行配置。使用RBAC能夠直接受權給用戶,讓用戶擁有受權管理的權限,這樣就再也不須要直接觸碰Master Node。在Kubernetes中RBAC被映射成API資源和操做。github

 

2、RBAC API的資源對象bootstrap

在Kubernetes 1.6中經過啓動參數--authorization-mode=RBAC.API Overview爲API Server啓用RBAC。api

使用kubeadm初始化的1.6版本的Kubernetes集羣,已經默認爲API Server開啓了RBAC,能夠查看Master Node上API Server的靜態Pod定義文件,若是- apiserver底下沒有看到安全

若是沒有下面紅色的信息,說明沒有啓用RBAC服務器

- apiserver
- --bind-address=0.0.0.0
- --secure-port=443
- --insecure-bind-address=0.0.0.0
- --insecure-port=8080
- --allow-privileged=true
- --service-cluster-ip-range=10.3.0.0/24
- --advertise-address=172.16.71.200
- --cors-allowed-origins=.*
- --admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,ResourceQuota
- --tls-cert-file=/etc/kubernetes/ssl/apiserver.pem
- --tls-private-key-file=/etc/kubernetes/ssl/apiserver-key.pem
- --client-ca-file=/etc/kubernetes/ssl/ca.pem
- --service-account-key-file=/etc/kubernetes/ssl/apiserver-key.pem
- --v=3
- --etcd-servers=http://172.16.71.200:2379,http://172.16.71.201:2379,http://172.16.71.202:2379,http://172.16.71.203:2379架構

- --authorization-mode=RBACapp

 

RBAC API定義了四個資源對象用於描述RBAC中用戶和資源之間的鏈接權限:cors

  • Role
  • ClusterRole
  • RoleBinding
  • ClusterRoleBinding

一、Role和ClusterRole

在RBAC API中,Role包含表示一組權限的規則。 權限是純粹的加法(沒有「否認」規則)。 一個Role能夠在一個namespace中用一個角色來定義,也可使用ClusterRole在羣集範圍內定義。

Role只能用於授予對單個namespace中資源的訪問權限。 如下是「default」命名空間中可用於授予對pod的讀訪問權限的示例:

kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  namespace: default
  name: pod-reader
rules:
- apiGroups: [""] # "" indicates the core API group
  resources: ["pods"]
  verbs: ["get", "watch", "list"]

ClusterRole可用於授予與Role相同的權限,但因爲它們是集羣範圍的,所以也可使用它們來授予對如下內容的訪問權限:

 

  • 集羣範圍的資源(如nodes)
  • 非資源端點(如「/ healthz」)
  • 在全部namespace中的資源(如pod)(例如:kubectl get pods --all-namespaces)

 

如下ClusterRole可用於授予對任何特定namespace或全部namespace中的secrets 的讀取訪問(取決於其綁定方式):

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  # "namespace" omitted since ClusterRoles are not namespaced
  name: secret-reader
rules:
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get", "watch", "list"]

二、RoleBinding和ClusterRoleBinding

RoleBinding把Role綁定到帳戶主體Subject(users, groups, or service accounts),讓Subject繼承Role所在namespace下的權限。ClusterRoleBinding把ClusterRole綁定到Subject,讓Subject集成ClusterRole在整個集羣中的權限。

如下RoleBinding將「pod-reader」角色授予「默認」命名空間中的用戶「hzb」。 這容許「hzb」在「默認」命名空間中讀取pod。

# This role binding allows "jane" to read pods in the "default" namespace.
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: read-pods
  namespace: default
subjects:
- kind: User
  name: hzb
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

RoleBinding還能夠引用ClusterRole來授予RoleBinding命名空間中ClusterRole中定義的命名空間資源的權限。 這容許管理員爲整個集羣定義一組通用角色,而後在多個命名空間中重用它們。也就是說,ClusterRole一旦被RoleBinding到某一個namespace中,它只能訪問該namesapce中的資源。

例如,即便如下RoleBinding引用了ClusterRole,「hzb」只能在「development」這個namespace(RoleBinding的命名空間)中讀取secrets 。

# This role binding allows "dave" to read secrets in the "development" namespace.
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: read-secrets
  namespace: development # This only grants permissions within the "development" namespace.
subjects:
- kind: User
  name: hzb
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: secret-reader
  apiGroup: rbac.authorization.k8s.io

ClusterRoleBinding能夠用於在集羣級別和全部namespace中授予權限。 如下ClusterRoleBinding容許組「manager」中的任何用戶在任何namespace中讀取secrets 。

kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: read-secrets-global
subjects:
- kind: Group
  name: manager
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: secret-reader
  apiGroup: rbac.authorization.k8s.io

三、子資源權限

大多數資源由其名稱的字符串表示形式表示,例如「pod」,就像它出如今相關API端點的URL中同樣。 然而,一些Kubernetes API涉及「子資源」,例如pod的日誌。 pod的日誌端點的URL是:

GET /api/v1/namespaces/{namespace}/pods/{name}/log

在這種狀況下,「pod」是namespace資源,「log」是pod的子資源。 要在RBAC角色中表示此角色,請使用/來劃分資源和子資源。 要容許主題讀取pod和pod日誌,請寫:

kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  namespace: default
  name: pod-and-pod-logs-reader
rules:
- apiGroups: [""]
  resources: ["pods", "pods/log"]
  verbs: ["get", "list"]

四、資源名稱引用

Role權限的資源也能夠是某必定義好的資源的名稱引用,須要在resourceNames中指定名稱。 好比限制一個主題只能「獲取」和「更新」一個configmap(這個configmap是用戶本身定義的一個資源名稱),您能夠寫:

kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  namespace: default
  name: configmap-updater
rules:
- apiGroups: [""]
  resources: ["configmap"]
  resourceNames: ["my-configmap"]
  verbs: ["update", "get"]

值得注意的是,若是設置了resourceName,那麼以上的verbs不能是list,watch,create或deletecollection。 

五、Role舉例

如下示例中僅顯示了規則部分。

容許讀取核心API組中的資源「pod」:

rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list", "watch"]

容許在「extensions」和「apps」API組中讀/寫「deployments」:

rules:
- apiGroups: ["extensions", "apps"]
  resources: ["deployments"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]

容許讀「pod」和閱讀/寫「jobs」:

rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list", "watch"]
- apiGroups: ["batch", "extensions"]
  resources: ["jobs"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]

容許讀取名爲「my-config」的ConfigMap(必須使用RoleBinding綁定才能限制在單個namespace中的單個ConfigMap):

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

容許讀取核心組中的資源「nodes」(由於nodes是集羣範圍的,必須是ClusterRole用ClusterRoleBinding綁定纔有效):

rules:
- apiGroups: [""]
  resources: ["nodes"]
  verbs: ["get", "list", "watch"]

容許「GET」和「POST」請求到非資源端點「/ healthz」和全部子路徑(必須是ClusterRole用ClusterRoleBinding綁定纔有效):

rules:
- nonResourceURLs: ["/healthz", "/healthz/*"] # '*' in a nonResourceURL is a suffix glob match
  verbs: ["get", "post"]

六、給Subjects受權

RoleBinding或ClusterRoleBinding將角色綁定到subjectssubjects能夠是 groups, users or service accounts。

Subjects 中 Users 使用字符串表示,它能夠是一個普通的名字字符串,如 「alice」;也能夠是 email 格式的郵箱地址,如 「bob@example.com」;甚至是一組字符串形式的數字 ID。Users 的格式必須知足集羣管理員配置的 驗證模塊 ,RBAC 受權系統中沒有對其作任何格式限定; 可是 Users 的前綴 system: 是系統保留的,集羣管理員應該確保普通用戶不會使用這個前綴格式

Kubernetes中的groups目前由Authenticator模塊提供。 groups表示爲字符串,該字符串沒有格式要求,除了前綴system:被保留。

service accounts具備前綴爲system:serviceaccount:用戶名,屬於前綴爲system:serviceaccount:的組

RoleBinding舉例:

如下示例中僅顯示了RoleBinding的subjects部分。對於名爲「hzb@test.com」的用戶:

subjects:
- kind: User
  name: "alice@example.com"
  apiGroup: rbac.authorization.k8s.io

給一個名爲frontend-admins的組

subjects:
- kind: Group
  name: "frontend-admins"
  apiGroup: rbac.authorization.k8s.io

對於kube-system命名空間中的默認服務賬戶:

subjects:
- kind: ServiceAccount
  name: default
  namespace: kube-system

對於「qa」命名空間中的全部服務賬戶:

subjects:
- kind: Group
  name: system:serviceaccounts:qa
  apiGroup: rbac.authorization.k8s.io

對於任何的 service accounts:

subjects:
- kind: Group
  name: system:serviceaccounts
  apiGroup: rbac.authorization.k8s.io

對於全部 authenticated users (version 1.5+):

subjects:
- kind: Group
  name: system:authenticated
  apiGroup: rbac.authorization.k8s.io

對於全部 unauthenticated users (version 1.5+):

subjects:
- kind: Group
  name: system:unauthenticated
  apiGroup: rbac.authorization.k8s.io

對於全部users (version 1.5+):

subjects:
- kind: Group
  name: system:authenticated
  apiGroup: rbac.authorization.k8s.io
- kind: Group
  name: system:unauthenticated
  apiGroup: rbac.authorization.k8s.io

 

3、默認的Roles and Role Bindings

API  servers 建立一組默認的ClusterRole和ClusterRoleBinding對象。 其中許可能是system:前綴,表示資源由基礎架構「擁有」。 對這些資源的修改可能致使集羣異常。 一個例子是system:node。 此角色定義了kubelet的權限。 若是角色被修改,它可能使kubelets沒法工做。

全部的 cluster roles and rolebindings 被label標記爲:

kubernetes.io/bootstrapping=rbac-defaults

API Server 在每次啓動後都會更新已經丟失的默認 ClusterRole 和 其綁定的相關 Subjects;這將容許集羣自動修復由於意外更改致使的 RBAC 受權錯誤,同時可以使在升級集羣后基礎設施的 RBAC 受權得以自動更新。

若是想要關閉 API Server 的自動修復功能,只須要將默認建立的 ClusterRole 和其 RoleBind 的 rbac.authorization.kubernetes.io/autoupdate 註解設置爲 false 便可,這樣作會有很大風險致使集羣由於意外修改 RBAC 而沒法工做

Auto-reconciliation 在 1.6+ 版本被默認啓用(當 RBAC 受權被激活時)

Discovery Roles

默認ClusterRole 默認ClusterRoleBinding 描述
system:basic-user system:authenticated and system:unauthenticatedgroups 容許用戶只讀訪問有關本身的基本信息。
system:discovery system:authenticated and system:unauthenticatedgroups 容許只讀訪問API發現端點,以發現和協商API級別。

User-facing Roles

一些默認角色不是system:前綴。 這些是面向用戶的角色。 它們包括超級用戶角色(cluster-admin),旨在使用ClusterRoleBindings(cluster-status)授予集羣範圍的角色,以及旨在使用RoleBindings(admin,edit,view)在特定命名空間中授予的角色。

默認ClusterRole 默認ClusterRoleBinding 描述
cluster-admin system:masters group

容許超級用戶訪問對任何資源執行任何操做。若是使用的是ClusterRoleBinding,它能夠徹底控制集羣和全部命名空間中的每一個資源,

當在RoleBinding中使用時,它能夠徹底控制rolebinding的命名空間中的每一個資源,包括命名空間自己。

admin none

容許管理員訪問,旨在使用RoleBinding授予對命名空間的訪問。 若是在RoleBinding中使用,則容許對命名空間中大多數資源進行讀/寫訪問,

包括在命名空間中建立角色和角色綁定的功能。 它不容許對資源配額或命名空間自己的寫訪問。

edit none 容許對命名空間中大多數對象的讀/寫訪問。 它不容許查看或修改Role或RoleBinding。
view none 容許只讀訪問查看命名空間中的大多數對象。 它不容許查看或修改Role或RoleBinding。 它不容許查看secrets。

Core Component Roles

默認ClusterRole 默認ClusterRoleBinding 描述
system:kube-scheduler system:kube-scheduler user 容許訪問kube-scheduler組件所需的資源。
system:kube-controller-manager system:kube-controller-manager user 容許訪問kube-controller-manager組件所需的資源。 控制器角色中包含單個控制循環所需的權限。
system:node system:nodes group (deprecated in 1.7) 容許訪問kubelet組件所需的資源,包括對全部secrets的讀取訪問權限,以及對全部pod的訪問權限。 從1.7開始,建議使用[Node Authorizer](/ docs / admin / authorization / node /)和[NodeRestriction admission plugin](/docs/admin/admission-controllers#NodeRestriction)而不是此角色,並容許基於計劃在其上運行的pod的API訪問kubelets。 從1.7開始,當啓用「Node」受權模式時,不會自動綁定到「system:nodes」組
system:node-proxier system:kube-proxy user 容許訪問kube-proxy組件所需的資源

Other Component Roles

默認ClusterRole 默認ClusterRoleBinding 描述
system:auth-delegator none 容許委託認證和受權檢查。 這一般由附加API服務器用於統一認證和受權。
system:heapster none Heapster組件的角色
system:kube-aggregator none kube-aggregator組件的角色。
system:kube-dns kube-dns service account in the kube-system namespace kube-dns組件的角色
system:node-bootstrapper none 容許訪問執行Kubelet TLS自舉所需的資源。
system:node-problem-detector none node-problem-detector組件的角色
system:persistent-volume-provisioner none 容許訪問大多數動態卷配置所需的資源

Controller Roles

Kubernetes控制器管理器運行核心控制環路。 當使用--use-service-account-credentials調用時,每一個控制循環都將使用單獨的服務賬戶啓動。 對於每一個控制循環,存在相應的角色,前綴爲system:controller:。 若是控制器管理器未啓動--use-service-account-credentials,它將使用其本身的憑證運行全部控制循環,這些憑證必須被授予全部相關的角色。 這些角色包括:

  • system:controller:attachdetach-controller
  • system:controller:certificate-controller
  • system:controller:cronjob-controller
  • system:controller:daemon-set-controller
  • system:controller:deployment-controller
  • system:controller:disruption-controller
  • system:controller:endpoint-controller
  • system:controller:generic-garbage-collector
  • system:controller:horizontal-pod-autoscaler
  • system:controller:job-controller
  • system:controller:namespace-controller
  • system:controller:node-controller
  • system:controller:persistent-volume-binder
  • system:controller:pod-garbage-collector
  • system:controller:replicaset-controller
  • system:controller:replication-controller
  • system:controller:resourcequota-controller
  • system:controller:route-controller
  • system:controller:service-account-controller
  • system:controller:service-controller
  • system:controller:statefulset-controller
  • system:controller:ttl-controller

 

4、特權升級預防和引導

      RBAC API阻止用戶經過編輯角色或角色綁定來升級權限。 由於這是在API級別實現的,因此即便RBAC受權器沒有被使用也是如此。

      用戶即便在對某個 Role 擁有所有權限的狀況下也僅能在其做用範圍內(ClusterRole -> 集羣範圍內,Role -> 當前 namespace 或 集羣範圍)對其進行 create 和 update 操做;

      例如 「user-1」 用戶不具備在集羣範圍內列出 secrets 的權限,那麼他也沒法在集羣範圍內建立具備該權限的 ClusterRole,也就是說想傳遞權限必須先得到該權限;

       想要容許用戶 cretae/update Role 有兩種方式:

  • 授予一個該用戶指望 create/update 的 Role 或者 ClusterRole
  • 授予一個包含該用戶指望 create/update 的 Role 或者 ClusterRole 的 Role 或者 ClusterRole(有點繞…);若是用戶嘗試 crate/update 一個其不擁有的 Role 或者 ClusterRole,則 API 會禁止。 若是他們嘗試建立或修改一個Role或ClusterRole的權限,他們本身尚未被受權,API請求將被禁止。

若是用戶想要建立/更新role binding,那麼用戶必須已經具備包含在引用角色中的全部權限(與角色綁定相同的範圍),或者若是已被賦予權限來執行role binding的verb,若是「user-1」沒法在羣集範圍內列出secrets,則不能向授予該權限的角色建立ClusterRoleBinding。

容許用戶建立/更新角色綁定:

  • 授予他們一個角色,容許他們根據須要建立/更新RoleBinding或ClusterRoleBinding對象。
  • 授予他們綁定特定角色所需的權限:

 

  1. 隱含地,經過給他們角色中包含的權限。
  2. 明確地說,經過授予他們在特定角色(或羣集角色)上執行綁定動詞的權限。

 

例如,此集羣角色和角色綁定將容許「user-1」授予其餘用戶在「user-1-namespace」命名空間中的管理,編輯和查看角色:

apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
  name: role-grantor
rules:
- apiGroups: ["rbac.authorization.k8s.io"]
  resources: ["rolebindings"]
  verbs: ["create"]
- apiGroups: ["rbac.authorization.k8s.io"]
  resources: ["clusterroles"]
  verbs: ["bind"]
  resourceNames: ["admin","edit","view"]
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding
metadata:
  name: role-grantor-binding
  namespace: user-1-namespace
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: role-grantor
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: User
  name: user-1

 

       當使用 bootstrapping 時,初始用戶尚沒有訪問 API 的權限,此時想要授予他們一些還沒有擁有的權限是不可能的,此時能夠有兩種解決方案:

  • 使用具備system:masters group的credential ,該credential是經過默認綁定綁定到cluster-admin超級用戶角色。
  • 若是您的API服務器在啓用了不安全端口(--insecure-port)的狀況下運行,那麼還能夠經過該端口進行API調用,不會強制執行身份驗證或受權

5、RBAC命令行工具

存在兩個kubectl命令來在命名空間或整個集羣中授予角色

kubectl create rolebinding

kubectl create rolebinding bob-admin-binding --clusterrole=admin --user=bob --namespace=acme
kubectl create rolebinding myapp-view-binding --clusterrole=view --serviceaccount=acme:myapp --namespace=acme

kubectl create clusterrolebinding

kubectl create clusterrolebinding root-cluster-admin-binding --clusterrole=cluster-admin --user=root
kubectl create clusterrolebinding kubelet-node-binding --clusterrole=system:node --user=kubelet
kubectl create clusterrolebinding myapp-view-binding --clusterrole=view --serviceaccount=acme:myapp

 

6、Service Account Permissions

Service Account概念的引入是基於這樣的使用場景:運行在pod裏的進程須要調用Kubernetes API以及非Kubernetes API的其它服務。Service Account它並非給kubernetes集羣的用戶使用的,而是給pod裏面的進程使用的,它爲pod提供必要的身份認證。

默認RBAC策略向 control-plane components, nodes, and controllers授予範圍限制的權限,但不向「kube-system」命名空間以外的service accounts授予權限(超出發給全部已驗證用戶的發現權限)。這容許您根據須要向特定服務賬戶授予特定角色。 細粒度角色綁定提供更大的安全性,但須要更多的努力來管理。 更普遍的受權能夠給service accounts提供沒必要要的(可能升級的)API訪問,可是更容易管理。

從最安全到最不安全的的方式以下:

  • 爲應用程序特定的服務賬戶(最佳實踐)授予角色:這要求應用程序在其pod的spec中指定serviceAccountName,而且要建立 service account 。例如,將「my-namespace」中的只讀權限授予「my-sa」服務賬戶:

         

kubectl create rolebinding my-sa-view --clusterrole=view --serviceaccount=my-namespace:my-sa --namespace=my-namespace
  • 在命名空間中爲「默認」 service account 授予角色:若是應用程序沒有指定serviceAccountName,它將使用「默認」service account。注意:授予「默認」服務賬戶的權限可用於命名空間中未指定serviceAccountName的任何pod。

         例如,將「my-namespace」中的只讀權限授予「默認」service account:

kubectl create rolebinding default-view --clusterrole=view  --serviceaccount=my-namespace:default  --namespace=my-namespace

許多加載項當前做爲「kube-system」命名空間中的「默認」service account運行。 要容許這些加載項使用超級用戶訪問權限,請將cluster-admin權限授予「kube-system」命名空間中的「默認」服務賬戶。注意:啓用這意味着「kube-system」命名空間包含授予超級用戶訪問API的權限。

kubectl create clusterrolebinding add-on-cluster-admin --clusterrole=cluster-admin --serviceaccount=kube-system:default
  • 爲命名空間中的全部service accounts授予角色:若是但願命名空間中的全部應用程序都具備該角色,不管使用什麼service accounts,能夠將該角色授予該命名空間的service account group 。例如,將「my-namespace」中的只讀權限授予該命名空間中的全部service accounts:
kubectl create rolebinding serviceaccounts-view --clusterrole=view --group=system:serviceaccounts:my-namespace--namespace=my-namespace
  • 對集羣範圍內的全部service accounts(不鼓勵)授予有限的權限:若是您不想管理每一個命名空間的權限,則能夠將羣集範圍角色授予全部service accounts。例如,將全部命名空間中的只讀權限授予羣集中的全部service accounts:
kubectl create clusterrolebinding serviceaccounts-view --clusterrole=view --group=system:serviceaccounts
  • 授予超級用戶訪問羣集範圍內的全部service accounts(強烈不鼓勵):若是您根本不關心分區權限,則能夠向全部service accounts授予超級用戶訪問權限。警告:這容許任何具備讀取訪問權限的用戶訪問secrets或可以建立一個pod以訪問超級用戶credentials。
kubectl create clusterrolebinding serviceaccounts-cluster-admin --clusterrole=cluster-admin --group=system:serviceaccounts
相關文章
相關標籤/搜索