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

  • 相关阅读:
    01、python数据分析与机器学习实战——Python可视化库Seaborn
    01、python数据分析与机器学习实战——Python可视化库Seaborn
    01、python数据分析与机器学习实战——Python可视化库Seaborn
    Sql Server增加字段、修改字段、修改类型、修改默认值 ALTER
    生产者/消费者模式的理解及实现
    生产者/消费者模式的理解及实现
    C# 通过Process.Start() 打开程序 置顶方法
    C# 通过Process.Start() 打开程序 置顶方法
    [C#.Net]判断文件是否被占用的两种方法
    VS2010启动多个实例调试
  • 原文地址:https://www.cnblogs.com/lulin9501/p/12491688.html
Copyright © 2020-2023  润新知