zoukankan      html  css  js  c++  java
  • kubernetes 1.6 RBAC访问控制

    一、简介

    之前,Kubernetes中的授权策略主要是ABAC(Attribute-Based Access Control)。对于ABAC,Kubernetes在实现上是比较难用的,而且需要Master Node的SSH和根文件系统访问权限,授权策略发生变化后还需要重启API Server。

    Kubernetes 1.6中,RBAC(Role-Based Access Control)基于角色的访问控制进入Beta阶段。RBAC访问控制策略可以使用kubectl或Kubernetes API进行配置。使用RBAC可以直接授权给用户,让用户拥有授权管理的权限,这样就不再需要直接触碰Master Node。在Kubernetes中RBAC被映射成API资源和操作。

    二、RBAC API的资源对象

    在Kubernetes 1.6中通过启动参数--authorization-mode=RBAC.API Overview为API Server启用RBAC。

    使用kubeadm初始化的1.6版本的Kubernetes集群,已经默认为API Server开启了RBAC,可以查看Master Node上API Server的静态Pod定义文件,如果- apiserver底下没有看到

    如果没有下面红色的信息,说明没有启用RBAC

    - apiserver
    - --bind-address=0.0.0.0
    - --secure-port=443
    - --insecure-bind-address=0.0.0.0
    - --insecure-port=8080
    - --allow-privileged=true
    - --service-cluster-ip-range=10.3.0.0/24
    - --advertise-address=172.16.71.200
    - --cors-allowed-origins=.*
    - --admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,ResourceQuota
    - --tls-cert-file=/etc/kubernetes/ssl/apiserver.pem
    - --tls-private-key-file=/etc/kubernetes/ssl/apiserver-key.pem
    - --client-ca-file=/etc/kubernetes/ssl/ca.pem
    - --service-account-key-file=/etc/kubernetes/ssl/apiserver-key.pem
    - --v=3
    - --etcd-servers=http://172.16.71.200:2379,http://172.16.71.201:2379,http://172.16.71.202:2379,http://172.16.71.203:2379

    - --authorization-mode=RBAC

    
    

    RBAC API定义了四个资源对象用于描述RBAC中用户和资源之间的连接权限:

    • Role
    • ClusterRole
    • RoleBinding
    • ClusterRoleBinding

    1、Role和ClusterRole

    在RBAC API中,Role包含表示一组权限的规则。 权限是纯粹的加法(没有“否定”规则)。 一个Role可以在一个namespace中用一个角色来定义,也可以使用ClusterRole在群集范围内定义。

    Role只能用于授予对单个namespace中资源的访问权限。 以下是“default”命名空间中可用于授予对pod的读访问权限的示例:

    kind: Role
    apiVersion: rbac.authorization.k8s.io/v1beta1
    metadata:
      namespace: default
      name: pod-reader
    rules:
    - apiGroups: [""] # "" indicates the core API group
      resources: ["pods"]
      verbs: ["get", "watch", "list"]

    ClusterRole可用于授予与Role相同的权限,但由于它们是集群范围的,因此也可以使用它们来授予对以下内容的访问权限:

    • 集群范围的资源(如nodes)
    • 非资源端点(如“/ healthz”)
    • 在所有namespace中的资源(如pod)(例如:kubectl get pods --all-namespaces)

    以下ClusterRole可用于授予对任何特定namespace或所有namespace中的secrets 的读取访问(取决于其绑定方式):

    kind: ClusterRole
    apiVersion: rbac.authorization.k8s.io/v1beta1
    metadata:
      # "namespace" omitted since ClusterRoles are not namespaced
      name: secret-reader
    rules:
    - apiGroups: [""]
      resources: ["secrets"]
      verbs: ["get", "watch", "list"]

    2、RoleBinding和ClusterRoleBinding

    RoleBinding把Role绑定到账户主体Subject(users, groups, or service accounts),让Subject继承Role所在namespace下的权限。ClusterRoleBinding把ClusterRole绑定到Subject,让Subject集成ClusterRole在整个集群中的权限。

    以下RoleBinding将“pod-reader”角色授予“默认”命名空间中的用户“hzb”。 这允许“hzb”在“默认”命名空间中读取pod。

    # This role binding allows "jane" to read pods in the "default" namespace.
    kind: RoleBinding
    apiVersion: rbac.authorization.k8s.io/v1beta1
    metadata:
      name: read-pods
      namespace: default
    subjects:
    - kind: User
      name: hzb
      apiGroup: rbac.authorization.k8s.io
    roleRef:
      kind: Role
      name: pod-reader
      apiGroup: rbac.authorization.k8s.io

    RoleBinding还可以引用ClusterRole来授予RoleBinding命名空间中ClusterRole中定义的命名空间资源的权限。 这允许管理员为整个集群定义一组通用角色,然后在多个命名空间中重用它们。也就是说,ClusterRole一旦被RoleBinding到某一个namespace中,它只能访问该namesapce中的资源。

    例如,即使以下RoleBinding引用了ClusterRole,“hzb”只能在“development”这个namespace(RoleBinding的命名空间)中读取secrets 。

    # This role binding allows "dave" to read secrets in the "development" namespace.
    kind: RoleBinding
    apiVersion: rbac.authorization.k8s.io/v1beta1
    metadata:
      name: read-secrets
      namespace: development # This only grants permissions within the "development" namespace.
    subjects:
    - kind: User
      name: hzb
      apiGroup: rbac.authorization.k8s.io
    roleRef:
      kind: ClusterRole
      name: secret-reader
      apiGroup: rbac.authorization.k8s.io

    ClusterRoleBinding可以用于在集群级别和所有namespace中授予权限。 以下ClusterRoleBinding允许组“manager”中的任何用户在任何namespace中读取secrets 。

    kind: ClusterRoleBinding
    apiVersion: rbac.authorization.k8s.io/v1beta1
    metadata:
      name: read-secrets-global
    subjects:
    - kind: Group
      name: manager
      apiGroup: rbac.authorization.k8s.io
    roleRef:
      kind: ClusterRole
      name: secret-reader
      apiGroup: rbac.authorization.k8s.io

    3、子资源权限

    大多数资源由其名称的字符串表示形式表示,例如“pod”,就像它出现在相关API端点的URL中一样。 然而,一些Kubernetes API涉及“子资源”,例如pod的日志。 pod的日志端点的URL是:

    GET /api/v1/namespaces/{namespace}/pods/{name}/log

    在这种情况下,“pod”是namespace资源,“log”是pod的子资源。 要在RBAC角色中表示此角色,请使用/来划分资源和子资源。 要允许主题读取pod和pod日志,请写:

    kind: Role
    apiVersion: rbac.authorization.k8s.io/v1beta1
    metadata:
      namespace: default
      name: pod-and-pod-logs-reader
    rules:
    - apiGroups: [""]
      resources: ["pods", "pods/log"]
      verbs: ["get", "list"]

    4、资源名称引用

    Role权限的资源也可以是某一定义好的资源的名称引用,需要在resourceNames中指定名称。 比如限制一个主题只能“获取”和“更新”一个configmap(这个configmap是用户自己定义的一个资源名称),您可以写:

    kind: Role
    apiVersion: rbac.authorization.k8s.io/v1beta1
    metadata:
      namespace: default
      name: configmap-updater
    rules:
    - apiGroups: [""]
      resources: ["configmap"]
      resourceNames: ["my-configmap"]
      verbs: ["update", "get"]

    值得注意的是,如果设置了resourceName,那么以上的verbs不能是list,watch,create或deletecollection。 

    5、Role举例

    以下示例中仅显示了规则部分。

    允许读取核心API组中的资源“pod”:

    rules:
    - apiGroups: [""]
      resources: ["pods"]
      verbs: ["get", "list", "watch"]

    允许在“extensions”和“apps”API组中读/写“deployments”:

    rules:
    - apiGroups: ["extensions", "apps"]
      resources: ["deployments"]
      verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]

    允许读“pod”和阅读/写“jobs”:

    rules:
    - apiGroups: [""]
      resources: ["pods"]
      verbs: ["get", "list", "watch"]
    - apiGroups: ["batch", "extensions"]
      resources: ["jobs"]
      verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]

    允许读取名为“my-config”的ConfigMap(必须使用RoleBinding绑定才能限制在单个namespace中的单个ConfigMap):

    rules:
    - apiGroups: [""]
      resources: ["configmaps"]
      resourceNames: ["my-config"]
      verbs: ["get"]

    允许读取核心组中的资源“nodes”(因为nodes是集群范围的,必须是ClusterRole用ClusterRoleBinding绑定才有效):

    rules:
    - apiGroups: [""]
      resources: ["nodes"]
      verbs: ["get", "list", "watch"]

    允许“GET”和“POST”请求到非资源端点“/ healthz”和所有子路径(必须是ClusterRole用ClusterRoleBinding绑定才有效):

    rules:
    - nonResourceURLs: ["/healthz", "/healthz/*"] # '*' in a nonResourceURL is a suffix glob match
      verbs: ["get", "post"]

    6、给Subjects授权

    RoleBinding或ClusterRoleBinding将角色绑定到subjectssubjects可以是 groups, users or service accounts。

    Subjects 中 Users 使用字符串表示,它可以是一个普通的名字字符串,如 “alice”;也可以是 email 格式的邮箱地址,如 “bob@example.com”;甚至是一组字符串形式的数字 ID。Users 的格式必须满足集群管理员配置的 验证模块 ,RBAC 授权系统中没有对其做任何格式限定; 但是 Users 的前缀 system: 是系统保留的,集群管理员应该确保普通用户不会使用这个前缀格式

    Kubernetes中的groups目前由Authenticator模块提供。 groups表示为字符串,该字符串没有格式要求,除了前缀system:被保留。

    service accounts具有前缀为system:serviceaccount:用户名,属于前缀为system:serviceaccount:的组

    RoleBinding举例:

    以下示例中仅显示了RoleBinding的subjects部分。对于名为“hzb@test.com”的用户:

    subjects:
    - kind: User
      name: "alice@example.com"
      apiGroup: rbac.authorization.k8s.io

    给一个名为frontend-admins的组

    subjects:
    - kind: Group
      name: "frontend-admins"
      apiGroup: rbac.authorization.k8s.io

    对于kube-system命名空间中的默认服务帐户:

    subjects:
    - kind: ServiceAccount
      name: default
      namespace: kube-system

    对于“qa”命名空间中的所有服务帐户:

    subjects:
    - kind: Group
      name: system:serviceaccounts:qa
      apiGroup: rbac.authorization.k8s.io

    对于任何的 service accounts:

    subjects:
    - kind: Group
      name: system:serviceaccounts
      apiGroup: rbac.authorization.k8s.io

    对于所有 authenticated users (version 1.5+):

    subjects:
    - kind: Group
      name: system:authenticated
      apiGroup: rbac.authorization.k8s.io

    对于所有 unauthenticated users (version 1.5+):

    subjects:
    - kind: Group
      name: system:unauthenticated
      apiGroup: rbac.authorization.k8s.io

    对于所有users (version 1.5+):

    subjects:
    - kind: Group
      name: system:authenticated
      apiGroup: rbac.authorization.k8s.io
    - kind: Group
      name: system:unauthenticated
      apiGroup: rbac.authorization.k8s.io

    三、默认的Roles and Role Bindings

    API  servers 创建一组默认的ClusterRole和ClusterRoleBinding对象。 其中许多是system:前缀,表示资源由基础架构“拥有”。 对这些资源的修改可能导致集群异常。 一个例子是system:node。 此角色定义了kubelet的权限。 如果角色被修改,它可能使kubelets无法工作。

    所有的 cluster roles and rolebindings 被label标记为:

    kubernetes.io/bootstrapping=rbac-defaults

    API Server 在每次启动后都会更新已经丢失的默认 ClusterRole 和 其绑定的相关 Subjects;这将允许集群自动修复因为意外更改导致的 RBAC 授权错误,同时能够使在升级集群后基础设施的 RBAC 授权得以自动更新。

    如果想要关闭 API Server 的自动修复功能,只需要将默认创建的 ClusterRole 和其 RoleBind 的 rbac.authorization.kubernetes.io/autoupdate 注解设置为 false 即可,这样做会有很大风险导致集群因为意外修改 RBAC 而无法工作

    Auto-reconciliation 在 1.6+ 版本被默认启用(当 RBAC 授权被激活时)

    Discovery Roles

    默认ClusterRole 默认ClusterRoleBinding 描述
    system:basic-user system:authenticated and system:unauthenticatedgroups 允许用户只读访问有关自己的基本信息。
    system:discovery system:authenticated and system:unauthenticatedgroups 允许只读访问API发现端点,以发现和协商API级别。

    User-facing Roles

    一些默认角色不是system:前缀。 这些是面向用户的角色。 它们包括超级用户角色(cluster-admin),旨在使用ClusterRoleBindings(cluster-status)授予集群范围的角色,以及旨在使用RoleBindings(admin,edit,view)在特定命名空间中授予的角色。

    默认ClusterRole 默认ClusterRoleBinding 描述
    cluster-admin system:masters group

    允许超级用户访问对任何资源执行任何操作。如果使用的是ClusterRoleBinding,它可以完全控制集群和所有命名空间中的每个资源,

    当在RoleBinding中使用时,它可以完全控制rolebinding的命名空间中的每个资源,包括命名空间本身。

    admin none

    允许管理员访问,旨在使用RoleBinding授予对命名空间的访问。 如果在RoleBinding中使用,则允许对命名空间中大多数资源进行读/写访问,

    包括在命名空间中创建角色和角色绑定的功能。 它不允许对资源配额或命名空间本身的写访问。

    edit none 允许对命名空间中大多数对象的读/写访问。 它不允许查看或修改Role或RoleBinding。
    view none 允许只读访问查看命名空间中的大多数对象。 它不允许查看或修改Role或RoleBinding。 它不允许查看secrets。

    Core Component Roles

    默认ClusterRole 默认ClusterRoleBinding 描述
    system:kube-scheduler system:kube-scheduler user 允许访问kube-scheduler组件所需的资源。
    system:kube-controller-manager system:kube-controller-manager user 允许访问kube-controller-manager组件所需的资源。 控制器角色中包含单个控制循环所需的权限。
    system:node system:nodes group (deprecated in 1.7) 允许访问kubelet组件所需的资源,包括对所有secrets的读取访问权限,以及对所有pod的访问权限。 从1.7开始,建议使用[Node Authorizer](/ docs / admin / authorization / node /)和[NodeRestriction admission plugin](/docs/admin/admission-controllers#NodeRestriction)而不是此角色,并允许基于计划在其上运行的pod的API访问kubelets。 从1.7开始,当启用“Node”授权模式时,不会自动绑定到“system:nodes”组
    system:node-proxier system:kube-proxy user 允许访问kube-proxy组件所需的资源

    Other Component Roles

    默认ClusterRole 默认ClusterRoleBinding 描述
    system:auth-delegator none 允许委托认证和授权检查。 这通常由附加API服务器用于统一认证和授权。
    system:heapster none Heapster组件的角色
    system:kube-aggregator none kube-aggregator组件的角色。
    system:kube-dns kube-dns service account in the kube-system namespace kube-dns组件的角色
    system:node-bootstrapper none 允许访问执行Kubelet TLS自举所需的资源。
    system:node-problem-detector none node-problem-detector组件的角色
    system:persistent-volume-provisioner none 允许访问大多数动态卷配置所需的资源

    Controller Roles

    Kubernetes控制器管理器运行核心控制环路。 当使用--use-service-account-credentials调用时,每个控制循环都将使用单独的服务帐户启动。 对于每个控制循环,存在相应的角色,前缀为system:controller:。 如果控制器管理器未启动--use-service-account-credentials,它将使用其自己的凭证运行所有控制循环,这些凭证必须被授予所有相关的角色。 这些角色包括:

    • system:controller:attachdetach-controller
    • system:controller:certificate-controller
    • system:controller:cronjob-controller
    • system:controller:daemon-set-controller
    • system:controller:deployment-controller
    • system:controller:disruption-controller
    • system:controller:endpoint-controller
    • system:controller:generic-garbage-collector
    • system:controller:horizontal-pod-autoscaler
    • system:controller:job-controller
    • system:controller:namespace-controller
    • system:controller:node-controller
    • system:controller:persistent-volume-binder
    • system:controller:pod-garbage-collector
    • system:controller:replicaset-controller
    • system:controller:replication-controller
    • system:controller:resourcequota-controller
    • system:controller:route-controller
    • system:controller:service-account-controller
    • system:controller:service-controller
    • system:controller:statefulset-controller
    • system:controller:ttl-controller

    四、特权升级预防和引导

          RBAC API阻止用户通过编辑角色或角色绑定来升级权限。 因为这是在API级别实现的,所以即使RBAC授权器没有被使用也是如此。

          用户即使在对某个 Role 拥有全部权限的情况下也仅能在其作用范围内(ClusterRole -> 集群范围内,Role -> 当前 namespace 或 集群范围)对其进行 create 和 update 操作;

          例如 “user-1” 用户不具有在集群范围内列出 secrets 的权限,那么他也无法在集群范围内创建具有该权限的 ClusterRole,也就是说想传递权限必须先获得该权限;

           想要允许用户 cretae/update Role 有两种方式:

    • 授予一个该用户期望 create/update 的 Role 或者 ClusterRole
    • 授予一个包含该用户期望 create/update 的 Role 或者 ClusterRole 的 Role 或者 ClusterRole(有点绕…);如果用户尝试 crate/update 一个其不拥有的 Role 或者 ClusterRole,则 API 会禁止。 如果他们尝试创建或修改一个Role或ClusterRole的权限,他们自己还没有被授权,API请求将被禁止。

    如果用户想要创建/更新role binding,那么用户必须已经具有包含在引用角色中的所有权限(与角色绑定相同的范围),或者如果已被赋予权限来执行role binding的verb,如果“user-1”无法在群集范围内列出secrets,则不能向授予该权限的角色创建ClusterRoleBinding。

    允许用户创建/更新角色绑定:

    • 授予他们一个角色,允许他们根据需要创建/更新RoleBinding或ClusterRoleBinding对象。
    • 授予他们绑定特定角色所需的权限:
    1. 隐含地,通过给他们角色中包含的权限。
    2. 明确地说,通过授予他们在特定角色(或群集角色)上执行绑定动词的权限。

    例如,此集群角色和角色绑定将允许“user-1”授予其他用户在“user-1-namespace”命名空间中的管理,编辑和查看角色:

    apiVersion: rbac.authorization.k8s.io/v1beta1
    kind: ClusterRole
    metadata:
      name: role-grantor
    rules:
    - apiGroups: ["rbac.authorization.k8s.io"]
      resources: ["rolebindings"]
      verbs: ["create"]
    - apiGroups: ["rbac.authorization.k8s.io"]
      resources: ["clusterroles"]
      verbs: ["bind"]
      resourceNames: ["admin","edit","view"]
    ---
    apiVersion: rbac.authorization.k8s.io/v1beta1
    kind: RoleBinding
    metadata:
      name: role-grantor-binding
      namespace: user-1-namespace
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: role-grantor
    subjects:
    - apiGroup: rbac.authorization.k8s.io
      kind: User
      name: user-1

           当使用 bootstrapping 时,初始用户尚没有访问 API 的权限,此时想要授予他们一些尚未拥有的权限是不可能的,此时可以有两种解决方案:

    • 使用具有system:masters group的credential ,该credential是通过默认绑定绑定到cluster-admin超级用户角色。
    • 如果您的API服务器在启用了不安全端口(--insecure-port)的情况下运行,那么还可以通过该端口进行API调用,不会强制执行身份验证或授权

    五、RBAC命令行工具

    存在两个kubectl命令来在命名空间或整个集群中授予角色

    kubectl create rolebinding

    kubectl create rolebinding bob-admin-binding --clusterrole=admin --user=bob --namespace=acme
    kubectl create rolebinding myapp-view-binding --clusterrole=view --serviceaccount=acme:myapp --namespace=acme

    kubectl create clusterrolebinding

    kubectl create clusterrolebinding root-cluster-admin-binding --clusterrole=cluster-admin --user=root
    kubectl create clusterrolebinding kubelet-node-binding --clusterrole=system:node --user=kubelet
    kubectl create clusterrolebinding myapp-view-binding --clusterrole=view --serviceaccount=acme:myapp

    六、Service Account Permissions

    Service Account概念的引入是基于这样的使用场景:运行在pod里的进程需要调用Kubernetes API以及非Kubernetes API的其它服务。Service Account它并不是给kubernetes集群的用户使用的,而是给pod里面的进程使用的,它为pod提供必要的身份认证。

    默认RBAC策略向 control-plane components, nodes, and controllers授予范围限制的权限,但不向“kube-system”命名空间之外的service accounts授予权限(超出发给所有已验证用户的发现权限)。这允许您根据需要向特定服务帐户授予特定角色。 细粒度角色绑定提供更大的安全性,但需要更多的努力来管理。 更广泛的授权可以给service accounts提供不必要的(可能升级的)API访问,但是更容易管理。

    从最安全到最不安全的的方式如下:

    • 为应用程序特定的服务帐户(最佳实践)授予角色:这要求应用程序在其pod的spec中指定serviceAccountName,并且要创建 service account 。例如,将“my-namespace”中的只读权限授予“my-sa”服务帐户:

             

    kubectl create rolebinding my-sa-view --clusterrole=view --serviceaccount=my-namespace:my-sa --namespace=my-namespace
    • 在命名空间中为“默认” service account 授予角色:如果应用程序没有指定serviceAccountName,它将使用“默认”service account。注意:授予“默认”服务帐户的权限可用于命名空间中未指定serviceAccountName的任何pod。

             例如,将“my-namespace”中的只读权限授予“默认”service account:

    kubectl create rolebinding default-view --clusterrole=view  --serviceaccount=my-namespace:default  --namespace=my-namespace

    许多加载项当前作为“kube-system”命名空间中的“默认”service account运行。 要允许这些加载项使用超级用户访问权限,请将cluster-admin权限授予“kube-system”命名空间中的“默认”服务帐户。注意:启用这意味着“kube-system”命名空间包含授予超级用户访问API的权限。

    kubectl create clusterrolebinding add-on-cluster-admin --clusterrole=cluster-admin --serviceaccount=kube-system:default
    • 为命名空间中的所有service accounts授予角色:如果希望命名空间中的所有应用程序都具有该角色,无论使用什么service accounts,可以将该角色授予该命名空间的service account group 。例如,将“my-namespace”中的只读权限授予该命名空间中的所有service accounts:
    kubectl create rolebinding serviceaccounts-view --clusterrole=view --group=system:serviceaccounts:my-namespace--namespace=my-namespace
    • 对集群范围内的所有service accounts(不鼓励)授予有限的权限:如果您不想管理每个命名空间的权限,则可以将群集范围角色授予所有service accounts。例如,将所有命名空间中的只读权限授予群集中的所有service accounts:
    kubectl create clusterrolebinding serviceaccounts-view --clusterrole=view --group=system:serviceaccounts
    • 授予超级用户访问群集范围内的所有service accounts(强烈不鼓励):如果您根本不关心分区权限,则可以向所有service accounts授予超级用户访问权限。警告:这允许任何具有读取访问权限的用户访问secrets或能够创建一个pod以访问超级用户credentials。
    kubectl create clusterrolebinding serviceaccounts-cluster-admin --clusterrole=cluster-admin --group=system:serviceaccounts
  • 相关阅读:
    KVM源代码阅读--内核版本3.17.4
    最新的裸机联想笔记本装win7系统/SSD(固态硬盘)上安装win7系统/联想K4450A i7装win7系统
    Vmaware复制后的虚拟机不能上网问题解决
    KVM基于X86硬件辅助的虚拟化技术实现机制【转】
    KVM和QEMU简介
    笔记--[基于完全虚拟化的安全监控技术研究_张丽(2013)]
    win8预装系统环境下安装win7问题以及双操作系统安装解决
    VM 操作系统实例化(基于 KVM 的虚拟化研究及应用--崔泽永(2011))的论文笔记
    VMware vsphere Hypervisor、VMware vsphere和VMware Workstation小记
    虚拟化、(完)全虚拟化、半虚拟化和准虚拟化技术个人总结
  • 原文地址:https://www.cnblogs.com/boshen-hzb/p/7381838.html
Copyright © 2011-2022 走看看