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
在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相同的權限,但因爲它們是集羣範圍的,所以也可使用它們來授予對如下內容的訪問權限:
如下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把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。
如下示例中僅顯示了規則部分。
容許讀取核心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"]
RoleBinding或ClusterRoleBinding將角色綁定到subjects。 subjects能夠是 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的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 受權被激活時)
默認ClusterRole | 默認ClusterRoleBinding | 描述 |
system:basic-user | system:authenticated and system:unauthenticatedgroups | 容許用戶只讀訪問有關本身的基本信息。 |
system:discovery | system:authenticated and system:unauthenticatedgroups | 容許只讀訪問API發現端點,以發現和協商API級別。 |
一些默認角色不是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。 |
默認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組件所需的資源 |
Kubernetes控制器管理器運行核心控制環路。 當使用--use-service-account-credentials調用時,每一個控制循環都將使用單獨的服務賬戶啓動。 對於每一個控制循環,存在相應的角色,前綴爲system:controller:。 若是控制器管理器未啓動--use-service-account-credentials,它將使用其本身的憑證運行全部控制循環,這些憑證必須被授予全部相關的角色。 這些角色包括:
4、特權升級預防和引導
RBAC API阻止用戶經過編輯角色或角色綁定來升級權限。 由於這是在API級別實現的,因此即便RBAC受權器沒有被使用也是如此。
用戶即便在對某個 Role 擁有所有權限的狀況下也僅能在其做用範圍內(ClusterRole -> 集羣範圍內,Role -> 當前 namespace 或 集羣範圍)對其進行 create 和 update 操做;
例如 「user-1」 用戶不具備在集羣範圍內列出 secrets 的權限,那麼他也沒法在集羣範圍內建立具備該權限的 ClusterRole,也就是說想傳遞權限必須先得到該權限;
想要容許用戶 cretae/update Role 有兩種方式:
若是用戶想要建立/更新role binding,那麼用戶必須已經具備包含在引用角色中的全部權限(與角色綁定相同的範圍),或者若是已被賦予權限來執行role binding的verb,若是「user-1」沒法在羣集範圍內列出secrets,則不能向授予該權限的角色建立ClusterRoleBinding。
容許用戶建立/更新角色綁定:
例如,此集羣角色和角色綁定將容許「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 的權限,此時想要授予他們一些還沒有擁有的權限是不可能的,此時能夠有兩種解決方案:
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
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訪問,可是更容易管理。
從最安全到最不安全的的方式以下:
kubectl create rolebinding my-sa-view --clusterrole=view --serviceaccount=my-namespace:my-sa --namespace=my-namespace
例如,將「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
kubectl create rolebinding serviceaccounts-view --clusterrole=view --group=system:serviceaccounts:my-namespace--namespace=my-namespace
kubectl create clusterrolebinding serviceaccounts-view --clusterrole=view --group=system:serviceaccounts
kubectl create clusterrolebinding serviceaccounts-cluster-admin --clusterrole=cluster-admin --group=system:serviceaccounts