十六 RBAC

Posted lulin9501

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了十六 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
技术图片

    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和用户创建授权,因此准入控制就先不介绍了

以上是关于十六 RBAC的主要内容,如果未能解决你的问题,请参考以下文章

RBAC从入门到精通

yii rbac管理

Rbac_权限管理

深度解析RBAC用户-角色-权限设计方案,以及核心逻辑代码的讲解

干货分享对于RBAC与shiro的一点理解

聊一个 GitHub 上开源的 RBAC 权限管理系统,很6!