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