Kubernetes中全部的API對象,都保存在Etcd裏,對這些API對象的操做,必定都是經過訪問kube-apiserver實現的,緣由是須要APIServer來作受權工做。node
在Kubernetes中,負責完成受權(Authorization)工做的機制,就是RBAC:基於角色的訪問控制(Role-Based Access Control)nginx
RBAC中有三個最基本的概念:api
一、Role:角色,它實際上是一組規則,定義了一組對Kubernetes API對象的操做權限spa
Role自己是一個Kubernetes的API對象,定義以下所示:code
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操做
二、Subject:被做用者,既能夠是「人」,也能夠是「機器」,也能夠是Kubernetes裏定義的「用戶」server
三、RoleBinding:定義了「被做用者」和「角色」的綁定關係對象
RoleBingding自己也是一個Kubernetes的API對象blog
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對象token
那對於非Namespaced對象(如: node)或者一個Role想做用於全部的Namespace的時候,又該如何去作受權呢?get
這個時候就必需要使用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