权限管理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 的读访问权限:
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 属于集群范围,所以它也可以为以下资源授予访问权限:
集群范围资源(比如节点(Node))
非资源端点(比如 /healthz)
跨命名空间访问的命名空间作用域的资源(如 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"]
可以使用通配符 * 批量引用所有的 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 用字符串来表示用户名。
用户名可以是普通的用户名,像 "alice";
或者是邮件风格的名称,如 "bob@example.com";
或者是以字符串形式表达的数字 ID。
Kubernetes 管理员负责配置身份认证模块, 以便后者能够生成你所期望的格式的用户名。
注意:
前缀 system: 是 Kubernetes 系统保留的,所以你要确保所配置的用户名或者组名不能出现上述 system: 前缀。
除了对前缀的限制之外,RBAC 鉴权系统不对用户名格式作任何要求。
在 Kubernetes 中,身份认证(Authenticator)模块提供用户组信息。与用户名一样,用户组名也用字符串来表示,而且对该字符串没有格式要求, 只是不能使用保留的前缀 system:。
服务账户(ServiceAccount) 的用户名前缀为 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
最后更新于
这有帮助吗?