您的位置:首页 > 其它

kubernetes 1.6 RBAC访问控制

2017-08-17 15:16 302 查看
一、简介

之前,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将角色绑定到subjects。 subjects可以是 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-usersystem:authenticated and system:unauthenticatedgroups允许用户只读访问有关自己的基本信息。
system:discoverysystem:authenticated and system:unauthenticatedgroups允许只读访问API发现端点,以发现和协商API级别。

User-facing Roles

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

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

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

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

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

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

Core Component Roles

默认ClusterRole默认ClusterRoleBinding描述
system:kube-schedulersystem:kube-scheduler user允许访问kube-scheduler组件所需的资源。
system:kube-controller-managersystem:kube-controller-manager user允许访问kube-controller-manager组件所需的资源。 控制器角色中包含单个控制循环所需的权限。
system:nodesystem: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-proxiersystem:kube-proxy user允许访问kube-proxy组件所需的资源

Other Component Roles

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

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对象。

授予他们绑定特定角色所需的权限:

隐含地,通过给他们角色中包含的权限。

明确地说,通过授予他们在特定角色(或群集角色)上执行绑定动词的权限。

例如,此集群角色和角色绑定将允许“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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: