RBAC
使用rbac.authorization.k8s.io
API Group 来实现受权决策,容许管理员经过 Kubernetes API 动态配置策略,要启用RBAC
,须要在 apiserver 中添加参数--authorization-mode=RBAC
,若是使用的kubeadm
安装的集群,1.6 版本以上的都默认开启了RBAC
,能够经过查看 Master 节点上 apiserver 的静态Pod
定义文件:shell
$ cat /etc/kubernetes/manifests/kube-apiserver.yaml ... - --authorization-mode=Node,RBAC ...
若是是二进制的方式搭建的集群,添加这个参数事后,记得要重启 apiserver 服务。json
Kubernetes
有一个很基本的特性就是它的全部资源对象都是模型化的 API 对象,容许执行 CRUD(Create、Read、Update、Delete)操做(也就是咱们常说的增、删、改、查操做),好比下面的这下资源:api
上面这些资源对象的可能存在的操做有:app
在更上层,这些资源和 API Group 进行关联,好比Pods
属于 Core API Group,而Deployements
属于 apps API Group,要在Kubernetes
中进行RBAC
的管理,除了上面的这些资源和操做之外,咱们还须要另外的一些对象:工具
Kubernetes
中都被定义为集群内部的 API 资源,和咱们前面学习过的 Pod、ConfigMap 这些相似,都是咱们集群的资源对象,因此一样的可使用咱们前面的kubectl
相关的命令来进行操做Subject:主题,对应在集群中尝试操做的对象,集群中定义了3种类型的主题资源:学习
Kubernetes
API 来管理的一些用户账号,和 namespace 进行关联的,适用于集群内部运行的应用程序,须要经过 API 来完成权限认证,因此在集群内部进行权限操做,咱们都须要使用到 ServiceAccount,这也是咱们这节课的重点RoleBinding 和 ClusterRoleBinding:角色绑定和集群角色绑定,简单来讲就是把声明的 Subject 和咱们的 Role 进行绑定的过程(给某个用户绑定上操做的权限),两者的区别也是做用范围的区别:RoleBinding 只会影响到当前 namespace 下面的资源操做权限,而 ClusterRoleBinding 会影响到全部的 namespace。测试
接下来咱们来经过几个示例来演示下RBAC
的配置方法。jsonp
咱们来建立一个 User Account,只能访问 kube-system 这个命名空间:spa
咱们前面已经提到过,Kubernetes
没有 User Account 的 API 对象,不过要建立一个用户账号的话也是挺简单的,利用管理员分配给你的一个私钥就能够建立了,这个咱们能够参考官方文档中的方法,这里咱们来使用OpenSSL
证书来建立一个 User,固然咱们也可使用更简单的cfssl
工具来建立:code
给用户 haimaxy 建立一个私钥,命名成:haimaxy.key:
$ openssl genrsa -out haimaxy.key 2048
使用咱们刚刚建立的私钥建立一个证书签名请求文件:haimaxy.csr,要注意须要确保在-subj
参数中指定用户名和组(CN表示用户名,O表示组):
$ openssl req -new -key haimaxy.key -out haimaxy.csr -subj "/CN=haimaxy/O=youdianzhis"
而后找到咱们的Kubernetes
集群的CA
,咱们使用的是kubeadm
安装的集群,CA
相关证书位于/etc/kubernetes/pki/
目录下面,若是你是二进制方式搭建的,你应该在最开始搭建集群的时候就已经指定好了CA
的目录,咱们会利用该目录下面的ca.crt
和ca.key
两个文件来批准上面的证书请求
生成最终的证书文件,咱们这里设置证书的有效期为500天:
$ openssl x509 -req -in haimaxy.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -out haimaxy.crt -days 500
如今查看咱们当前文件夹下面是否生成了一个证书文件:
$ ls haimaxy.csr haimaxy.key haimaxy.crt
如今咱们可使用刚刚建立的证书文件和私钥文件在集群中建立新的凭证和上下文(Context):
$ kubectl config set-credentials haimaxy --client-certificate=haimaxy.crt --client-key=haimaxy.key
咱们能够看到一个用户haimaxy
建立了,而后为这个用户设置新的 Context:
$ kubectl config set-context haimaxy-context --cluster=kubernetes --namespace=kube-system --user=haimaxy
到这里,咱们的用户haimaxy
就已经建立成功了,如今咱们使用当前的这个配置文件来操做kubectl
命令的时候,应该会出现错误,由于咱们尚未为该用户定义任何操做的权限呢:
$ kubectl get pods --context=haimaxy-context Error from server (Forbidden): pods is forbidden: User "haimaxy" cannot list pods in the namespace "default"
用户建立完成后,接下来就须要给该用户添加操做权限,咱们来定义一个YAML
文件,建立一个容许用户操做 Deployment、Pod、ReplicaSets 的角色,以下定义:(haimaxy-role.yaml)
apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: haimaxy-role namespace: kube-system rules: - apiGroups: ["", "extensions", "apps"] resources: ["deployments", "replicasets", "pods"] verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] # 也可使用['*']
其中Pod
属于 core 这个 API Group,在YAML
中用空字符就能够,而Deployment
属于 apps 这个 API Group,ReplicaSets
属于extensions
这个 API Group(我怎么知道的?点这里查文档),因此 rules 下面的 apiGroups 就综合了这几个资源的 API Group:["", "extensions", "apps"],其中verbs
就是咱们上面提到的能够对这些资源对象执行的操做,咱们这里须要全部的操做方法,因此咱们也可使用['*']来代替。
而后建立这个Role
:
$ kubectl create -f haimaxy-role.yaml
注意这里咱们没有使用上面的
haimaxy-context
这个上下文了,由于木有权限啦
Role 建立完成了,可是很明显如今咱们这个 Role 和咱们的用户 haimaxy 尚未任何关系,对吧?这里我就须要建立一个RoleBinding
对象,在 kube-system 这个命名空间下面将上面的 haimaxy-role 角色和用户 haimaxy 进行绑定:(haimaxy-rolebinding.yaml)
apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: haimaxy-rolebinding namespace: kube-system subjects: - kind: User name: haimaxy apiGroup: "" roleRef: kind: Role name: haimaxy-role apiGroup: ""
上面的YAML
文件中咱们看到了subjects
关键字,这里就是咱们上面提到的用来尝试操做集群的对象,这里对应上面的 User 账号 haimaxy,使用kubectl
建立上面的资源对象:
$ kubectl create -f haimaxy-rolebinding.yaml
如今咱们应该能够上面的haimaxy-context
上下文来操做集群了:
$ kubectl get pods --context=haimaxy-context ....
咱们能够看到咱们使用kubectl
的使用并无指定 namespace 了,这是由于咱们已经为该用户分配了权限了,若是咱们在后面加上一个-n default
试看看呢?
$ kubectl --context=haimaxy-context get pods --namespace=default Error from server (Forbidden): pods is forbidden: User "haimaxy" cannot list pods in the namespace "default"
是符合咱们预期的吧?由于该用户并无 default 这个命名空间的操做权限
上面咱们建立了一个只能访问某个命名空间下面的普通用户,咱们前面也提到过 subjects 下面还有一直类型的主题资源:ServiceAccount,如今咱们来建立一个集群内部的用户只能操做 kube-system 这个命名空间下面的 pods 和 deployments,首先来建立一个 ServiceAccount 对象:
$ kubectl create sa haimaxy-sa -n kube-system
固然咱们也能够定义成YAML
文件的形式来建立。
而后新建一个 Role 对象:(haimaxy-sa-role.yaml)
apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: haimaxy-sa-role namespace: kube-system rules: - apiGroups: [""] resources: ["pods"] verbs: ["get", "watch", "list"] - apiGroups: ["apps"] resources: ["deployments"] verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
能够看到咱们这里定义的角色没有建立、删除、更新 Pod 的权限,待会咱们能够重点测试一下,建立该 Role 对象:
$ kubectl create -f haimaxy-sa-role.yaml
而后建立一个 RoleBinding 对象,将上面的 haimaxy-sa 和角色 haimaxy-sa-role 进行绑定:(haimaxy-sa-rolebinding.yaml)
kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: haimaxy-sa-rolebinding namespace: kube-system subjects: - kind: ServiceAccount name: haimaxy-sa namespace: kube-system roleRef: kind: Role name: haimaxy-sa-role apiGroup: rbac.authorization.k8s.io
添加这个资源对象:
$ kubectl create -f haimaxy-sa-rolebinding.yaml
而后咱们怎么去验证这个 ServiceAccount 呢?咱们前面的课程中是否是提到过一个 ServiceAccount 会生成一个 Secret 对象和它进行映射,这个 Secret 里面包含一个 token,咱们能够利用这个 token 去登陆 Dashboard,而后咱们就能够在 Dashboard 中来验证咱们的功能是否符合预期了:
$ kubectl get secret -n kube-system |grep haimay-sa haimay-sa-token-nxgqx kubernetes.io/service-account-token 3 47m $ kubectl get secret haimay-sa-token-nxgqx -o jsonpath={.data.token} -n kube-system |base64 -d # 会生成一串很长的base64后的字符串
使用这里的 token 去 Dashboard 页面进行登陆:
咱们能够看到上面的提示信息,这是由于咱们登陆进来后默认跳转到 default 命名空间,咱们切换到 kube-system 命名空间下面就能够了:
咱们能够看到能够访问pod列表了,可是也会有一些其余额外的提示:events is forbidden: User “system:serviceaccount:kube-system:haimaxy-sa” cannot list events in the namespace “kube-system”,这是由于当前登陆用只被受权了访问 pod 和 deployment 的权限,一样的,访问下deployment看看能够了吗?
一样的,你能够根据本身的需求来对访问用户的权限进行限制,能够本身经过 Role 定义更加细粒度的权限,也可使用系统内置的一些权限……
刚刚咱们建立的haimaxy-sa
这个 ServiceAccount 和一个 Role 角色进行绑定的,若是咱们如今建立一个新的 ServiceAccount,须要他操做的权限做用于全部的 namespace,这个时候咱们就须要使用到 ClusterRole 和 ClusterRoleBinding 这两种资源对象了。一样,首先新建一个 ServiceAcount 对象:(haimaxy-sa2.yaml)
apiVersion: v1 kind: ServiceAccount metadata: name: haimaxy-sa2 namespace: kube-system
建立:
$ kubectl create -f haimaxy-sa2.yaml
而后建立一个 ClusterRoleBinding 对象(haimaxy-clusterolebinding.yaml):
kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1beta1 metadata: name: haimaxy-sa2-clusterrolebinding subjects: - kind: ServiceAccount name: haimaxy-sa2 namespace: kube-system roleRef: kind: ClusterRole name: cluster-admin apiGroup: rbac.authorization.k8s.io
从上面咱们能够看到咱们没有为这个资源对象声明 namespace,由于这是一个 ClusterRoleBinding 资源对象,是做用于整个集群的,咱们也没有单独新建一个 ClusterRole 对象,而是使用的 cluster-admin 这个对象,这是Kubernetes
集群内置的 ClusterRole 对象,咱们可使用kubectl get clusterrole
和kubectl get clusterrolebinding
查看系统内置的一些集群角色和集群角色绑定,这里咱们使用的 cluster-admin 这个集群角色是拥有最高权限的集群角色,因此通常须要谨慎使用该集群角色。
建立上面集群角色绑定资源对象,建立完成后一样使用 ServiceAccount 对应的 token 去登陆 Dashboard 验证下:
$ kubectl create -f haimaxy-clusterolebinding.yaml
$ kubectl get secret -n kube-system |grep haimay-sa2 haimay-sa2-token-nxgqx kubernetes.io/service-account-token 3 47m $ kubectl get secret haimay-sa2-token-nxgqx -o jsonpath={.data.token} -n kube-system |base64 -d # 会生成一串很长的base64后的字符串