本页面简要介绍了 Kubernetes 提供的 RBAC(基于角色的访问权限控制)系统,以及如何在 Google Kubernetes Engine (GKE) 中使用 Kubernetes RBAC。
概览
Kubernetes 内置了一项基于角色的访问权限控制 (RBAC) 机制,可让您配置一组特定的细化权限,以定义某一特定 Google Cloud 用户或用户组如何与集群(或集群的特定命名空间)中的任何 Kubernetes 对象互动。
默认情况下,Kubernetes RBAC 处于启用状态。
准备工作
在开始之前,请确保您已执行以下任务:
- 确保您已启用 Google Kubernetes Engine API。 启用 Google Kubernetes Engine API
- 确保您已安装 Cloud SDK。
使用以下任一方法设定默认的 gcloud
设置:
- 使用
gcloud init
(如果您想要在系统引导下完成默认设置)。 - 使用
gcloud config
(如果您想单独设置项目 ID、区域和地区)。
使用 gcloud init
如果您收到 One of [--zone, --region] must be supplied: Please specify
location
错误,请完成本部分。
-
运行
gcloud init
并按照说明操作:gcloud init
如果您要在远程服务器上使用 SSH,请使用
--console-only
标志来防止命令启动浏览器:gcloud init --console-only
-
按照说明授权
gcloud
使用您的 Google Cloud 帐号。 - 创建新配置或选择现有配置。
- 选择 Google Cloud 项目。
- 选择默认的 Compute Engine 区域。
使用 gcloud config
与 Identity and Access Management 互动
您可以使用 Identity and Access Management (IAM) 和 Kubernetes RBAC 来控制对 GKE 集群的访问权限:
IAM 并非特定于 Kubernetes;它为多种 Google Cloud 产品提供身份管理,并且主要在 Google Cloud 项目级层运行。
Kubernetes RBAC 是 Kubernetes 的核心组成部分,可让您针对集群内的任何对象或对象类型创建和授予角色(一组权限)。
在 GKE 中,IAM 和 Kubernetes RBAC 集成在一起,您可以通过任一工具向用户授权,使其有足够的权限执行操作。这对于 GKE 集群的引导过程至关重要,因为默认情况下,Google Cloud 用户不具有任何 Kubernetes RBAC RoleBindings。
如需使用 Google Cloud 帐号向用户授权,您必须首先将客户端正确配置为使用这些帐号进行身份验证。例如,如果您使用的是 kubectl
,则必须先配置 kubectl
命令以向 Google Cloud 进行身份验证,然后才能运行任何需要授权的命令。
虽然在几乎所有情况下都可以使用 Kubernetes RBAC 取代 IAM,但 GKE 用户至少需要集群所在项目中的 container.clusters.get
IAM 权限。container.clusterViewer
角色以及其他具有更高权限的角色包含此权限。用户必须拥有 container.clusters.get
权限才能向项目中的集群进行身份验证,但并未获得授权在这些集群内执行任何操作。随后,授权可由 IAM 或 Kubernetes RBAC 提供。
Google GKE 群组
以前,您只能向 Google Cloud 用户帐号或 IAM 服务帐号授予角色。现在,您可以通过 Google GKE 群组(Beta 版)向 Google 网上论坛企业版中的群组成员授予角色。借助此机制,用户和群组本身可由 Google Workspace 管理员完全在 Kubernetes 或 Cloud Console 外部进行维护,因此您的集群管理员就不需要用户的详细信息。另外,此功能还有一项优势,那就是它集成了现有的用户帐号管理做法,例如,您可以撤消已离开组织的人员的访问权限。
如需使用此功能,请完成以下任务:
- 满足要求。
- 配置 Google 群组。
- 创建已启用该功能的集群。
- 将 Google 群组与集群权限集相关联。
要求
使用 Google GKE 群组有以下要求:
- 您必须订阅 Google Workspace 或 Cloud Identity。
配置 Google 群组以结合 RBAC 进行使用
本主题后面的部分介绍了如何将集群配置为使用此功能,以及在 Kubernetes RBAC 中引用 Google 群组的语法。首先,您需要按照以下步骤设置 Google 群组:
在您的网域中创建一个名为
gke-security-groups@yourdomain.com
的 Google 群组。该群组的名称必须与gke-security-groups
完全一致。确保gke-security-groups
群组对“群组成员”拥有“查看成员”的权限。如需查看如何在 Google Workspace 管理控制台中设置此权限的示例,请参阅这篇文章。如需详细了解如何在 Google Workspace 中管理群组,您还可以参阅群组帮助中心。
创建多个群组(如果它们尚不存在),以表示对集群具有不同权限的用户组或群组。每个群组都必须对“群组成员”拥有“查看成员”的权限。
将这些群组(而非用户)添加到
gke-security-groups@yourdomain.com
的成员资格中。
GKE 会根据群组成员资格检查特定用户是否有权创建、修改或查看集群中的资源,也就是说,它会检查该用户是否属于具有访问权限的群组,以及该群组是否直接属于您的网域的 gke-security-groups
群组。
Google 群组成员资格的相关信息会缓存一小段时间。群组成员资格的更改可能需要几分钟才能传播到您的所有集群。除了群组更改带来的延迟之外,集群上的用户凭据的标准缓存时间约为 1 小时。
配置集群以使用 Google GKE 群组
在 Google 群组管理员设置群组后,请使用 gcloud
命令创建一个新集群,添加 --security-group="gke-security-groups@yourdomain.com"
标志,并将相关值替换为您自己的域名。
以下是 cluster create 命令的示例:
gcloud beta container clusters create cluster-name \
--security-group="gke-security-groups@yourdomain.com"
现在,您可以随时创建 Role、ClusterRole、RoleBinding 和 ClusterRoleBinding 来引用您的 Google 群组。
定义和分配权限
您可以通过创建以下类型的 Kubernetes 对象来定义 RBAC 权限:
- ClusterRole 或 Role:这些对象定义了一组资源类型和操作,以便分配给集群 (ClusterRole) 或命名空间 (Role) 中的特定用户或用户组,但它们未指定具体用户或用户组。
- ClusterRoleBinding 或 RoleBinding:这些对象可向特定用户或用户组分配 ClusterRole 或 Role。ClusterRoleBinding 与 ClusterRole 搭配使用,RoleBinding 与 ClusterRole 或 Role 搭配使用。
RBAC 角色只是附加角色,无需设置“拒绝”规则。在构建 RBAC 角色时,您应该考虑向用户“授予”集群资源访问权限。
使用 Role 或 ClusterRole 定义权限
您可以在 Role 或 ClusterRole 对象中定义权限。Role 用于定义对单个命名空间内资源的访问权限,而 ClusterRole 用于定义对整个集群内资源的访问权限。
Role 和 ClusterRole 采用相同语法。每个对象都有一个 rules
部分,您可以在其中定义 Role 的相关命名空间、资源类型和允许的操作。例如,以下 Role 授予 accounting
命名空间内所有 Pod 的读取访问权限(get
、watch
、list
):
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: accounting
name: pod-reader
rules:
- apiGroups: [""] # "" indicates the core API group
resources: ["pods"]
verbs: ["get", "watch", "list"]
Role
与 ClusterRole
由于 ClusterRole 授予的权限适用于整个集群,因此您可以使用 ClusterRole 来控制与使用 Role 可以控制的不同资源的访问权限。其中包括:
- 集群级资源(例如节点)
- 非资源 REST 端点(例如
/healthz
) - 所有命名空间内的命名空间型资源(例如,整个集群内的所有 Pod,无论位于哪个命名空间)
使用 RoleBinding 或 ClusterRoleBinding 分配角色
创建 Role 或 ClusterRole 后,您可以通过创建 RoleBinding 或 ClusterRoleBinding 将其分配给特定用户或用户组。用户和群组被称为 subjects
,可以是以下任何类型:
主体类型 | “kind ”的值 |
“name ”的值 |
---|---|---|
Google Cloud 用户帐号 | User |
Google Cloud 注册电子邮件地址 |
Kubernetes 服务帐号 | ServiceAccount |
集群中 Kubernetes ServiceAccount 对象的名称 |
IAM 服务帐号 | User |
自动生成的 IAM 服务帐号电子邮件地址 |
通过验证的网域上的 Google 群组地址(Beta 版) | Group |
Google 群组的电子邮件地址,该地址本身是 Google 群组 gke-security-groups@yourdomain.com 的成员 |
以下 RoleBinding 向用户、Kubernetes 服务帐号、IAM 服务帐号和 Google 群组授予 pod-reader
角色:
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: pod-reader-binding
namespace: accounting
subjects:
# Google Cloud user account
- kind: User
name: janedoe@example.com
# Kubernetes service account
- kind: ServiceAccount
name: johndoe
# IAM service account
- kind: User
name: test-account@test-project-123456.google.com.iam.gserviceaccount.com
# Google Group
- kind: Group
name: accounting-group@example.com
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
API 用法和示例
如需全面了解如何使用 Kubernetes API 创建 RBAC 所需的 Role
、ClusterRole
、RoleBinding
、ClusterRoleBinding
对象,请参阅 Kubernetes 文档中的使用基于角色的访问权限控制授权。
问题排查和调试
如需调试 RBAC 的问题,请使用管理员活动审核日志(默认情况下,系统会在所有集群上启用该日志)。如果由于缺少足够的权限而导致对资源或操作的访问被拒绝,则 API 服务器会记录 RBAC DENY
错误以及其他信息,例如用户的隐式和显式群组成员资格。如果您使用的是 Google GKE 群组,则日志消息中会显示 google groups
。
调试与 Google 群组集成相关的问题
您可以按照以下说明查看日志,以验证您的集群是否已成功配置为在 RBAC RoleBindings 中使用 Google 群组。
前提条件
在开始检查日志之前,请确保:
- 您至少有一个小时未与要测试的集群进行交互(例如,运行任何
kubectl
命令)。身份验证信息会缓存一小时,您需要确保请求在发生时会得到记录。 - 您是
gke-security-groups
中至少一个群组的成员。这可确保在日志中填充一些 Google 群组信息。
配置日志
如需通过 RBAC 使用日志来调试 Google 群组,请执行以下操作:
为您的 Google Cloud 项目启用数据访问日志记录。如需启用日志记录,请执行以下操作:
在 Cloud Console 中,转到 IAM 菜单中的审核日志页面。
在表格中,选择 Kubernetes Engine API。
在日志类型菜单中,选择:
- 管理员读取
- 数据读取
- 数据写入
点击保存。
如需详细了解如何启用审核日志记录,请参阅 Cloud 管理工具文档中的使用 Cloud Console 配置数据访问日志。
在集群中使用
kubectl
运行命令。这就像运行kubectl create ns helloworld
一样简单。在日志查看器页面中输入自定义查询。如需运行查询,请执行以下操作:
在 Cloud Console 中,转到日志记录菜单中的日志查看器页面。
点击页面顶部的查询预览框中的箭头。
在显示的下拉框中,复制并粘贴以下查询:
resource.type="k8s_cluster" resource.labels.location="cluster-region" resource.labels.cluster_name="cluster-name" protoPayload.resourceName="authorization.k8s.io/v1beta1/subjectaccessreviews" protoPayload.response.spec.user="email-address"
其中:
- cluster-region 是您的集群的地区或区域。
- cluster-name 是您的集群的名称。
- email-address 是您的 Google 帐号的注册电子邮件地址。
选择运行查询。您应该至少看到一个结果。如果没有,请尝试增加时间范围。
选择要检查的集群。
点击展开嵌套字段。
字段
protoPayload.request.spec.group
包含符合以下条件的群组:- 这些群组是
gke-security-group
的成员。 - 您是该群组的成员。
此列表应与您所属的群组集匹配。如果没有群组,则可能是因为群组的设置方式存在问题。
- 这些群组是
将数据访问日志记录恢复为以前的设置,以免产生更多费用(如果需要)。
限制
以下部分介绍了在使用 Kubernetes RBAC 时可能不太明显的交互。
默认发现角色
创建的集群包含一组默认 ClusterRole 和 ClusterRoleBinding。
使用有效凭据发出的请求将置于 system:authenticated
组中,而其他所有请求都将归入 system:unauthenticated
。在 Kubernetes 1.14 版之前,system:authenticated
和 system:unauthenticated
均默认授予 system:basic-user
和 system:discovery
ClusterRole。
system:basic-user
ClusterRole 可让用户进行 SelfSubjectAccessReviews
,以测试其在集群中的权限。system:discovery
角色可让用户读取发现 API,这些 API 可以发现已添加到集群的 CustomResourceDefinitions
的相关信息。
从 Kubernetes 1.14 开始,匿名用户 (system:unauthenticated
) 将收到 system:public-info-viewer
ClusterRole,该角色会授予 /healthz
和 /version
API 的只读访问权限。
如需查看 system:discovery
ClusterRole 允许的 API 端点,请运行以下命令:
kubectl get clusterroles system:discovery -o yaml
Google Cloud 虚拟机实例上的服务帐号出现“禁止使用”错误
如果虚拟机实例没有 userinfo-email
范围,则可能会发生以下错误:
Error from server (Forbidden): error when creating ... "role-name" is forbidden: attempt to grant extra privileges:...
例如,假设虚拟机具有 cloud-platform
范围,但没有 userinfo-email
范围。当虚拟机获得访问令牌时,Google Cloud 会将该令牌与 cloud-platform
范围相关联。当 Kubernetes API 服务器向 Google Cloud 请求与访问令牌相关联的身份时,它会收到服务帐号的唯一 ID,而不是服务帐号的电子邮件地址。
如需成功进行身份验证,请使用 userinfo-email
范围创建新的虚拟机,或者创建使用唯一 ID 的新角色绑定。
如需使用 userinfo-email
范围创建新的虚拟机,请运行以下命令:
gcloud compute instances create instance-name \ --service-account service-account-email \ --scopes userinfo-email
如需创建使用现有虚拟机的服务帐号唯一 ID 的新角色绑定,请执行以下步骤:
标识服务帐号的唯一 ID:
gcloud iam service-accounts describe service-account-email
例如,以下输出会显示
my-iam-account@somedomain.com
服务帐号的uniqueId
:displayName: Some Domain IAM service account email: my-iam-account@somedomain.com etag: BwWWja0YfJA name: projects/project-name/serviceAccounts/my-iam-account@somedomain.com oauth2ClientId: '123456789012345678901' projectId: project-name uniqueId: '123456789012345678901'
使用服务帐号的
uniqueId
创建角色绑定:kubectl create clusterrolebinding clusterrolebinding-name \ --clusterrole cluster-admin \ --user unique-id
后续步骤
- 了解如何创建 IAM 政策。