4 RBAC授权
4.1 什么是RBAC
在Kubernetes中,所有资源对象都是通过API进行操作,他们保存在etcd里。而对etcd的操作我们需要通过访问kube-apiserver来实现,上面的Service Account其实就是APIServer的认证过程,而授权的机制是通过RBAC:基于角色的访问控制实现。
RBAC(Role Base Access Control)基于角色的访问控制,其实就是将资源的操作权限授予给指定的角色,而后将用户加入该角色,那么该用户则拥有了对应角色的权限。
RBAC有四个资源对象,分别是 Role、ClusterRole、RoleBinding、ClusterRoleBinding。
举例: 希望qingchen用户能够获取所有Pod的列表
1、首先定义角色,然后定义角色权限规则,资源: POd,操作权限: get,list
2、然后定义角色绑定,将qingchen绑定至该角色,然后qingchen就拥有了该角色的权限,进而就能获取Pod信息
4.2 RBAC角色与集群角色
Kubernetes系统的RBAC授权插件将角色分为了Role和ClusterRole两类:
Role: 进作用于名称空间级别,用于承载名称空间级别内的资源权限集合
ClusterRole: 作用于集群乏味,能够同时承载名称空间和集群级别的资源权限集合
Kubernetes利用Role和ClusterRole两类角色来赋予对应的权限,同时也需要用到另外两类资源Rolebinding和ClusterRolebinding来完成用户与角色之间的绑定关系。
注意: RoleBinding除了可以绑定Role以外,还可以绑定ClusterRole,但它的权限还是限制在名称空间级别;
这种方式有着特定的应用场景:
比如: 希望在三个名称空间中都创建一个管理员身份,那么我们就需要创建3个role和3个rolebinding
但是: 我们可以定义一个clusterrole,然后通过rolebinding绑定就完成了,,也就不需要重复创建很多的role
4.3Role:角色
一组权限的集合,在一个命名空间中,可以用其来定义一个角色,只能对命名空间内的资源进行授权。如果是集群级别的资源,则需要使用ClusterRole。例如:定义一个角色用来读取 Pod 的权限
4.4ClusterRole:集群角色
具有和角色一致的命名空间资源的管理能力,还可用于以下特殊元素的授权
1、集群范围的资源,例如Node
2、非资源型的路径,例如:/healthz
3、包含全部命名空间的资源,例如Pods
例如:定义一个集群角色可让用户访问任意
4.5RoleBinding:角色绑定、ClusterRolebinding:集群角色绑定
角色绑定和集群角色绑定用于把一个角色绑定在一个目标上,可以是 User,Group,Service Account,使用RoleBinding为某个命名空间授权,使用ClusterRoleBinding为集群范围内授权。
例如:将在 rbac 命名空间中把 pod-read 角色授予用户 es
RoleBinding也可以引用ClusterRole,对属于同一命名空间内的ClusterRole定义的资源主体进行授权, 例如:es 能获取到集群中所有的资源信息
集群角色绑定的角色只能是集群角色,用于进行集群级别或对所有命名空间都生效的授权
例如:允许manager组的用户读取所有namaspace的secrets
4.6 资源的引用方式
多数资源可以用其名称的字符串表示,也就是Endpoint中的URL相对路径,例如pod中的日志是GET /api/v1/namaspaces/{namespace}/pods/{podname}/log
如果需要在一个RBAC对象中体现上下级资源,就需要使用“/”分割资源和下级资源。
例如:若想授权让某个主体同时能够读取Pod和Pod log,则可以配置 resources 为一个数组
资源还可以通过名称(ResourceName)进行引用,在指定ResourceName后,使用get、 delete、update、patch请求,就会被限制在这个资源实例范围内
例如,下面的声明让一个主体只能对名为my-configmap的Configmap进行get和update操作:
4.7RBAC场景实践
4.7.1 kubectl命令行工具创建资源对象
(1)在命名空间rbac中为用户es授权admin ClusterRole:
kubectl create rolebinding bob-admin-binding --clusterrole=admin --user=es --namespace=rbac
(2)在命名空间rbac中为名为myapp的Service Account授予 view ClusterRole:
kubctl create rolebinding myapp-role-binding --clusterrole=view --serviceaccount=rbac:myapp --namespace=rbac
(3)在全集群范围内为用户root授予cluster-admin ClusterRole:
kubectl create clusterrolebinding cluster-binding --clusterrole=cluster-admin --user=root
(4)在全集群范围内为名为myapp 的 Service Account 授予 view ClusterRole:
kubectl create clusterrolebinding service-account-binding --clusterrole=view --serviceaccount=myapp
yaml 文件进行 rbac 授权:https://kubernetes.io/zh/docs/reference/access-authnauthz/rbac/
4.7.2实践场景-1
场景说明: 赋予qingchen用户对default名称空间拥有Pod的读取权限
1、创建role角色,设定对应的规则
2、创建rolebinding角色绑定,将qingchen绑定至对应的role上
3、使用qingchen用户验证权限
#非default名称空间,访问会报错
4.7.3实践场景-2
场景说明: 赋予qingchen用户对所有名称空间拥有Pod的读写权限(ClusterRole、ClusterRoleBinding)
1、创建clusterrole
2、创建clusterrolebinding,并绑定qingchen用于至对应的clusterrole
3、使用qingchen用户验证权限
kubectl get pod --context="qingchen@kubernetes"
kubectl get pod -n kube-system --context="qingchen@kubernetes"
#任何名称空间都可以查看,但没有删除权限
4.7.4实践场景-3
场景说明: 赋予qingchen用户对default名称空间拥有管理员权限
系统内置了一个ClusterRole:admin的集群管理员,我们可以通过rolebinding引用Cluster:admin集群角色,该引用会造成用户仅对rolebinding所在的名称空间有管理员权限(因为rolebinding仅能作用在名称空间)。
1、删除此前的绑定,避免权限受到干扰
kubectl delete clusterrolebinding cluster-pod-reader-qingchen
2、创建RoleBinding引用Cluster-role
3、验证qingchen用户权限
#能对default名称空间进行增删改查,对其他名称空间毫无权限
4.8内置的ClusterRole
Kubernetes系统内置了一组默认的ClusterRole和ClusterRoleBinding资源预留给系统使用,其中大多数以system:为前缀。还有一些不以system:为前缀的
ClusterRole是面向用户设计的,比如: 集群管理员角色cluster-admin、admin、edit、view,掌握这些默认的内置角色资源有助于按需创建用户并分配相应的权限。
4.8.1 Cluster-admin分析
内置的cluster-admin资源拥有管理集群所有资源的权限,而内置的cluster-admin将该角色分配给了system:master组,这意味着所有加入该组的用户都将自动具有集群的超级管理员权限。
在使用kubeadm安装集群时,它自动创建配置文件/etc/kubernetes/admin.conf中定义的用户为kubernetes-admin,而该用户使用数字证书,Subject属性值为/O=system:masters。所以APIServer会在成功验证该用户的身份之后将其识别为system:masters用户组的成员。
分析过程如下:
1、查看cluster-admin角色绑定关系,可以看到cluster-admin这个角色绑定的system.masters
2、system:masters这个组名称并非人为定义,而是证书生成的
openssl x509 -in /etc/kubernetes/pki/apiserver-kubelet-client.crt -text -noout
注意: 在创建证书时,可以将用户绑定到system:masters、组,用户会自动继承组的权限
4.8.2 Cluster-admin实践
创建一个k8s-dream用户,然后将该用户加入到system:masters组中,验证是否拥有集群管理员权限
1、创建证书私钥文件
2、创建证书签署请求文件,CN为指定的用户名,O为指定的组名称
3、使用kubernetes-ca的身份对文件进行签署
4、根据x509数字证书及私钥创建身份凭据
5、配置context上下文,以k8s-dream身份凭据访问已定义的Kubernetes集群,context名称为k8s-dream@kubernetes
6、测试k8s-dream是否具备超级管理员权限
kubectl get nodes --context="k8s-dream@kubernetes"
kubectl get pod -A --context="k8s-dream@kubernetes"