• k8s的认证-RBAC机制


    引言:
    https://kubernetes.io/docs/reference/access-authn-authz/rbac/
    Role-based access control (RBAC) :
    基于角色的权限控制,在k8s为了实现这种机制,是利用四种object:Role, ClusterRole, RoleBinding and ClusterRoleBinding来达成权限控制的
    整体的核心思想是k8s的rbac是白名单机制,想让他具备什么权限,就先创建某个角色Role然后定制rules,再将某个用户user与该role进行绑定bind得到这种绑定关系为RoleBind
     
    一,相关的API Object
    1.Role and ClusterRole
    一个role或者cluster role这样的object,包含了若干的rules,这些rules代表是一组的permissions(准入,权限),这些准入是叠加起作用的,并且不存在deny规则,即都是"允许干xxx",而不是"不允许干xxx"....
    1)role: 他属于某个特定的namespace,所以你创建的时候就该指定你创建的role属于哪个namespace。
    2)clusterRole
         定义:  是一个集群范围的概念,也就是说他并不属于某个特定的namespce,他有很多用法,例如:
    define permissions on namespaced resources and be granted within individual namespace(s)
    define permissions on namespaced resources and be granted across all namespaces
    define permissions on cluster-scoped resources

          wxy: 虽然clusterRole是没有namespace概念的,但是他在赋予的时候,是可以具体到某个单独的ns,当然也可以是所有ns,具体用法见后面
         使用: clusterRole也可以像Role一样使用,毕竟他是集群级别的,所以可以在如下的场景下进行权限的赋予:
    cluster-scoped resources (like nodes)
    non-resource endpoints (like /healthz)
    namespaced resources (like Pods), across all namespaces For example:  kubectl get pods --all-namespaces.
           注:  是不可以定义ClusterRole为哪个namespace的,即不可以namespaced。 wxy: 使用时可以....
      
    总结起来就是,想要顶一个额在namespace内使用的角色,用Role类型object,想要一个集群范围内的role则ClusterRole,
    另外,a ClusterRole that can be used to grant read access to SOME OBJECT  in any particular namespace, or across all namespaces (depending on how it is bound),所以接下来看看绑定相关的object。
     
    k8s的api举例:
    例1:
    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      ...
    rules:
    - apiGroups: [""] # "" indicates the core API group
      resources: ["pods"]
      verbs: ["get", "watch", "list"]
    例2:
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
    ...
    注意:
    # kubectl get Role -nkube-system

    # kubectl get  ClusterRole
    解析:
    ClusterRole是集群范围的object,所以不需要指定ns直接查看,Role是特定某个ns下的object,所以需要指定查看的是哪个ns

    2.RoleBinding and ClusterRoleBinding
    所谓role bingding,就是指将role中定义的权限赋予某个用户,或者一组用户。这里面涉及多种概念包括users, groups, or service accounts,   以及所赋予的role的引用。RoleBinding授予特定命名空间中的权限,而ClusterRoleBinding授予在群集范围内访问的权限。
    RoleBinding可以引用同一名称空间中的任何Role。或者,RoleBinding也可以引用ClusterRole并将该ClusterRole绑定到RoleBinding所属的名称空间。如果要将ClusterRole绑定到群集中的所有名称空间,请使用ClusterRoleBinding
    另外,根据官网的信息,以及实际操作发现,如果创建ClusterRoleBinding时指定namespace, 虽然不会报错但也不会生效
               wxy: 这个和如果为服务账号创建绑定时指定的namespace不是一回事。
    wxy:role只是规则,规则是给人用的,这里的人可以是用户,组,或服务账户,赋予user某种role,该user就具备了哪些权限,所以xxBinding的作用就是“赋予”这种行为,确切的说是给自己旗下的user挑选一个role,即指定一个role引用。
        注意:()roleBind操作是站在用户的角度,去选择role,引用的这个role可以是本namespace下的,也可以是                  整个集群的,一旦是集群下的role,那么就相当于给这个role缩小了范围,和namespace范围的rule没什么区别了。如果是想让这个集群级用户能具备某种集群级权限,则就必须要使用ClusterRoleBinding的引用。
     所以,可以在整个集群中定义一组通用角色,然后在多个名称空间中重用它们。

    举例说明
    例1:RoleBinding的用法1:针对某个namespace进行Role级别权限的赋予
    仅赋予jane操作default命名空间的资源,至于具体能操作哪些,要看pod-reader这个规则的具体定义
    apiVersion: rbac.authorization.k8s.io/v1
    # This role binding allows "jane" to read pods in the "default" namespace.You need to already have a Role named "pod-reader" in that namespace.
    kind: RoleBinding
    metadata:
      name: read-pods
      namespace: default
    subjects:
    # You can specify more than one "subject"
    - kind: User
      name: jane
      apiGroup: rbac.authorization.k8s.io
    roleRef:
      # "roleRef" specifies the binding to a Role / ClusterRole
      kind: Role #this must be Role or ClusterRole
      name: pod-reader # this must match the name of the Role or ClusterRole you wish to bind to
      apiGroup: rbac.authorization.k8s.io
    例2: RoleBinding的用法2:  针对某个namespace进行ClusterRole级别权限的赋予
    仅赋予dave操作development命名空间的资源,至于具体能操作哪些,要看secret-reader这个规则的具体定义
    wxy: ClusterRole和Role虽然在这里的用法没有什么区别,但是显而易见,secret-reader是集群级别的,所以可以复用到多个ns下
    apiVersion: rbac.authorization.k8s.io/v1
    # This role binding allows "dave" to read secrets in the "development" namespace. You need to already have a ClusterRole named "secret-reader".
    kind: RoleBinding
    metadata:
      name: read-secrets
      # The namespace of the RoleBinding determines where the permissions are granted.This only grants permissions within the "development" namespace.
      namespace: development
    subjects:
    - kind: User   ---也可以是Group,表示赋予谁...
      name: dave
      apiGroup: rbac.authorization.k8s.io
    roleRef:
      kind: ClusterRole
      name: secret-reader
      apiGroup: rbac.authorization.k8s.io
    例3: ClusterRoleBinding的用法: 给用户赋予一个ClusterRole级别的权限,让其可以操作整个集群
     
     
    小小结:
    一: 给用户赋予命名空间级别(ns)的权限
         1)ns下创建RoleBinding(manifest中需要指定namespace), 绑定ns下的Role,
         2)ns下创建RoleBinding(manifest中需要指定namespace),绑定集群级别的ClusterRole
    二:给用户赋予集群级别的权限
         1)创建ClusterRoleBinding(manifest中不需要指定namespace,指定了也不生效),绑定集群级别的ClusterRole
     
     
    二. 聚合ClusterRoles(Aggregated ClusterRoles)
    我们可以将多个ClusterRole汇聚到一个联合ClusterRole中. 对于一个controller,作为集群控制平面的一部分,会一直watch 携带aggregationRule set的ClusterRole对象。
    aggregationRule定义了一个标签selector,controller使用这个selector与其他ClusterRole进行匹配,匹配成功的ClusterRole将会被导入到该对象的rules中。
    例如:
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      name: monitoring
    aggregationRule:
      clusterRoleSelectors:
      - matchLabels:
          rbac.example.com/aggregate-to-monitoring: "true"    ---如果有一个ClusterRole,他携带的labels符合我的要求,则他的rules会自动填充到我的rules中
    rules: [] # The control plane automatically fills in the rules

    对于缺省的面向用户的roles使用ClusterRole 聚合的,会让作为集群管理员的你,将针对用户资源或者聚合API server的rules都包含进来,即扩展了缺省roles。
     
     

    三:  缺省角色和角色绑定
    API servers 创建了一组缺省的ClusterRole以及ClusterRoleBinding对象,他们大部分是以system:为前缀的,这表示这些资源是直接受集群的控制平面管理的,所有的缺省ClusterRoles和ClusterRoleBindings都被打上了kubernetes.io/bootstrapping=rbac-defaults这个标签。
    自动调谐(Auto-reconciliation)
    每一次的启动,API server都会更新那些with any missing permissions的缺省集群角色 ,并且更新那些 with any missing subjects的集群角色绑定,这样使得集群能够修复那些意外的修改,从而一旦新Kubernetes版本中有权限和主题的更改,有助于保持角色和角色绑定为最新。
    要选择退出这种调谐,那么需要将缺省群集角色或角色绑定上的rbac.authorization.kubernetes.io/autoupdate 注解设置为false。请注意,缺少默认权限和主题可能会导致群集无法正常运行。如果RBAC authorizer 模块处于活动状态,则默认情况下会启用自动调谐。

    1.API discovery 角色
     对于无论是否经过身份验证的用户, 缺省的角色绑定都允许他们 去读取 被认可为公开访问是安全的API 信息(包括CRD)。如果想要禁止未经身份验证的匿名用户访问,则需要在API server的配置中添加上 --anonymous-auth=false。
    想要看看这方面的配置信息,可以使用如下的命令:
    kubectl get clusterroles system:discovery -o yaml

    2. User-facing 角色(面向用户的角色)
     一些缺省的ClusterRoles是不带"system:"前缀,这意味他们是面向用户的角色,其中包括超级用户角色(cluster-admin), 这些角色如果是要在集群范围内被授予,则通过ClusterRoleBindings,如果是想要在ns范围内被授予,则使用RoleBindings (admin, edit, view).
    面向用户的ClusterRoles,是 使用ClusterRole aggregation 机制来允许管理员将针对custom resource的rules包含在自己的ClusterRoles中。为了给admin, edit, or view这些角色添加rules,则需要创建的ClusterRoles具备以下一个或多个labels:
    metadata:
      labels:
        rbac.authorization.k8s.io/aggregate-to-admin: "true"
        rbac.authorization.k8s.io/aggregate-to-edit: "true"
        rbac.authorization.k8s.io/aggregate-to-view: "true"

    3.Core component 角色(核心组件角色)
    system:kube-scheduler
    system:volume-scheduler
    ...
     
    4.Other component 角色
    system:node-bootstrapper
    ...

    5.for built-in controllers的角色
     
    三,权限提升预测机制 和 bootstrapping
    RBAC API通过编辑角色或角色绑定来防止用户提升特权。因为这是在API 级别强制执行的,所以即使未使能RBAC授权,它也适用。
    wxy: 我理解他的意思是说,因为所有的操作都是通过调用api完成的,所以你不可能随心所欲提升权限,因为api本身就是一道关卡。
     
     
     
     
    N: ServiceAccount权限
    缺省的RBAC策略向控制平面组件,节点,controller授予了有限范围的权限,但并没有对kube-system namespace之外的的服务账户授予任何权限(除了给所有认证用户授予了discovery权限)
     
     
     
     
    =============================
    一个利用RBAC进行权限管控的实现方案
    前情提要:
    一个第三方软件通过读取/etc/kubernetes/admin.conf(使用kubeadmin部署的集群会存在这个文件)文件中的证书信息,以超级管理员的身份操作集群
    目前的需求是:限制第三方的权限,让其只可以访问指定namespace下的资源,和不属于namespace范畴的资源
     
    实现步骤:
    第0步: 准备一个即将被第三方托管的集群,确定使用的命名空间,且这些命名空间需确实存在
     
    第1步: 创建一个用户,并为这个用户签发证书,假如这个用户叫做wxy,命令如下:
    openssl genrsa -out wxy.key 2048
    openssl req -new -key wxy.key -out wxy.csr -subj "/CN=wxy"
    openssl x509 -req -in wxy.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -out wxy.crt -days 3650
    说明: 其中CA的路径必须是集群的根证书所在路径,一般情况下都是/etc/kubernetes/pki/
     

    第2步: 替换/etc/kubernetes/admin.conf 中的相关的内容,
    1)将上一步中生成的证书文件进行base64加密
    cat wxy.crt |base64 --wrap=0
    cat wxy.key |base64 --wrap=0
    2)修改配置文件,需替换部分如下:
    # vi /etc/kubernetes/admin.conf
    ...
    aXRLTGJsMVRoc29lZ1lWemVDWGJHbTE0S3IrbjhuU2JGTkdUOD0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
        server: https://192.168.48.232:6443
      name: kubernetes
    contexts:
    - context:
        cluster: kubernetes
        user: wxy   ---替换成自定义用户
      name: wxy@kubernetes     ---替换成自定义用户
    current-context: wxy@kubernetes   ---替换成自定义用户
    kind: Config
    preferences: {}
    users:
    - name: wxy   ---替换成自定义用户
      user:
        client-certificate-data: {{---替换成wxy.crt加密后的内容---}}
        client-key-data: {{---替换成wxy.key加密后的内容---}}
     
    第3步: 创建role,一个用来限制自定义用户权限的资源类型,这个权限的规则遵从k8s的RBAC,可根据需要自行定制
           在这里我创建了一个角色允许其获取节点信息,namespace信息,创建PV,而其他属于namespace范畴下的资源则不允许访问
    wxy-admin.json:从edit 和  system:node中继承来的

    第4步: 将角色role与我们自定义用户进行绑定,命令如下:
    1)与上一步创建的自定义角色wxy-admin绑定
    kubectl create clusterrolebinding wxy-admin-binding --clusterrole=wxy-admin --user=wxy
     
    2)与k8s内置的集群管理员角色cluster-admin进行绑定,但要求其只在001命名空间下具有该角色,达到权限缩小到namespace的目的
    kubectl create rolebinding wxy-001-admin-binding --clusterrole=cluster-admin --user=wxy--namespace=001
     
    另:
    如果查看的是不允许的namespace下资源,则会报错,比如如下:
    Failure executing: GET at: https://x.x.x.x:6443/api/v1/namespaces/kube-system/pods. Message: Forbidden! User kubernetes-admin doesn't have permission. pods is forbidden: User "wxy" cannot list resource "pods" in API group "" in the namespace "kube-system"
    根据错误信息就可以知道,因为权限问题,请求被拒绝了!
     
     
       
     
     
  • 相关阅读:
    java前三章总结
    Java入门第二章
    java编程入门小结
    Java入门第二章
    java预习易错点
    计算机基础
    切换卡
    ajax
    水印4
    shuiyin3
  • 原文地址:https://www.cnblogs.com/shuiguizi/p/13143319.html
Copyright © 2020-2023  润新知