十六 RBAC
一、概述
1、前面讲过,kubernetes的授权也是基于插件来实现而且用户访问时某一次操作经由某一授权插件检查能通过后就不再经由其它插件检查。然后由准入控制插件再做进一步后续的准入控制检查。那么在他众多授权插件中已经解释过常用的有这样四个。
授权插件:Node,ABAC,RBAC,Webhook
二、RBAC
1、RBAC全称为Role-based AccessControl,所谓基于角色的访问控制可以理解为这么一种场景:我们的用户账号就是可以独立访问计算机服务的和我们此前所讲的用户没什么不同。角色反而是授权的机制。他通过角色完成了权限的授予,分配等。
a、角色(role):因此从内容来讲角色是指一个组织或者任务中的工作或者位置,他通常代表一种权力和资格,或者一种责任,在RBAC中还有一个重要的术语
b、许可(permission),也称作为权限。
2、基于角色的访问控制可以从下图中来理解,我们用户扮演一个角色,这个角色拥有权限所以这个用户也拥有了这个权限,所以我们随后授权不授予用户而授予给角色。我们以后的许可授权都添加在角色上。随后我们让用户去扮演这么一个角色,所以他就拥有了这个角色权限。
3、权限是怎么定义的呢?图中解释的很明显,每一个被访问的组件都是对象,大家都知道在k8s中一切皆对象,k8s上运行的组件或者k8s所有内容可分为三类,第一类就叫对象,它占了大部分主体。第二类叫对象列表,在API中。第三种叫虚拟对象,是一些虚拟路径,通常很少,叫非对象资源。 既然如此,我们接下来在restful风格基础中的所有操作都是指在某个对象上施加的某种行为,我们称为action。我们把其称为Operations操作,把一个对象上能施加的操作组合起来我们称为许可权限。而后我们可以在Role之上去授予这个Role拥有某种带许可的权限。就是拥有了某种在某些对象上实现某些操作的权限。因此我们要想实现使用基于角色的访问控制,那么应该有User,有Role,然后还有Permissions,而Permissions无非就是你应该事先在系统上有一大堆的Objects,这些Objects支持一些Operations,我们把它组合在一块儿定义成Permissions,把它们组合起来授予给Role就完成了授权。所以他大体上就表现为在基于角色访问控制中我们定义的无非就是某个主语,对于某个宾语施加某个操作。比如我们创建的账号叫wohaoshuai,能够去列出pods,但是我们对应的这个主体权限不是直接获取的而是需要有一个中间层,这个中间层就是角色,所以我们可以有一个中间的虚拟层,所有的权限都是指派到角色之上,让用户拥有这个角色就行了。
4、而真正能扮演成角色并施加权限的有两个账号
a、UserAccount,也就是现实中的人
b、Service Account,要执行某些操作的账号,真正的操作类型如图中所示。操作对象如图中所示(路径不正确)。
5、将上述所描述的操作和操作对象绑定起来定义成Permission而后再额外把这个Permission授予到角色上,然后再让用户扮演角色就完成授权了。
6、在k8s中我们的RBAC在实现授权时无非就是定义标准的刚刚我们所描述的概念。就是我们定义一个角色,而在角色上绑定了权限定义,我们让用户去扮演角色就够了。把这种概念反应在我们k8s集群上体现为:
a、我们应该定义一个角色,这是标准的k8s资源,角色里面定义Operations和objects,意思是对哪个对象执行什么操作。意思是允许对这些对象做这些操作(不能定义拒绝权限),也就是许可授权。
b、定义用户账号,然后绑定二者之间关系,在k8s上我们用的方式比较独特,它叫做rolebinding,表示绑定哪个用户,user account或service account,到哪个角色上
7、但是在k8s之上,我们所拥有的role和rolebinding是分别拥有两个级别。在k8s中,我们资源分属于两种级别:集群和名称空间。所以我们的role和rolebinding主要是在名称空间级别授予这个名称空间范围内的许可权限。除了role和rolebinding之外我们集群还有另外两个组件叫clusterrole和clusterrolebinding,即集群角色和集群角色绑定,很显然它是属于集群级别,可以看到我们在名称空间A中定义了一个角色叫Role,有用户叫user1,我们把user1和Role使用RoleBinding建立起了绑定关系,从而这个user1就拥有了这个Role之上所定义的权限,而这个Role所定义的权限一定是当前名称空间的。
但是如果我在cluster级别定义一个Role说用户能够get pod意味着用户能获取所有名称空间中的所有pod。因此我们如果把用户基于ClusterRoleBinding绑定到一个ClusterRole上就意味着这个用户拥有了集群级别上授予的权限。即便看上去我们的操作,即Operations和object是一样的,比如都是get或者list,后面给的object都是pods,如果定义成Role,表示这个Role的权限只对当前名称空间有效,pod就是指当前名称空间中所有pod,如果我们定义的角色是ClusterRole级别,那么我们一旦把用户绑定至这个ClusterRole上它就拥有所有名称空间的操作权限。
8、正常情况下,集群空间中我们使用RoleBinding去绑定Role,即一个用户绑定到Role上就表示用户拥有了当前名称空间中这个角色权限。我们使用ClusterRoleBinding去绑定ClusterRole也容易理解,我把一个用户通过ClusterRoleBinding绑定到ClusterRole上就表示这个用户拥有了对于这个ClusterRole对应的集群级别的所有权,但是,我们也可以使用RoleBinding去绑定ClusterRole。这意味着这个ClusterRole所对应的该用户的权限就只能对应到该用户所对应的名称空间上。那干嘛这么绕呢?干脆使用RoleBinding绑定Role不就行了么,为什么还要用RoleBinding绑定ClusterRole,其实他有个很好很便捷的做法:比如,我想授权一个用户对当前名称空间拥有管理权限,那么我们有十个名称空间,每个名称空间都有一个名称空间管理员,那么应该怎么定义呢?现在我们可以定义一个ClusterRole,然后使用RoleBinding去绑它,这样虽然ClusterRole定义的对所有名称空间有管理权限,但是真正的只有去绑定他的RoleBinding所在的名称空间中的用户对自己的名称空间拥有管理权限。若使用ClusterRoleBinding的话,该名称空间中的用户就对集群中所有的名称空间具有管理权限。
三,接下来我们创建。
1、创建Role
a、使用命令创建一个Role
[root@k8smaster ~]# kubectl create role pod-reader --verb=get,list,watch --resource=pods --dry-run #干跑模式
role.rbac.authorization.k8s.io/pod-reader created (dry run)
[root@k8smaster ~]# kubectl create role pod-reader --verb=get,list,watch --resource=pods --dry-run -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
creationTimestamp: null
name: pod-reader
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- list
- watch
b、使用yaml文件创建
[root@k8smaster manifests]# cat role-demo.yaml # 创建角色的配置文件
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pods-reader
namespace: default
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- list
- watch
[root@k8smaster manifests]# kubectl apply -f role-demo.yaml
role.rbac.authorization.k8s.io/pods-reader created
[root@k8smaster manifests]# kubectl get role # 查看角色
NAME AGE
pods-reader 12s
[root@k8smaster manifests]# kubectl
Name: pods-reader
Labels: <none>
Annotations: kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"rbac.authorization.k8s.io/v1","kind":"Role","metadata":{"annotations":{},"name":"pods-reader","namespace":"defa
ult"},"rules":[{"apiGroup...PolicyRule:
Resources Non-Resource URLs Resource Names Verbs
--------- ----------------- -------------- -----
pods [] [] [get list watch]
2、我们在之前创建了一个用户叫wohaoshuai,他是没有权限去读pod的,现在我们让wohaoshuai去扮演这个角色,此时我们需要创建一个RoleBinding并绑定
a、使用命令创建
[root@k8smaster manifests]# kubectl create rolebinding wohaoshuai-read-pods --role=pods-reader --user=wohaoshuai --dry-run -o yaml #将role和rolebinging绑定
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
creationTimestamp: null
name: wohaoshuai-read-pods
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: pods-reader
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: wohaoshuai
b、使用yaml文件创建
[root@k8smaster manifests]# cat rolebinding-demo.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: wohaoshuai-read-pods namespace: default roleRef: #role引用,即引用哪个role apiGroup: rbac.authorization.k8s.io kind: Role name: pods-reader subjects: #动作的执行主题,即绑定的哪个用户账号,他有两类用户,human User或者service account - apiGroup: rbac.authorization.k8s.io kind: User name: wohaoshuai [root@k8smaster manifests]# kubectl apply -f rolebinding-demo.yaml rolebinding.rbac.authorization.k8s.io/wohaoshuai-read-pods created [root@k8smaster manifests]# kubectl describe rolebinding wohaoshuai-read-pods Name: wohaoshuai-read-pods Labels: <none> Annotations: kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"rbac.authorization.k8s.io/v1","kind":"RoleBinding","metadata":{"annotations":{},"name":"wohaoshuai-read-pods"," namespace":"default"},"ro...Role: Kind: Role Name: pods-reader Subjects: Kind Name Namespace ---- ---- --------- User wohaoshuai
3、现在我们切换到账号wohaoshuai并查看pod
[root@k8smaster manifests]# kubectl config use-context wohaoshuai@kubernetes Switched to context "wohaoshuai@kubernetes". [root@k8smaster manifests]# kubectl get pods NAME READY STATUS RESTARTS AGE liveness-httpget-pod 1/1 Running 9 64d myapp-deploy-67f6f6b4dc-76ddb 1/1 Running 0 8d myapp-deploy-67f6f6b4dc-dfdjv 1/1 Running 0 8d myapp-deploy-67f6f6b4dc-gjlqd 1/1 Running 0 8d pod-sa-demo 1/1 Running 0 8d [root@k8smaster manifests]# kubectl get pods -n kube-system #因为只有当前名称空间权限因此不能get kube-system名称空间的pod No resources found. Error from server (Forbidden): pods is forbidden: User "wohaoshuai" cannot list pods in the namespace "kube-system"
# kubectl config use-context kubernetes-admin@kubernetes # 切回角色
4、定义clusterrole
a、命令创建
[root@k8smaster manifests]# kubectl create clusterrole cluster-reader --verb=get,list,watch --resource=pods -o yaml --dry-run
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
creationTimestamp: null
name: cluster-reader
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- list
- watch
在上述的资源配置清单中,rules主要用于定义策略规则,但不包含策略应用的目标,可内嵌的字段如下:
apiGroups:包含了资源API组的名称,支持列表格式指定的多个组,空串(“”)标识 核心组。
resourceNames:规则应用的目标资源名称列表,默认为资源类型下的所有资源
resources:规则应用的目标资源类型组成的列表,ResourceAll标识所有的资源
verb:可应用至此规则匹配到的所有资源类型的操作列表,可用的选项有:get、list、create、update、patch、watch、proxy、redirect、dekete和deletecollection。
nonResourceURLs:定义用户应该有权限访问的网址列表,并非名称空间级别的资源。只能永于ClusterRole和ClusterRoleBinding
b、yaml文件定义
[root@k8smaster manifests]# cat clusterrole-demo.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: cluster-reader
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- list
- watch
[root@k8smaster manifests]# kubectl apply -f clusterrole-demo.yaml
clusterrole.rbac.authorization.k8s.io/cluster-reader created
5、接下来我们可以做绑定了,我们可以把我们此前的wohaoshuai绑定在clusterrole上,wohaoshuai就拥有了读取所有名称空间pod的权限。
a、使用命令创建clusterrolebinding
[root@k8smaster manifests]# kubectl create clusterrolebinding wohaoshuai-read-all-pods --clusterrole=cluster-reader --user=wohaoshuai --dry-run -o yaml apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRoleBinding metadata: creationTimestamp: null name: wohaoshuai-read-all-pods roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-reader subjects: - apiGroup: rbac.authorization.k8s.io kind: User name: wohaoshuai
b、使用yaml文件创建
[root@k8smaster manifests]# cat clusterrolebinding-demo.yaml apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRoleBinding metadata: name: wohaoshuai-read-all-pods roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-reader subjects: - apiGroup: rbac.authorization.k8s.io kind: User name: wohaoshuai [root@k8smaster manifests]# kubectl apply -f clusterrolebinding-demo.yaml clusterrolebinding.rbac.authorization.k8s.io/wohaoshuai-read-all-pods created
[root@k8smaster manifests]# kubectl describe clusterrolebinding wohaoshuai-read-all-pods
Name: wohaoshuai-read-all-pods
Labels: <none>
Annotations: kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"rbac.authorization.k8s.io/v1beta1","kind":"ClusterRoleBinding","metadata":{"annotations":{},"name":"wohaoshuai-
read-all-pods","namespace...Role:
Kind: ClusterRole
Name: cluster-reader
Subjects:
Kind Name Namespace
---- ---- ---------
User wohaoshuai
6、我们再将账号切换至wohaoshuai然后访问所有名称空间的pod,发现是可以访问的
[root@k8smaster manifests]# kubectl config use-context wohaoshuai@kubernetes Switched to context "wohaoshuai@kubernetes". [root@k8smaster manifests]# kubectl get pods --all-namespaces NAMESPACE NAME READY STATUS RESTARTS AGE default liveness-httpget-pod 1/1 Running 9 66d default myapp-deploy-67f6f6b4dc-76ddb 1/1 Running 0 10d default myapp-deploy-67f6f6b4dc-dfdjv 1/1 Running 0 10d default myapp-deploy-67f6f6b4dc-gjlqd 1/1 Running 0 10d default pod-sa-demo 1/1 Running 0 9d ingress-nginx default-http-backend-846b65fb5f-ggwwp 1/1 Running 7 36d ingress-nginx nginx-ingress-controller-d658896cd-nqt4b 1/1 Running 27 36d kube-system coredns-78fcdf6894-6qs64 1/1 Running 6 71d kube-system coredns-78fcdf6894-bhzf4 1/1 Running 6 71d kube-system etcd-k8smaster 1/1 Running 15 71d kube-system kube-apiserver-k8smaster 1/1 Running 28 71d kube-system kube-controller-manager-k8smaster 1/1 Running 15 71d kube-system kube-flannel-ds-amd64-d22fv 1/1 Running 9 71d kube-system kube-flannel-ds-amd64-nskmt 1/1 Running 6 71d kube-system kube-flannel-ds-amd64-q4jvr 1/1 Running 9 71d kube-system kube-proxy-6858m 1/1 Running 9 71d kube-system kube-proxy-6btdl 1/1 Running 8 71d kube-system kube-proxy-fknmj 1/1 Running 6 71d kube-system kube-scheduler-k8smaster 1/1 Running 15 71d
但是它是没有删除权限的,因为没有给他赋予
[root@k8smaster manifests]# kubectl delete pod myapp-deploy-67f6f6b4dc-76ddb Error from server (Forbidden): pods "myapp-deploy-67f6f6b4dc-76ddb" is forbidden: User "wohaoshuai" cannot delete pods in the namespace "default"
6、现在我们把刚刚这个clusterrolebinding删掉,然后使用rolebinding去绑定clusterrole,这样clusterrole上所定义的权限只针对rolebinding所在的名称空间生效。 所以如果我们先把把wohaoshuai这个账号用rolebinding去绑定我们刚刚定义的clusterrole cluster-read-all-pods上,角色还是那个角色,不过绑定方式变了,我们换成rolebinding了就变成wohaoshuai只能读这个rolebinding所在名称空间中的所有资源了
[root@k8smaster ~]# kubectl delete clusterrolebinding wohaoshuai-read-all-pods clusterrolebinding.rbac.authorization.k8s.io "wohaoshuai-read-all-pods" deleted [root@k8smaster manifests]# kubectl create rolebinding wohaoshuai-read-pods --clusterrole=cluster-reader --user=wohaoshuai --dry-run -o yaml >rolebinding-clusterrole-demo.yaml [root@k8smaster manifests]# cat rolebinding-clusterrole-demo.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: wohaoshuai-read-pods namespace: default roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-reader subjects: - apiGroup: rbac.authorization.k8s.io kind: User name: wohaoshuai
[root@k8smaster manifests]# kubectl describe rolebinding wohaoshuai-read-pods Name: wohaoshuai-read-pods Labels: <none> Annotations: kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"rbac.authorization.k8s.io/v1","kind":"RoleBinding","metadata":{"annotations":{},"name":"wohaoshuai-read-pods"," namespace":"default"},"ro...Role: Kind: ClusterRole Name: cluster-reader Subjects: Kind Name Namespace ---- ---- --------- User wohaoshuai [root@k8smaster manifests]# kubectl config use-context wohaoshuai@kubernetes Switched to context "wohaoshuai@kubernetes". [root@k8smaster manifests]# kubectl get pods NAME READY STATUS RESTARTS AGE liveness-httpget-pod 1/1 Running 9 72d myapp-deploy-67f6f6b4dc-76ddb 1/1 Running 0 15d myapp-deploy-67f6f6b4dc-dfdjv 1/1 Running 0 15d myapp-deploy-67f6f6b4dc-gjlqd 1/1 Running 0 15d pod-sa-demo 1/1 Running 0 15d [root@k8smaster manifests]# kubectl get pods --all-namespaces #可以看到降级了 No resources found. Error from server (Forbidden): pods is forbidden: User "wohaoshuai" cannot list pods at the cluster scope
7、刚刚演示的授权只是授权到一个pod类别上,我们也可以授权到单个资源上,比如授权到某一个特定的pod资源之上。
四、我们系统内建的clusterrole
1、我们定义role和定义clusterrole很相像,定义rolebinding和clusterrolebinding也很相像,他们只不过所作用的范围不一样而已。接下来我们看一下系统内建的clusterrole admin,admin定义成为一个clusterrole意味着它其实是整个集群级别的权限。
[root@k8smaster manifests]# kubectl get clusterrole admin -o yaml
aggregationRule:
clusterRoleSelectors:
- matchLabels:
rbac.authorization.k8s.io/aggregate-to-admin: "true"
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
annotations:
rbac.authorization.kubernetes.io/autoupdate: "true"
creationTimestamp: 2019-05-08T10:02:12Z
labels:
kubernetes.io/bootstrapping: rbac-defaults
name: admin
resourceVersion: "350"
selfLink: /apis/rbac.authorization.k8s.io/v1/clusterroles/admin
uid: 59a867c7-7178-11e9-be24-000c29d142be
rules:
- apiGroups:
- ""
resources: #对于pod的操作
- pods
- pods/attach
- pods/exec
- pods/portforward
- pods/proxy
verbs: #允许的操作
- create
- delete
- deletecollection
- get
- list
- patch
- update
- watch
- apiGroups:
- ""
resources:
- configmaps
- endpoints
- persistentvolumeclaims
- replicationcontrollers
- replicationcontrollers/scale
- secrets
- serviceaccounts
- services
- services/proxy
verbs:
- create
- delete
- deletecollection
- get
- list
- patch
- update
- watch
- apiGroups:
- ""
resources:
- bindings
- events
- limitranges
- namespaces/status
- pods/log
- pods/status
- replicationcontrollers/status
- resourcequotas
- resourcequotas/status
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- namespaces
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- serviceaccounts
verbs:
- impersonate
- apiGroups:
- apps
resources:
- daemonsets
- deployments
- deployments/rollback
- deployments/scale
- replicasets
- replicasets/scale
- statefulsets
- statefulsets/scale
verbs:
- create
- delete
- deletecollection
- get
- list
- patch
- update
- watch
- apiGroups:
- autoscaling
resources:
- horizontalpodautoscalers
verbs:
- create
- delete
- deletecollection
- get
- list
- patch
- update
- watch
- apiGroups:
- batch
resources:
- cronjobs
- jobs
verbs:
- create
- delete
- deletecollection
- get
- list
- patch
- update
- watch
- apiGroups:
- extensions
resources:
- daemonsets
- deployments
- deployments/rollback
- deployments/scale
- ingresses
- networkpolicies
- replicasets
- replicasets/scale
- replicationcontrollers/scale
verbs:
- create
- delete
- deletecollection
- get
- list
- patch
- update
- watch
- apiGroups:
- policy
resources:
- poddisruptionbudgets
verbs:
- create
- delete
- deletecollection
- get
- list
- patch
- update
- watch
- apiGroups:
- networking.k8s.io
resources:
- networkpolicies
verbs:
- create
- delete
- deletecollection
- get
- list
- patch
- update
- watch
- apiGroups:
- authorization.k8s.io
resources:
- localsubjectaccessreviews
verbs:
- create
- apiGroups:
- rbac.authorization.k8s.io
resources:
- rolebindings
- roles
verbs:
- create
- delete
- deletecollection
- get
- list
- patch
- update
- watch
2、我们现在把wohaoshuai在default名称空间使用rolebinding绑在clusterrole admin上,那么wohaoshuai就拥有了default名称空间的管理权限,但他不具有删除敏感资源的权限。像有些configmap资源等只能查看,现在我们来做绑定
a、用命令的方式
[root@k8smaster manifests]# kubectl create rolebinding default-ns-admin --clusterrole=admin --user=wohaoshuai --dry-run -o yaml
b、用yaml的方式
[root@k8smaster manifests]# cat rolebinding-default-ns-admin.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: default-ns-admin namespace: default roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: admin subjects: - apiGroup: rbac.authorization.k8s.io kind: User name: wohaoshuai [root@k8smaster manifests]# kubectl apply -f rolebinding-default-ns-admin.yaml rolebinding.rbac.authorization.k8s.io/default-ns-admin created
c、测试
[root@k8smaster manifests]# kubectl get pods NAME READY STATUS RESTARTS AGE liveness-httpget-pod 1/1 Running 9 72d myapp-deploy-67f6f6b4dc-76ddb 1/1 Running 0 16d myapp-deploy-67f6f6b4dc-dfdjv 1/1 Running 0 16d myapp-deploy-67f6f6b4dc-gjlqd 1/1 Running 0 16d pod-sa-demo 1/1 Running 0 15d [root@k8smaster manifests]# kubectl get pods --all-namespaces No resources found. Error from server (Forbidden): pods is forbidden: User "wohaoshuai" cannot list pods at the cluster scope [root@k8smaster manifests]# kubectl delete pod myapp-deploy-67f6f6b4dc-gjlqd pod "myapp-deploy-67f6f6b4dc-gjlqd" deleted
3、为什么系统装完以后默认的这个账号默认复制配置文件就拥有管理所有空间的所有资源的权限呢?接下来我们去get 一个clusterrolebinding cluster-admin
[root@k8smaster manifests]# kubectl get clusterrolebinding cluster-admin -o yaml apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: annotations: rbac.authorization.kubernetes.io/autoupdate: "true" creationTimestamp: 2019-05-08T10:02:12Z labels: kubernetes.io/bootstrapping: rbac-defaults name: cluster-admin resourceVersion: "110" selfLink: /apis/rbac.authorization.k8s.io/v1/clusterrolebindings/cluster-admin uid: 59d7c0d0-7178-11e9-be24-000c29d142be roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-admin subjects: # system:masters这个组内有一用户叫kubernetes-admin,之所以属于这个组是在kubernetes-admin这个证书中定义的 - apiGroup: rbac.authorization.k8s.io kind: Group #组 name: system:masters
[root@k8smaster pki]# openssl x509 -in ./apiserver-kubelet-client.crt -text -noout
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 9020042834761097681 (0x7d2da12b00be21d1)
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN=kubernetes
Validity
Not Before: May 8 10:01:24 2019 GMT
Not After : May 7 10:01:24 2020 GMT
Subject: O=system:masters, CN=kube-apiserver-kubelet-client #说明system:masters这个组内的所有用户都拥有这个权限了,当前用户kubernetes-admin对应的其实就是CN中的这个名字,虽然在config view看到的是admin但是在系统中识别的就是CN中的这个用户。以后我们自己定义的时候定义成组也可以,使用O=什么就行了,上次只定义了一个CN=wohaoshuai,如果想把wohaoshuai定义到admin这个组来设置成O=admin即可
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:cd:6d:ad:60:e3:65:72:88:97:4f:79:51:aa:13:
22:be:53:45:97:3d:fc:03:e3:ac:d4:5d:1a:08:79:
62:97:a8:be:fa:63:b5:67:ee:66:a8:95:48:50:8c:
c4:14:2b:b6:05:7f:1a:f7:12:ec:81:b6:53:89:bb:
f7:2e:7e:a4:83:0e:6c:8a:3c:6e:76:ad:02:3d:00:
cd:5a:16:36:5e:bb:6a:08:1f:28:ef:f4:01:e3:06:
6c:12:b8:e0:fb:47:9f:ec:d2:4d:3d:20:d6:e0:7d:
bf:bb:7f:b0:04:e8:8a:2b:1d:fe:66:a9:79:ec:30:
aa:e0:15:90:d8:14:62:fc:14:ed:63:38:ae:cc:6e:
ff:c9:bc:5e:6a:64:22:26:1e:7c:31:78:ae:d1:04:
8f:2d:b9:1a:72:c6:05:dc:90:53:3c:a3:34:c0:17:
dd:d8:eb:de:0d:24:13:57:01:7d:a3:54:8a:e1:10:
47:71:2a:61:0f:8c:99:13:30:16:84:f5:0c:d4:1c:
8a:28:79:95:09:0b:54:5c:f4:55:6c:06:d7:e2:d1:
f8:5e:5e:d1:6e:6b:90:a6:db:42:d3:a1:e1:de:c5:
7c:cd:b3:2f:8a:23:1d:14:03:c9:10:90:80:e2:01:
c6:1c:8a:df:d5:e8:37:c0:9c:52:5d:23:26:95:f8:
c4:c5
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Key Usage: critical
Digital Signature, Key Encipherment
X509v3 Extended Key Usage:
TLS Web Client Authentication
Signature Algorithm: sha256WithRSAEncryption
b4:5d:2a:3c:71:e5:37:c6:ae:ce:11:b3:ab:6c:7f:bf:99:8c:
b9:ff:46:14:60:40:86:90:86:52:b5:ea:c5:1b:d0:cd:fe:51:
0b:c3:15:e8:55:80:79:03:62:83:32:2a:46:ac:42:a8:4a:ad:
f3:9a:57:2e:fe:38:5f:7b:cc:97:f8:52:f1:49:00:bd:aa:ce:
42:af:b1:93:5f:6f:1f:a9:6b:c4:c1:bb:7f:9c:3b:38:92:32:
a6:7b:9d:1e:19:e2:89:d5:50:3c:8e:84:91:ee:03:31:ec:7e:
a4:33:34:e6:5a:18:32:ca:28:52:b6:2b:ec:ab:58:03:03:0c:
ab:33:cd:03:4e:47:0a:16:71:f4:16:af:9b:2d:5d:85:d1:eb:
0c:0c:df:0d:3d:7b:3b:6b:ff:14:9d:8f:ba:eb:c4:d2:f8:15:
96:4d:b3:bf:68:98:9c:8d:b8:e5:cd:a6:8c:7b:94:66:46:24:
30:06:5b:be:79:8f:cb:b1:1c:2e:a9:e2:88:e0:91:e3:c5:8d:
72:3d:64:11:f2:b9:f2:b1:44:d4:26:56:30:d8:f7:4e:a3:bc:
13:93:3b:24:6e:2c:05:a9:42:8d:5d:1e:a3:dd:d9:0f:80:2f:
95:e1:8b:aa:f1:22:fc:63:7b:d9:8a:36:02:fc:27:22:19:93:
6c:a3:6b:8c
4、在rbac上进行授权时,存在三类组件。第一类为user,我们授权绑定时,即clusterrolebinding或rolebinding时都可以绑定在user上,也可以绑定在group上,还可以绑定在serviceaccount上。若绑定在user上表示只授权这一个用户扮演相关角色。若绑定在组上表示授权这个组内所有用户都能扮演这个角色。所以如果想一次授权多个用户在一个名称空间中拥有同样的权限你就可以定义一个组,授权的时候定义组授权。接下来演示如何绑定serviceAccount,它和我们其它绑定方式没有什么区别。而且一旦你在serviceaccount上做了rolebinding或clusterbinding就意味着这个serviceaccount拥有了访问权限,任何一个pod如果启动时以这个serviceaccountname 作为它使用的serviceaccount的话那么这个pod中应用程序就拥有了它所授予的权限,即这个serviceaccout所拥有的权限。
我们在创建pod时可以给pod指定一个属性叫serviceAccountname,也就是说这个pod以这个serviceAccount去连接Apiserver获取资源访问资源,因此如果我们授权时候把这个serviceAccountname所表现的账号授予了特殊权限,比如拥有了管理员权限,那么就认为这个pod具有管理员权限了。
所以我们可以这么干,在集群中定义一个clusterrolebinding和一个rolebinding,(怎么做都行,取决于你的需要)。比如使用rolebinding把这个serviceaccount绑定在一个role上,也就意味着授予这个sa拥有这个role这个权限,因此相当于这个pod拥有了这个role权限了。因为这个pod是以serviceaccount的身份来运行。因此有些pod是需要管理员权限的,比如kube-system名称空间中的很多的pod资源。比如flannel之类的就需要特殊权限,需要访问网络名称空间中的网络,默认这个serviceaccount没这个权限,但是我们现在需要flannel这个程序获取当前系统集群上的其它很多其它资源以确保能正确设置网络属性,因此这个flannel就需要获取更多的额外权限。所以我们在flannel上就有了专门的角色。
[root@k8smaster pki]# kubectl get pods -n kube-system NAME READY STATUS RESTARTS AGE coredns-78fcdf6894-6qs64 1/1 Running 6 77d coredns-78fcdf6894-bhzf4 1/1 Running 6 77d etcd-k8smaster 1/1 Running 15 77d kube-apiserver-k8smaster 1/1 Running 28 77d kube-controller-manager-k8smaster 1/1 Running 15 77d kube-flannel-ds-amd64-d22fv 1/1 Running 9 77d kube-flannel-ds-amd64-nskmt 1/1 Running 6 77d kube-flannel-ds-amd64-q4jvr 1/1 Running 9 77d kube-proxy-6858m 1/1 Running 9 77d kube-proxy-6btdl 1/1 Running 8 77d kube-proxy-fknmj 1/1 Running 6 77d kube-scheduler-k8smaster 1/1 Running 15 77d
[root@k8smaster pki]# kubectl get pod kube-flannel-ds-amd64-q4jvr -n kube-system -o yaml apiVersion: v1 kind: Pod metadata: creationTimestamp: 2019-05-09T01:53:25Z generateName: kube-flannel-ds-amd64- labels: app: flannel controller-revision-hash: "3982298629" pod-template-generation: "1" tier: node name: kube-flannel-ds-amd64-q4jvr namespace: kube-system ownerReferences: - apiVersion: apps/v1 blockOwnerDeletion: true controller: true kind: DaemonSet name: kube-flannel-ds-amd64 uid: 637fb671-71fa-11e9-be24-000c29d142be resourceVersion: "1108587" selfLink: /api/v1/namespaces/kube-system/pods/kube-flannel-ds-amd64-q4jvr uid: 3b841e7c-71fd-11e9-be24-000c29d142be spec: containers: - args: - --ip-masq - --kube-subnet-mgr command: - /opt/bin/flanneld env: - name: POD_NAME valueFrom: fieldRef: apiVersion: v1 fieldPath: metadata.name - name: POD_NAMESPACE valueFrom: fieldRef: apiVersion: v1 fieldPath: metadata.namespace image: quay.io/coreos/flannel:v0.11.0-amd64 imagePullPolicy: IfNotPresent name: kube-flannel resources: limits: cpu: 100m memory: 50Mi requests: cpu: 100m memory: 50Mi securityContext: capabilities: add: - NET_ADMIN privileged: false terminationMessagePath: /dev/termination-log terminationMessagePolicy: File volumeMounts: - mountPath: /run/flannel name: run - mountPath: /etc/kube-flannel/ name: flannel-cfg - mountPath: /var/run/secrets/kubernetes.io/serviceaccount name: flannel-token-qclvk readOnly: true dnsPolicy: ClusterFirst hostNetwork: true initContainers: - args: - -f - /etc/kube-flannel/cni-conf.json - /etc/cni/net.d/10-flannel.conflist command: - cp image: quay.io/coreos/flannel:v0.11.0-amd64 imagePullPolicy: IfNotPresent name: install-cni resources: {} terminationMessagePath: /dev/termination-log terminationMessagePolicy: File volumeMounts: - mountPath: /etc/cni/net.d name: cni - mountPath: /etc/kube-flannel/ name: flannel-cfg - mountPath: /var/run/secrets/kubernetes.io/serviceaccount name: flannel-token-qclvk readOnly: true nodeName: k8snode1 nodeSelector: beta.kubernetes.io/arch: amd64 priority: 0 restartPolicy: Always schedulerName: default-scheduler securityContext: {} serviceAccount: flannel #可以看到serviceAccount为 flannel serviceAccountName: flannel terminationGracePeriodSeconds: 30 tolerations: - effect: NoSchedule operator: Exists - effect: NoExecute key: node.kubernetes.io/not-ready operator: Exists - effect: NoExecute key: node.kubernetes.io/unreachable operator: Exists - effect: NoSchedule key: node.kubernetes.io/disk-pressure operator: Exists - effect: NoSchedule key: node.kubernetes.io/memory-pressure operator: Exists volumes: - hostPath: path: /run/flannel type: "" name: run - hostPath: path: /etc/cni/net.d type: "" name: cni - configMap: defaultMode: 420 name: kube-flannel-cfg name: flannel-cfg - name: flannel-token-qclvk secret: defaultMode: 420 secretName: flannel-token-qclvk status: conditions: - lastProbeTime: null lastTransitionTime: 2019-05-09T01:57:04Z status: "True" type: Initialized - lastProbeTime: null lastTransitionTime: 2019-07-08T03:19:45Z status: "True" type: Ready - lastProbeTime: null lastTransitionTime: null status: "True" type: ContainersReady - lastProbeTime: null lastTransitionTime: 2019-05-09T01:53:25Z status: "True" type: PodScheduled containerStatuses: - containerID: docker://8446608c056ed91897ff9a00ed117141b52750087b727663aefef01b9cd65a48 image: quay.io/coreos/flannel:v0.11.0-amd64 imageID: docker-pullable://quay.io/coreos/flannel@sha256:7806805c93b20a168d0bbbd25c6a213f00ac58a511c47e8fa6409543528a204e lastState: terminated: containerID: docker://092fada4a26f3b00e2ac7c13c27e6882b7df31938b9d8572ad48f1195956276f exitCode: 137 finishedAt: 2019-07-08T01:09:37Z reason: Error startedAt: 2019-07-03T01:58:49Z name: kube-flannel ready: true restartCount: 9 state: running: startedAt: 2019-07-08T03:19:44Z hostIP: 192.168.10.11 initContainerStatuses: - containerID: docker://2b1f8112d5607f278870bac7ea041e04b496be598db142f2f129406f2b6e9d81 image: quay.io/coreos/flannel:v0.11.0-amd64 imageID: docker-pullable://quay.io/coreos/flannel@sha256:7806805c93b20a168d0bbbd25c6a213f00ac58a511c47e8fa6409543528a204e lastState: {} name: install-cni ready: true restartCount: 6 state: terminated: containerID: docker://2b1f8112d5607f278870bac7ea041e04b496be598db142f2f129406f2b6e9d81 exitCode: 0 finishedAt: 2019-07-08T03:19:38Z reason: Completed startedAt: 2019-07-08T03:19:38Z phase: Running podIP: 192.168.10.11 qosClass: Guaranteed startTime: 2019-05-09T01:53:25Z
5、准入控制我们一般很少直接操作,将来做的操作多数情况下都是RBAC和用户创建授权,因此准入控制就先不介绍了