【Kubernetes】基于角色的权限控制:RBAC

  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
相关文章
相关标签/搜索