使用外部身份提供方向 GKE 进行身份验证


本页介绍了如何配置通过外部身份提供程序 (IdP) 对 Google Kubernetes Engine (GKE) 集群进行身份验证。

本页面面向使用支持 OpenID Connect (OIDC) 或安全断言标记语言 (SAML) 2.0 的外部 IdP 的平台管理员和运营者,以及身份和账号管理员。

在阅读本页面之前,请确保您熟悉以下身份验证和 OpenID 概念:

GKE 中的外部 IdP 身份验证方法

推荐 - 员工身份联合

员工身份联合是一项 IAM 功能,可让您通过支持 OIDC 或 SAML 2.0 的任何外部 IdP 进行身份验证。 Google Cloud Workforce Identity Federation 无需任何集群内安装,可与 Autopilot 集群和 Standard 集群搭配使用,并且内置于 Google Cloud中。如需了解详情,请参阅 IAM 文档中的员工身份联合部分。

不推荐 - Identity Service for GKE

仅在 GKE Standard 集群中,GKE 还支持 Identity Service for GKE。Identity Service for GKE 仅限于 OIDC IdP,并会在您的集群中安装其他组件。GKE 强烈建议您使用 Workforce Identity Federation,而不是 Identity Service for GKE。

准备工作

在开始之前,请确保您已执行以下任务:

  • 启用 Google Kubernetes Engine API。
  • 启用 Google Kubernetes Engine API
  • 如果您要使用 Google Cloud CLI 执行此任务,请安装初始化 gcloud CLI。 如果您之前安装了 gcloud CLI,请运行 gcloud components update 以获取最新版本。

注意事项

无头系统不受 Workforce Identity Federation 和 GKE Identity Service 的支持。基于浏览器的身份验证流程会提示您同意并授权您的用户账号。

在 GKE 中使用 Workforce Identity Federation

如需在 GKE 集群中使用 Workforce Identity Federation,请执行以下操作:

  1. 为贵组织和外部 IdP 设置员工身份联合。如需了解相关说明,请参阅配置员工身份联合
  2. 设置外部 IdP 对 Google Cloud Workforce Identity Federation 控制台的访问权限。如需了解详情,请参阅设置用户对控制台(联合)的访问权限
  3. 使用以下任一授权机制配置用户访问权限:

使用 RBAC 配置用户对集群的访问权限

Google Cloud 使用主账号标识符来标识员工身份池中的用户。您可以在 Kubernetes RBAC 政策或 IAM 政策中引用这些主账号标识符。您可以向单个用户或用户群组授予权限,如下例所示:

身份 主账号标识符
单个用户
principal://iam.googleapis.com/locations/global/workforcePools/WORKFORCE_IDENTITY_POOL/subject/SUBJECT_ATTRIBUTE_VALUE

替换以下内容:

  • WORKFORCE_IDENTITY_POOL:员工身份池的名称。
  • SUBJECT_ATTRIBUTE_VALUE:身份令牌的正文断言中的属性值。例如,这可能是 SAML 2.0 断言中 NameID 字段的值。

例如:

principal://iam.googleapis.com/locations/global/workforcePools/full-time-employees/subject/amal@example.com
群组中的所有用户
principalSet://iam.googleapis.com/locations/global/workforcePools/WORKFORCE_IDENTITY_POOL/group/GROUP_NAME

替换以下内容:

  • WORKFORCE_IDENTITY_POOL:员工身份池的名称。
  • GROUP_NAME:进行身份验证的用户所属的群组的名称。IdP 令牌中的断言必须具有对 Google Cloud google.groups 属性的属性映射

例如:

principalSet://iam.googleapis.com/locations/global/workforcePools/full-time-employees/group/sre

如需了解员工身份联合支持的每个主账号标识符,请参阅在 IAM 政策中表示员工池用户

以下示例展示了如何向 full-time-employees 员工池中 IdP 令牌中包含 access_level="sensitive" 属性的任何实体授予对 Secret 的集群级只读访问权限。

  1. 将以下 ClusterRole 清单另存为 secret-viewer-cluster-role.yaml

    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      name: secret-viewer
    rules:
    - apiGroups: [""]
      resources: ["secrets"]
      verbs: ["get", "watch", "list"]
    

    您将此 ClusterRole 绑定到的任何正文都可以查看 Secret。

  2. 将以下 ClusterRoleBinding 清单另存为 secret-viewer-cluster-role-binding.yaml

    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name:  users-view-secrets
    subjects:
    - kind: Group
      name: principalSet://iam.googleapis.com/locations/global/workforcePools/full-time-employees/attribute.access_level/sensitive
      apiGroup: rbac.authorization.k8s.io
    roleRef:
      kind: ClusterRole
      name: secret-viewer
      apiGroup: rbac.authorization.k8s.io
    

    此 ClusterRoleBinding 会向具有 access_level="sensitive" 属性的任何用户授予 secret-viewer ClusterRole。

  3. 部署 ClusterRole 和 ClusterRoleBinding:

    kubectl apply -f secret-viewer-cluster-role.yaml
    kubectl apply -f secret-viewer-cluster-role-binding.yaml
    

将适用于 GKE 集群的 Identity Service 迁移到 Workforce Identity Federation

如果您在现有 GKE 集群中使用 Identity Service for GKE,请迁移到 Workforce Identity Federation。这些方法使用不同的语法来引用同一正文,如下表所示:

Identity Service for GKE 语法 员工身份联合语法
amal@example.com principal://iam.googleapis.com/locations/global/workforcePools/full-time-employees/subject/amal@example.com
sre-group principalSet://iam.googleapis.com/locations/global/workforcePools/full-time-employees/group/sre-group

如需迁移集群以使用员工身份联合,请执行以下操作:

  1. 为贵组织和外部 IdP 设置员工身份联合。如需了解相关说明,请参阅配置员工身份联合

  2. 更新集群中所有 RoleBinding 和 ClusterRoleBinding 的清单,以使用 Workforce Identity Federation 标识符语法。请使用以下任一选项:

    • 程序化更新:安装并运行 gke-identity-service-migrator 实用程序。如需了解相关说明,请参阅 GoogleCloudPlatform/gke-utilities 代码库自述文件

      此实用程序会查找使用 Identity Service for GKE 语法的现有 RBAC 绑定,并创建使用相应 Workforce Identity Federation 正文标识符的新清单。

    • 手动更新:对于引用已验证用户或群组的每个绑定,请为对象的清单文件创建一个单独的副本,并使用 Workforce Identity Federation 标识符语法。

  3. 将更新后的 RoleBinding 和 ClusterRoleBinding 清单应用到您的集群。

  4. 测试用户使用员工身份联合进行身份验证时是否可以访问相同的资源。

  5. 从集群中移除已废弃的 RBAC 绑定。

  6. 停用 Identity Service for GKE

使用 Identity Service for GKE

如需在 GKE 标准模式集群上设置和使用 Identity Service for GKE,集群管理员必须执行以下操作:

  1. 在集群上启用 Identity Service for GKE
  2. 配置 Identity Service for GKE
  3. 为您的集群创建 RBAC 政策

集群管理员配置 Identity Service for GKE 后,开发者可以登录集群并进行身份验证

Identity Service for GKE 创建的 Kubernetes 对象

下表介绍了在集群上启用 Identity Service for GKE 时创建的 Kubernetes 对象:

Kubernetes 对象
anthos-identity-service Namespace
用于 Identity Service for GKE 部署。
kube-public Namespace
用于 default 客户端配置文件。
gke-oidc-envoy LoadBalancer
OIDC 请求的端点。默认为外部端点。如果您在没有外部 IP 端点的集群中创建了该端点,则它是集群 Virtual Private Cloud 的内部端点。
anthos-identity-service 命名空间中创建。
gke-oidc-service ClusterIP
方便在 gke-oidc-envoy Deployment 和 gke-oidc-service Deployment 之间进行通信。
anthos-identity-service 命名空间中创建。
gke-oidc-envoy Deployment
运行向 gke-oidc-envoy LoadBalancer 公开的代理。与 gke-oidc-service 通信以验证身份令牌。充当 Kubernetes API 服务器的代理,并在向 API 服务器传递请求时模拟用户
anthos-identity-service 命名空间中创建。
gke-oidc-service Deployment
验证身份令牌,并为 ClientConfig 资源提供验证准入网络钩子
anthos-identity-service 命名空间中创建。
gke-oidc-operator Deployment
协调客户端配置和 gke-oidc-envoy LoadBalancer。
anthos-identity-service 命名空间中创建。
gke-oidc-certs Secret
包含 LoadBalancer 的集群证书授权机构 (CA) 和 TLS 证书。
anthos-identity-service 命名空间中创建
default ClientConfig CRD
包含 OIDC 参数,例如首选身份验证方法、身份提供商配置以及用户和群组声明映射。用于身份令牌验证。供集群管理员用于在分发给开发者之前配置 OIDC 设置。
kube-public 命名空间中创建

在集群上启用 Identity Service for GKE

默认情况下,Identity and Access Management (IAM) 配置为集群身份验证的身份提供方。如果您希望将 OIDC 与第三方身份提供方搭配使用,则可以使用 Google Cloud CLI 在新集群或现有集群上启用 Identity Service for GKE。

在新集群上启用 Identity Service for GKE

如需创建启用 Identity Service for GKE 的集群,请运行以下命令:

gcloud container clusters create CLUSTER_NAME \
    --enable-identity-service

CLUSTER_NAME 替换为新集群的名称。

在现有集群上启用 Identity Service for GKE

要在现有集群上启用 Identity Service for GKE,请运行以下命令:

gcloud container clusters update CLUSTER_NAME \
    --enable-identity-service

CLUSTER_NAME 替换为您的集群名称。

配置 Identity Service for GKE

您可以通过下载和修改 default ClientConfig 来配置 Identity Service for GKE 参数。

  1. 下载 default ClientConfig:

    kubectl get clientconfig default -n kube-public -o yaml > client-config.yaml
    
  2. 使用首选设置来更新 spec.authentication 部分:

    apiVersion: authentication.gke.io/v2alpha1
    kind: ClientConfig
    metadata:
      name: default
      namespace: kube-public
    spec:
      name: cluster-name
      server: https://192.168.0.1:6443
      authentication:
      - name: oidc
        oidc:
          clientID: CLIENT_ID
          certificateAuthorityData: OIDC_PROVIDER_CERTIFICATE
          extraParams: EXTRA_PARAMS
          issuerURI:  ISSUER_URI
          cloudConsoleRedirectURI: https://console.cloud.google.com/kubernetes/oidc
          kubectlRedirectURI: KUBECTL_REDIRECT_URL
          scopes: SCOPES
          userClaim: USER
          groupsClaim: GROUPS
          userPrefix: USER_PREFIX
          groupPrefix: GROUP_PREFIX
    

    替换以下内容:

    • CLIENT_ID:向 OIDC 提供商发出身份验证请求的客户端应用的 ID。
    • OIDC_PROVIDER_CERTIFICATE:(可选)OIDC 提供方的 PEM 证书。如果您的 OIDC 提供方使用自签名证书,则此字段可能有用。默认情况下,Identity Service for GKE 包含一组公共根目录。
    • EXTRA_PARAMS:要发送到 OIDC 提供商的其他键值对参数。
      • 使用 resource=token-groups-claim 向群组授权。
      • 使用 prompt=consent 对 Microsoft Azure 和 Okta 进行身份验证。
      • 对于 Cloud Identity,请使用 prompt=consent,access_type=offline
    • ISSUER_URI:用于发送 OIDC 授权请求的网址,例如 https://example.com/adfs。Kubernetes API 服务器使用此网址来发现用于验证令牌的公钥。URI 必须使用 HTTPS。对于 Cloud Identity,请使用 https://accounts.google.com
    • KUBECTL_REDIRECT_URLkubectl oidc login 用于授权的重定向网址。格式通常为 http://localhost:PORT/callback,其中 PORT 是将在开发者工作站上可用的高于 1024 的任意端口,例如 http://localhost:10000/callback。您必须向 OIDC 提供商将该网址注册为客户端应用的授权重定向网址。如果您将 Google Identity 用作 OIDC 提供商,请参阅设置重定向 URI 以了解说明。
    • SCOPES:要发送到 OIDC 提供商的其他范围。
      • Microsoft Azure 和 Okta 需要 offline_access 范围。
      • 对于 Cloud Identity,请使用 openid, email 获取包含 email 声明中的电子邮件地址的 ID 令牌。
    • USER:身份令牌中的用户声明。
    • GROUPS:身份令牌中的群组声明。
    • USER_PREFIX:附加到用户声明的前缀,以防止与现有名称冲突。默认情况下,颁发者前缀会附加到提供给 Kubernetes API 服务器的 userID(除非用户声明为 email)。生成的用户标识符为 ISSUER_URI#USER。我们建议您使用前缀,但您可以通过将 USER_PREFIX 设置为 - 来停用该前缀。
    • GROUP_PREFIX:附加到群组声明的前缀,以防止与现有名称冲突。例如,如果您有两个名为 foobar 的群组,请添加前缀 gid-。生成的群组为 gid-foobar
  3. 应用更新后的配置:

    kubectl apply -f client-config.yaml
    

    应用此配置后,Identity Service for GKE 会在集群内部运行,并通过 gke-oidc-envoy 负载均衡器处理请求。spec.server 字段中的 IP 地址必须是负载均衡器的 IP 地址。如果您更改 spec.server 字段,则 kubectl 命令可能会失败。

  4. 创建 client-config.yaml 配置文件的副本:

    cp client-config.yaml login-config.yaml
    
  5. 使用 spec.authentication.oidc 部分中的 clientSecret 设置更新 login-config.yaml 配置文件。

    clientSecret: CLIENT_SECRET
    

    CLIENT_SECRET 替换为 OIDC 客户端应用和 OIDC 提供方之间的共享密钥。

  6. 将更新的 login-config.yaml 文件分发给开发者。

在实施严格政策的集群上配置 Identity Service for GKE

如需将 Identity Service for GKE 配置为在实施严格网络政策的集群上按预期工作,请执行以下操作:

  1. 为 TCP 端口 15000 添加防火墙规则,以允许您的控制平面与 ClientConfig 验证网络钩子进行通信。
  2. 如果 gke-oidc-envoy 创建为内部负载均衡器,请在 VPC 上公开它
  3. 如果您的政策拒绝集群内部的流量,请为 TCP 端口 8443 添加防火墙规则,以允许 gke-oidc-envoy 部署与 gke-oidc-service 部署进行通信。

Identity Service for GKE 组件 0.2.20 及更高版本不使用 TCP 端口 15000。如果您的组件版本为 0.2.20 或更高版本,则无需为端口 15000 添加防火墙规则。如需检查组件版本,请运行以下命令:

kubectl describe deployment gke-oidc-envoy -n anthos-identity-service \
    | grep "components.gke.io/component-name: gke-oidc" -A1

向负载均衡器添加自定义属性

配置 Identity Service for GKE 后,您可以将自定义注解和属性(例如静态 IP 地址)添加到 gke-oidc-envoy 负载均衡器。要编辑 gke-oidc-envoy Service,请运行以下命令:

kubectl edit service gke-oidc-envoy -n anthos-identity-service

如需详细了解如何为 GKE 配置 TCP/UDP 负载均衡,请参阅 LoadBalancer Service 参数

为您的集群创建 RBAC 政策

管理员使用 Kubernetes 基于角色的访问权限控制 (RBAC) 向经过身份验证的集群用户授予访问权限。如需为集群配置 RBAC,您必须为每个开发者授予 RBAC 角色。要授予对特定命名空间中的资源的访问权限,请创建 RoleRoleBinding要授予对整个集群的资源的访问权限,请创建 ClusterRoleClusterRoleBinding

比方说,假设一个用户需要查看集群中的所有 Secret 对象。以下步骤会向此用户授予所需的 RBAC 角色。

  1. 将以下 ClusterRole 清单另存为 secret-viewer-cluster-role.yaml。被授予此角色的人员可以获取、查看和列出集群中的任何 Secret。

    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      name: secret-viewer
    rules:
    - apiGroups: [""]
      # The resource type for which access is granted
      resources: ["secrets"]
      # The permissions granted by the ClusterRole
      verbs: ["get", "watch", "list"]
    
  2. 应用 ClusterRole 清单:

    kubectl apply -f secret-viewer-cluster-role.yaml
    
  3. 将以下 ClusterRoleBinding 清单另存为 secret-viewer-cluster-role-binding.yaml。绑定会将 secret-viewer 角色授予客户端配置文件中定义的用户名。

    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name:  people-who-view-secrets
    subjects:
    - kind: User
      name: ISSUER_URI#USER
      apiGroup: rbac.authorization.k8s.io
    roleRef:
      kind: ClusterRole
      name: secret-viewer
      apiGroup: rbac.authorization.k8s.io
    

    替换以下内容:

    • ISSUER_URI:客户端配置文件的 spec.authentication.oidc.issuerURI 中的颁发者 URI。
    • USER:令牌中的用户标识符,该令牌位于客户端配置文件的 spec.authentication.oidc.userClaim 中配置的声明名称之下。
  4. 应用 ClusterRoleBinding 清单:

    kubectl apply -f secret-viewer-cluster-role-binding.yaml
    

登录集群并进行身份验证

作为从管理员处收到 OIDC 配置文件的开发者,您可以向集群进行身份验证。

  1. 下载管理员提供的 login-config.yaml 文件。

  2. 安装 Google Cloud CLI SDK,它提供了单独的 OIDC 组件。您可以通过运行以下指令来安装此组件:

    gcloud components install kubectl-oidc
    
  3. 向您的集群进行身份验证:

    kubectl oidc login --cluster=CLUSTER_NAME --login-config=login-config.yaml
    

    系统会打开网络浏览器以完成身份验证过程。

  4. 完成身份验证后,您可以运行 kubectl 命令,例如:

    kubectl get pods
    

停用 Identity Service for GKE

您可以使用 gcloud CLI 停用 Identity Service for GKE。要停用 Identity Service for GKE,请运行以下命令:

gcloud container clusters update CLUSTER_NAME \
    --no-enable-identity-service

后续步骤