RBAC(Role-Based Access Contrd,基于角色的访问控制) 使用 rbac.authorization.k8s.io API组来推动授权决策,允许管理员通过Kubernetes API动态配置策略。
RBAC API声明了4种Kubernetes对象:Role 、ClusterRole 、RoleBinding 、ClusterRoleBinding ,可以像使用其他API资源一样使用kubectl API调用这些资源对象。例如通过文件创建一个RBAC:kubectl create –f (resource).yml 。
Role和ClusterRole
RBAC 的 Role 或 ClusterRole 中包含一组代表相关权限的规则 。这些权限是纯粹累加的(不存在拒绝某操作的规则)。
Role 总是用来在某个命名空间内 设置访问权限;在创建 Role 时,必须指定该 Role 所属的名字空间 。
与之相对,ClusterRole 则是一个集群作用域的资源 。
ClusterRole 有若干用法:
定义对某命名空间域对象的访问权限,并将在个别命名空间内被授予访问权限;
为命名空间作用域的对象设置访问权限,并被授予跨所有命名空间的访问权限;
如果你希望在命名空间内定义角色,应该使用 Role; 如果你希望定义集群范围的角色,应该使用 ClusterRole。
提示:
这两种资源的名字不同(Role 和 ClusterRole) 是因为 Kubernetes 对象要么是命名空间作用域的,要么是集群作用域的,不可两者兼具。
Role 示例
下面是一个位于 "default" 名字空间的 Role 的示例,可用来授予对 Pod 的读访问权限:
复制 apiVersion : rbac.authorization.k8s.io/v1
kind : Role
metadata :
namespace : default
name : pod-reader
rules :
- apiGroups : [ "" ] # "" 标明 core API 组
resources : [ "pods" ]
verbs : [ "get" , "watch" , "list" ]
ClusterRole 示例
ClusterRole 同样可以用于授予 Role 能够授予的权限。 因为 ClusterRole 属于集群范围,所以它也可以为以下资源授予访问权限:
跨命名空间访问的命名空间作用域的资源(如 Pod)
比如,你可以使用 ClusterRole 来允许某特定用户执行 kubectl get pods --all-namespaces
下面是一个 ClusterRole 的示例,可用来为任一特定命名空间中的 Secret 授予读访问权限 , 或者跨命名空间的访问权限 (取决于该角色是如何绑定的):
复制 apiVersion : rbac.authorization.k8s.io/v1
kind : ClusterRole
metadata :
# "namespace" 被忽略,因为 ClusterRoles 不受命名空间限制
name : secret-reader
rules :
- apiGroups : [ "" ]
# 在 HTTP 层面,用来访问 Secret 资源的名称为 "secrets"
resources : [ "secrets" ]
verbs : [ "get" , "watch" , "list" ]
RoleBinding 和 ClusterRoleBinding
角色绑定(Role Binding)是将角色中定义的权限赋予一个或者一组用户。
它包含若干主体(Subject) (用户、组或服务账户)的列表和对这些主体所获得的角色 的引用。
RoleBinding 在指定的命名空间中执行授权 ,而 ClusterRoleBinding 在集群范围执行授权 。
一个 RoleBinding 可以引用同一的命名空间中的任何 Role 。或者,一个 RoleBinding 可以引用某 ClusterRole 并将该 ClusterRole 绑定到 RoleBinding 所在的命名空间 。
如果你希望将某 ClusterRole 绑定到集群中所有命名空间,你要使用 ClusterRoleBinding。
RoleBinding 示例
下面的例子中的 RoleBinding 将 "pod-reader " Role 授予在 "default " 命名空间中的用户 "jane" 。 这样,用户 "jane" 就具有了读取 "default" 命名空间中所有 Pod 的权限。
复制 apiVersion : rbac.authorization.k8s.io/v1
# 此角色绑定允许 "jane" 读取 "default" 命名空间中的 Pod
# 你需要在该命名空间中有一个名为 “pod-reader” 的 Role
kind : RoleBinding
metadata :
name : read-pods
namespace : default
subjects :
# 你可以指定不止一个“subject(主体)”
- kind : User
name : jane # "name" 是区分大小写的
apiGroup : rbac.authorization.k8s.io
roleRef :
# "roleRef" 指定与某 Role 或 ClusterRole 的绑定关系
kind : Role # 此字段必须是 Role 或 ClusterRole
name : pod-reader # 此字段必须与你要绑定的 Role 或 ClusterRole 的名称匹配
apiGroup : rbac.authorization.k8s.io
RoleBinding 也可以引用 ClusterRole,以将对应 ClusterRole 中定义的访问权限授予 RoleBinding 所在命名空间的资源 。这种引用使得你可以跨整个集群定义一组通用的角色, 之后在多个命名空间中复用。
例如,尽管下面的 RoleBinding 引用的是一个 ClusterRole ,"dave"(这里的主体, 区分大小写)只能访问 "development" 命名空间中的 Secret 对象,因为 RoleBinding 所在的命名空间(由其 metadata 决定)是 "development" 。
复制 apiVersion : rbac.authorization.k8s.io/v1
# 此角色绑定使得用户 "dave" 能够读取 "development" 命名空间中的 Secret
# 你需要一个名为 "secret-reader" 的 ClusterRole
kind : RoleBinding
metadata :
name : read-secrets
# RoleBinding 的命名空间决定了访问权限的授予范围。
# 这里隐含授权仅在 "development" 命名空间内的访问权限。
namespace : development
subjects :
- kind : User
name : dave # 'name' 是区分大小写的
apiGroup : rbac.authorization.k8s.io
roleRef :
kind : ClusterRole
name : secret-reader
apiGroup : rbac.authorization.k8s.io
ClusterRoleBinding 示例
要跨整个集群完成访问权限的授予,你可以使用一个 ClusterRoleBinding 。下面的 ClusterRoleBinding 允许 "manager" 组内的所有用户访问 任何命名空间 中的 Secret。
复制 apiVersion : rbac.authorization.k8s.io/v1
# 此集群角色绑定允许 “manager” 组中的任何人访问任何命名空间中的 Secret 资源
kind : ClusterRoleBinding
metadata :
name : read-secrets-global
subjects :
- kind : Group
name : manager # 'name' 是区分大小写的
apiGroup : rbac.authorization.k8s.io
roleRef :
kind : ClusterRole
name : secret-reader
apiGroup : rbac.authorization.k8s.io
对资源的引用
在 Kubernetes API 中,大多数资源都是使用对象名称的字符串表示来呈现与访问的。 例如,对于 Pod 应使用 "pods"。 RBAC 使用对应 API 端点的 URL 中呈现的名字来引用资源。 有一些 Kubernetes API 涉及子资源(subresource) ,例如 Pod 的日志。 对 Pod 日志的请求看起来像这样:
复制 GET /api/v1/namespaces/{namespace}/pods/{name}/log
在这里,pods 对应命名空间作用域的 Pod 资源,而 log 是 pods 的子资源。 在 RBAC 中表达子资源时,使用斜线(/)来分隔资源和子资源。 要允许某主体读取 pods 同时访问这些 Pod 的 log 子资源,你可以这样写:
复制 apiVersion : rbac.authorization.k8s.io/v1
kind : Role
metadata :
namespace : default
name : pod-and-pod-logs-reader
rules :
- apiGroups : [ "" ]
resources : [ "pods" , "pods/log" ]
verbs : [ "get" , "list" ]
对于某些请求,也可以通过 resourceNames 列表按名称引用资源 。 在指定时,可以将请求限定为资源的单个实例 。 下面的例子中限制可以 get 和 update 一个名为 my-configmap 的 ConfigMap:
复制 apiVersion : rbac.authorization.k8s.io/v1
kind : Role
metadata :
namespace : default
name : configmap-updater
rules :
- apiGroups : [ "" ]
# 在 HTTP 层面,用来访问 ConfigMap 资源的名称为 "configmaps"
resources : [ "configmaps" ]
resourceNames : [ "my-configmap" ]
verbs : [ "update" , "get" ]
说明:
不能使用资源名字来限制 create 或者 deletecollection 请求。 对于 create 请求而言,这是因为在鉴权时可能还不知道新对象的名字。
可以使用通配符 * 批量引用所有的 resources、apiGroups 和 verbs 对象 ,无需逐一引用。
对于 nonResourceURLs,你可以将通配符 * 作为后缀实现全局通配。
对于 resourceNames,空集表示没有任何限制。
下面的示例对 example.com API 组中所有当前和未来资源执行所有动作。 这类似于内置的 cluster-admin。
复制 apiVersion : rbac.authorization.k8s.io/v1
kind : Role
metadata :
namespace : default
name : example.com-superuser # 此角色仅作示范,请勿使用
rules :
- apiGroups : [ "example.com" ]
resources : [ "*" ]
verbs : [ "*" ]
注意:
在 resources 和 verbs 条目中使用通配符会为敏感资源授予过多的访问权限。 例如,如果添加了新的资源类型、新的子资源或新的自定义动词, 通配符条目会自动授予访问权限,用户可能不希望出现这种情况。
应该执行最小特权原则, 使用具体的 resources 和 verbs 确保仅赋予工作负载正常运行所需的权限。
聚合的 ClusterRole
可以将若干 ClusterRole 聚合(Aggregate) 起来,形成一个复合的 ClusterRole。
作为集群控制面的一部分,控制器会监视带有 aggregationRule 的 ClusterRole 对象集合。aggregationRule 为控制器定义一个标签选择算符 供后者匹配应该组合到当前 ClusterRole 的 roles 字段中的 ClusterRole 对象。
下面是一个聚合 ClusterRole 的示例:
复制 apiVersion : rbac.authorization.k8s.io/v1
kind : ClusterRole
metadata :
name : monitoring
aggregationRule :
clusterRoleSelectors :
- matchLabels :
rbac.example.com/aggregate-to-monitoring : "true"
rules : [] # 控制面自动填充这里的规则
如果你创建一个与某个已存在的聚合 ClusterRole 的标签选择算符匹配的 ClusterRole, 这一变化会触发新的规则被添加到聚合 ClusterRole 的操作。
下面的例子中,通过创建一个标签同样为 rbac.example.com/aggregate-to-monitoring: true 的 ClusterRole,新的规则可被添加到 "monitoring" ClusterRole 中。
复制 apiVersion : rbac.authorization.k8s.io/v1
kind : ClusterRole
metadata :
name : monitoring-endpoints
labels :
rbac.example.com/aggregate-to-monitoring : "true"
# 当你创建 "monitoring-endpoints" ClusterRole 时,
# 下面的规则会被添加到 "monitoring" ClusterRole 中
rules :
- apiGroups : [ "" ]
resources : [ "services" , "endpointslices" , "pods" ]
verbs : [ "get" , "list" , "watch" ]
默认的面向用户的角色使用 ClusterRole 聚合 。 这使得你可以扩展默认规则,包括为定制资源设置规则, 比如通过 CustomResourceDefinitions 或聚合 API 服务器提供的定制资源。
例如,下面的 ClusterRoles 让默认角色 "admin" 和 "edit" 拥有管理自定义资源 "CronTabs" 的权限, "view" 角色对 CronTab 资源拥有读操作权限。 你可以假定 CronTab 对象在 API 服务器所看到的 URL 中被命名为 "crontabs"。
复制 apiVersion : rbac.authorization.k8s.io/v1
kind : ClusterRole
metadata :
name : aggregate-cron-tabs-edit
labels :
# 添加以下权限到默认角色 "admin" 和 "edit" 中
rbac.authorization.k8s.io/aggregate-to-admin : "true"
rbac.authorization.k8s.io/aggregate-to-edit : "true"
rules :
- apiGroups : [ "stable.example.com" ]
resources : [ "crontabs" ]
verbs : [ "get" , "list" , "watch" , "create" , "update" , "patch" , "delete" ]
---
kind : ClusterRole
apiVersion : rbac.authorization.k8s.io/v1
metadata :
name : aggregate-cron-tabs-view
labels :
# 添加以下权限到 "view" 默认角色中
rbac.authorization.k8s.io/aggregate-to-view : "true"
rules :
- apiGroups : [ "stable.example.com" ]
resources : [ "crontabs" ]
verbs : [ "get" , "list" , "watch" ]
RoleBinding 或者 ClusterRoleBinding 可绑定角色到某主体(Subject) 上。 主体可以是组,用户或者服务账户。
Kubernetes 用字符串 来表示用户名 。
或者是邮件风格的名称,如 "bob@example.com";
Kubernetes 管理员负责配置身份认证模块 , 以便后者能够生成你所期望的格式的用户名。
注意:
前缀 system: 是 Kubernetes 系统保留的,所以你要确保所配置的用户名或者组名不能出现上述 system: 前缀。
除了对前缀的限制之外,RBAC 鉴权系统不对用户名格式作任何要求。
在 Kubernetes 中,身份认证(Authenticator)模块提供用户组信息 。与用户名一样,用户组名也用字符串来表示,而且对该字符串没有格式要求, 只是不能使用保留的前缀 system:。
服务账户(ServiceAccount) 的用户名前缀为 system:serviceaccount:,属于前缀为 system:serviceaccounts: 的用户组。
system:serviceaccount: (单数)是用于服务账户用户名的前缀;
system:serviceaccounts: (复数)是用于服务账户组名的前缀。
RoleBinding 示例
下面示例是 RoleBinding 中的片段,仅展示其 subjects 的部分。
对于名称为 alice@example.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
对于在任何名字空间中的服务账户:
复制 subjects :
- kind : Group
name : system:serviceaccounts
apiGroup : rbac.authorization.k8s.io
对于所有已经过身份认证的用户:
复制 subjects :
- kind : Group
name : system:authenticated
apiGroup : rbac.authorization.k8s.io
对于所有未通过身份认证的用户:
复制 subjects :
- kind : Group
name : system:unauthenticated
apiGroup : rbac.authorization.k8s.io
对于所有用户:
复制 subjects :
- kind : Group
name : system:authenticated
apiGroup : rbac.authorization.k8s.io
- kind : Group
name : system:unauthenticated
apiGroup : rbac.authorization.k8s.io