权限管理RBAC
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 示例
下面是一个位于 "default" 名字空间的 Role 的示例,可用来授予对 Pod 的读访问权限:
ClusterRole 示例
ClusterRole 同样可以用于授予 Role 能够授予的权限。 因为 ClusterRole 属于集群范围,所以它也可以为以下资源授予访问权限:
集群范围资源(比如节点(Node))
非资源端点(比如 /healthz)
跨命名空间访问的命名空间作用域的资源(如 Pod)
比如,你可以使用 ClusterRole 来允许某特定用户执行 kubectl get pods --all-namespaces
下面是一个 ClusterRole 的示例,可用来为任一特定命名空间中的 Secret 授予读访问权限, 或者跨命名空间的访问权限(取决于该角色是如何绑定的):
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 的权限。
RoleBinding 也可以引用 ClusterRole,以将对应 ClusterRole 中定义的访问权限授予 RoleBinding 所在命名空间的资源。这种引用使得你可以跨整个集群定义一组通用的角色, 之后在多个命名空间中复用。
例如,尽管下面的 RoleBinding 引用的是一个 ClusterRole,"dave"(这里的主体, 区分大小写)只能访问 "development" 命名空间中的 Secret 对象,因为 RoleBinding 所在的命名空间(由其 metadata 决定)是 "development"。
ClusterRoleBinding 示例
要跨整个集群完成访问权限的授予,你可以使用一个 ClusterRoleBinding。下面的 ClusterRoleBinding 允许 "manager" 组内的所有用户访问任何命名空间中的 Secret。
对资源的引用
在 Kubernetes API 中,大多数资源都是使用对象名称的字符串表示来呈现与访问的。 例如,对于 Pod 应使用 "pods"。 RBAC 使用对应 API 端点的 URL 中呈现的名字来引用资源。 有一些 Kubernetes API 涉及子资源(subresource),例如 Pod 的日志。 对 Pod 日志的请求看起来像这样:
在这里,pods 对应命名空间作用域的 Pod 资源,而 log 是 pods 的子资源。 在 RBAC 中表达子资源时,使用斜线(/)来分隔资源和子资源。 要允许某主体读取 pods 同时访问这些 Pod 的 log 子资源,你可以这样写:
对于某些请求,也可以通过 resourceNames 列表按名称引用资源。 在指定时,可以将请求限定为资源的单个实例。 下面的例子中限制可以 get 和 update 一个名为 my-configmap 的 ConfigMap:
可以使用通配符 * 批量引用所有的 resources、apiGroups 和 verbs 对象,无需逐一引用。
对于 nonResourceURLs,你可以将通配符 * 作为后缀实现全局通配。
对于 resourceNames,空集表示没有任何限制。
下面的示例对 example.com API 组中所有当前和未来资源执行所有动作。 这类似于内置的 cluster-admin。
注意:
在 resources 和 verbs 条目中使用通配符会为敏感资源授予过多的访问权限。例如,如果添加了新的资源类型、新的子资源或新的自定义动词, 通配符条目会自动授予访问权限,用户可能不希望出现这种情况。
应该执行最小特权原则, 使用具体的 resources 和 verbs 确保仅赋予工作负载正常运行所需的权限。
聚合的 ClusterRole
可以将若干 ClusterRole 聚合(Aggregate) 起来,形成一个复合的 ClusterRole。
作为集群控制面的一部分,控制器会监视带有 aggregationRule 的 ClusterRole 对象集合。aggregationRule 为控制器定义一个标签选择算符供后者匹配应该组合到当前 ClusterRole 的 roles 字段中的 ClusterRole 对象。
下面是一个聚合 ClusterRole 的示例:
如果你创建一个与某个已存在的聚合 ClusterRole 的标签选择算符匹配的 ClusterRole, 这一变化会触发新的规则被添加到聚合 ClusterRole 的操作。
下面的例子中,通过创建一个标签同样为 rbac.example.com/aggregate-to-monitoring: true 的 ClusterRole,新的规则可被添加到 "monitoring" ClusterRole 中。
默认的面向用户的角色使用 ClusterRole 聚合。 这使得你可以扩展默认规则,包括为定制资源设置规则, 比如通过 CustomResourceDefinitions 或聚合 API 服务器提供的定制资源。
例如,下面的 ClusterRoles 让默认角色 "admin" 和 "edit" 拥有管理自定义资源 "CronTabs" 的权限, "view" 角色对 CronTab 资源拥有读操作权限。 你可以假定 CronTab 对象在 API 服务器所看到的 URL 中被命名为 "crontabs"。
RoleBinding 或者 ClusterRoleBinding 可绑定角色到某主体(Subject)上。 主体可以是组,用户或者服务账户。
Kubernetes 用字符串来表示用户名。
用户名可以是普通的用户名,像 "alice";
或者是邮件风格的名称,如 "bob@example.com";
或者是以字符串形式表达的数字 ID。
Kubernetes 管理员负责配置身份认证模块, 以便后者能够生成你所期望的格式的用户名。
注意:
前缀 system: 是 Kubernetes 系统保留的,所以你要确保所配置的用户名或者组名不能出现上述 system: 前缀。
除了对前缀的限制之外,RBAC 鉴权系统不对用户名格式作任何要求。
在 Kubernetes 中,身份认证(Authenticator)模块提供用户组信息。与用户名一样,用户组名也用字符串来表示,而且对该字符串没有格式要求, 只是不能使用保留的前缀 system:。
服务账户(ServiceAccount) 的用户名前缀为 system:serviceaccount:,属于前缀为 system:serviceaccounts: 的用户组。
system:serviceaccount: (单数)是用于服务账户用户名的前缀;
system:serviceaccounts: (复数)是用于服务账户组名的前缀。
RoleBinding 示例
下面示例是 RoleBinding 中的片段,仅展示其 subjects 的部分。
对于名称为 alice@example.com 的用户:
对于名称为 frontend-admins 的用户组:
对于 kube-system 名字空间中的默认服务账户:
对于 "qa" 名称空间中的所有服务账户:
对于在任何名字空间中的服务账户:
对于所有已经过身份认证的用户:
对于所有未通过身份认证的用户:
对于所有用户:
最后更新于
这有帮助吗?