使用 OpenID Connect (OIDC) 进行身份验证

本页面介绍如何配置 GKE On-Prem 以使用 OpenID 提供方对用户集群进行身份验证。如需了解如何将 OIDC 与 AD FS 搭配使用,请参阅使用 OIDC 和 AD FS 进行身份验证

如需大致了解 GKE On-Prem 身份验证流程,请参阅身份验证

概览

GKE On-Prem 支持使用 OpenID Connect (OIDC) 作为与用户集群的 Kubernetes API 服务器进行交互的身份验证机制之一。借助 OIDC,您可以按照组织中创建、启用和停用员工帐号的标准过程来管理对 Kubernetes 集群的访问权限。

员工可以通过两种方式使用 OIDC 身份验证流程:

  • 员工可以使用 kubectl 启动 OIDC 流程。为了实现此流程的自动化,GKE On-Prem 提供适用于 OIDC 的 Kubectl 插件,这是一个 kubectl 插件

  • 员工可以使用 Google Cloud 控制台启动 OIDC 身份验证流程。

在本练习中,您将配置两个选项:kubectl 和 Google Cloud 控制台。

准备工作

本主题假定您熟悉 OAuth 2.0OpenID Connect。本主题假定您熟悉 OpenID 范围声明

选择 OpenID 提供方

本部分面向管理员。

您可以选择使用任何 OpenID 提供方。如需查看经过认证的提供方列表,请参阅 OpenID 认证

您可以使用 Active Directory Federated Services (AD FS) 作为 OpenID 提供方,并使用 Active Directory 的本地实例作为员工数据库。如需了解详情,请参阅使用 OIDC 和 AD FS 进行身份验证

下载适用于 OIDC 的 Kubectl 插件

本部分面向希望使用适用于 OIDC 的 Kubectl 插件的管理员和员工。

下载插件并设置访问权限:

Linux

gsutil cp gs://gke-on-prem-release/oidc-plugin/v1.1alpha/linux_amd64/kubectl-oidc .
chmod +x kubectl-oidc

Windows

gsutil cp gs://gke-on-prem-release/oidc-plugin/v1.1alpha/windows_amd64/kubectl-oidc .

macOS

gsutil cp gs://gke-on-prem-release/oidc-plugin/v1.1alpha/darwin_amd64/kubectl-oidc .
chmod +x kubectl-oidc

安装插件

通过将可执行文件移到 PATH 上的任意位置来安装插件。可执行文件必须命名为 kubectl-oidc。如需了解详情,请参阅安装 kubectl 插件

为适用于 OIDC 的 Kubectl 插件创建重定向网址

本部分面向管理员。

作为与您的 OpenID 提供方建立关系的一部分,您必须指定提供方可用于向适用于 OIDC 的 Kubectl 插件返回 ID 令牌的重定向网址。适用于 OIDC 的 Kubectl 插件在每位员工的本地机器上运行,并侦听您选择的端口。选择适合此用途且大于 1024 的端口号。然后,重定向网址为:

http://localhost:[PORT]/callback

其中,[PORT] 是您的端口号。

配置 OpenID 提供商时,请指定 http://localhost:[PORT]/callback 作为您的重定向网址之一。具体操作方法取决于您的提供商。

为 Google Cloud 控制台配置重定向网址

本部分面向管理员。

除了具有 kubectl 的重定向网址之外,您还需要 Google Cloud 控制台的重定向网址。Google Cloud 控制台的重定向网址为:

https://console.cloud.google.com/kubernetes/oidc

配置 OIDC 提供商时,请指定 https://console.cloud.google.com/kubernetes/oidc 作为您的重定向网址之一。具体操作方法取决于您的提供商。

向 OpenID 提供方注册您的客户端应用

本部分面向管理员。

您需要先向 OpenID 提供商注册这两个客户端,您的员工才能将适用于 OIDC 的 Kubectl 插件或 Google Cloud 控制台与您的 OpenID 提供商搭配使用。注册包括以下步骤:

  • 了解提供商的颁发者 URI。这是适用于 OIDC 的 Kubectl 插件或 Google Cloud 控制台发送身份验证请求的位置。

  • 为提供商提供适用于 OIDC 的 Kubectl 插件的重定向网址。

  • 为提供方提供 Google Cloud 控制台的重定向网址。网址为 https://console.cloud.google.com/kubernetes/oidc。

  • 确定单个客户端 ID。这是提供商用于标识适用于 OIDC 的 Kubectl 插件和 Google Cloud 控制台的 ID。

  • 确定单个客户端密钥。适用于 OIDC 的 Kubectl 插件和 Google Cloud 控制台都使用此密钥向 OpenID 提供商进行身份验证。

  • 确定自定义范围,供适用于 OIDC 的 Kubectl 插件或 Google Cloud 控制台用来请求用户的安全组。

  • 建立自定义声明名称,供提供商用来返回用户的安全组。

如何执行这些步骤取决于您的 OpenID 提供方。如需了解如何使用 AD FS 执行注册步骤,请参阅使用 OIDC 和 AD FS 进行身份验证

在 GKE On-Prem 配置文件中填充 oidc 规范

本部分面向想要创建配置为使用 OIDC 的集群的员工。

在创建用户集群之前,可使用 gkectl create-config 生成 GKE On-Prem 配置文件。配置包括以下 oidc 规范。使用提供方特定的值来填充 oidc

oidc:
  issuerurl:
  clientid:
  clientsecret:
  username:
  usernameprefix:
  group:
  groupprefix:
  scopes:
  extraparams:
  usehttpproxy:
  capath:
  • issuerurl:必填。您的 OpenID 提供商的网址,例如 https://example.com/adfs。客户端应用(如适用于 OIDC 的 Kubectl 插件和 Google Cloud 控制台)会向此网址发送授权请求。Kubernetes API 服务器使用此网址来发现用于验证令牌的公钥。必须使用 HTTPS。
  • clientid:必填。向 OpenID 提供商发出身份验证请求的客户端应用的 ID。适用于 OIDC 的 Kubectl 插件和 Google Cloud 控制台都使用此 ID。
  • clientsecret:可选。客户端应用的密钥。适用于 OIDC 的 Kubectl 插件和 Google Cloud 控制台均使用此密钥。
  • username:可选。用作用户名的 JWT 声明。默认值为 sub,该值应为最终用户的唯一标识符。您可以选择其他声明,例如 emailname,具体取决于 OpenID 提供方。不过,email 以外的声明会以颁发者网址作为前缀,以防止命名与其他插件冲突。
  • usernameprefix:可选。附加到用户名声明前面的前缀,以防止与现有名称冲突。如果您未提供此字段,并且 usernameemail 以外的值,则前缀默认为 issuerurl#。您可以使用值 - 停用所有前缀。
  • group:可选。提供方将用于返回安全群组的 JWT 声明。
  • groupprefix:可选。附加到群组声明前面的前缀,以防止与现有名称冲突。例如,给定一个组 foobar 和一个前缀 gid-,则格式为 gid-foobar
  • scopes:可选。以英文逗号分隔列表的形式发送给 OpenID 提供方的额外范围。
  • extraparams:可选。以英文逗号分隔列表的形式发送到 OpenID 提供方的额外键值对参数。
  • usehttpproxy:可选。指定是否在集群中部署反向代理,以允许 Connect Agent 访问本地 OIDC 提供方来验证用户身份。值必须是字符串:"true""false"
  • capath:可选。证书授权机构 (CA)(负责颁发身份提供方 Web 证书)颁发的证书路径。此值可能不是必需的。例如,如果您的身份提供方证书是由知名公共 CA 颁发的,那么您无需在此提供值。

示例:向用户和群组授权

许多提供方在令牌中对用户标识属性(例如电子邮件和用户 ID)进行编码。但是,对于身份验证政策来说,这些属性具有潜在的风险:

  • 用户 ID 可能会导致政策难以阅读和审核。
  • 电子邮件可能会产生可用性风险(如果用户更改其主电子邮件),也可能产生安全风险(如果可以重新分配电子邮件)。

因此,最佳做法是使用群组政策,因为群组 ID 是永久性 ID 且更易于审核。

假设您的提供方创建了包含以下字段的身份令牌:

{
  'iss': 'https://server.example.com'
  'sub': 'u98523-4509823'
  'groupList: ['developers@example.corp', 'us-east1-cluster-admins@example.corp']
  ...
}
根据此令牌格式,您可以按如下方式填充配置文件的 oidc 规范:
issueruri: 'https://server.example.com'
username: 'sub'
usernameprefix: 'uid-'
group: 'groupList'
groupprefix: 'gid-'
extraparams: 'resource=token-groups-claim'
...

创建用户集群后,您可以使用 Kubernetes 基于角色的访问权限控制 (RBAC) 向经过身份验证的用户授予具有特权的访问权限。例如,您可以创建一个 ClusterRole,向其用户授予对集群 Secret 的只读权限,并创建一个 ClusterRoleBinding 资源,以将角色绑定到经过身份验证的群组:

ClusterRole

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

ClusterRoleBinding

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: read-secrets-admins
subjects:
  # Allows anyone in the "us-east1-cluster-admins" group to
  # read Secrets in any namespace within this cluster.
- kind: Group
  name: gid-us-east1-cluster-admins # Name is case sensitive
  apiGroup: rbac.authorization.k8s.io
  # Allows this specific user to read Secrets in any
  # namespace within this cluster
- kind: User
  name: uid-u98523-4509823
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: secret-reader
  apiGroup: rbac.authorization.k8s.io

保存 Kubernetes API 服务器的 CA 证书

本部分面向已创建用户集群并且现在想要使用适用于 OIDC 的 Kubectl 插件的员工。

您的用户集群具有 Kubernetes API 服务器。您的用户集群的 kubeconfig 文件存储将证书颁发给 Kubernetes API 服务器的 CA 的证书。CA 的证书是 certificate-authority-data 字段的 base-64 编码值。您需要解码此值并将其存储在本地文件(例如 server-ca-cert)中:

cat [USER_CLUSTER_KUBECONFIG]  | grep certificate-authority-data | awk '{ print $2}' | base64 --decode > server-ca-cert

生成客户端身份验证配置文件

本部分面向已创建用户集群并且现在想要使用适用于 OIDC 的 Kubectl 插件的员工。

如需生成客户端身份验证配置文件,请输入以下命令:

Linux

kubectl oidc client-config \
--issuer-uri [ISSUER_URI] \
--redirect-uri [REDIRECT_URL] \
--client-id [CLIENT_ID] \
--client-secret [CLIENT_SECRET] \
--scopes "[CUSTOM_SCOPES]" \
--cluster-name [USER_CLUSTER_NAME] \
--server [CLUSTER_URL] \
--server-ca-file [SERVER_CA_CERT] \
--issuer-ca-file [PROVIDER_CA_CERT] \
--extra-params [KEY]=[VALUE], ... # e.g. --extra-params "resource=token-groups-claim"
> client-config.yaml

其中:

  • [ISSUER_URI] 是您的颁发者 URI。
  • [REDIRECT_URL] 是适用于 OIDC 的 Kubectl 插件的重定向网址
  • [CLIENT_ID] 是适用于 OIDC 的 Kubectl 插件的客户端 ID。
  • [CLIENT_SECRET] 是适用于 OIDC 的 Kubectl 插件的客户端密钥。
  • [USER_CLUSTER_NAME] 是您的用户集群的名称。
  • [CLUSTER_URL] 是用户集群的 Kubernetes API 服务器的网址。
  • [SERVER_CA_FILE] 是向 Kubernetes API 服务器颁发证书的 CA 的证书路径。这是您在上一部分中创建的证书文件。
  • [PROVIDER_CA_CERT] 是对 OpenID 提供方的证书进行签名的 CA 的证书路径。这与集群配置文件中 oidc:cacert 的值相同。
  • [CUSTOM_SCOPES] 是以英文逗号分隔的安全组的自定义范围列表。这与集群配置文件中 oidc:scopes 的值相同。
  • --extra-params [KEY]=[VALUE], ... 是要包含在向 OpenID 提供方发出的授权请求中的以英文逗号分隔的键值对列表。

PowerShell

kubectl oidc client-config `
--issuer-uri [ISSUER_URI] `
--redirect-uri [REDIRECT_URL] `
--client-id [CLIENT_ID] `
--client-secret [CLIENT_SECRET] `
--scopes "[CUSTOM_SCOPES]" `
--cluster-name [USER_CLUSTER_NAME] `
--server [CLUSTER_URL] `
--server-ca-file [SERVER_CA_CERT] `
--issuer-ca-file [PROVIDER_CA_CERT] `
--extra-params [KEY]=[VALUE]
> client-config.yaml

其中:

  • [ISSUER_URI] 是您的颁发者 URI。
  • [REDIRECT_URL] 是适用于 OIDC 的 Kubectl 插件的重定向网址
  • [CLIENT_ID] 是适用于 OIDC 的 Kubectl 插件的客户端 ID。
  • [CLIENT_SECRET] 是适用于 OIDC 的 Kubectl 插件的客户端密钥。
  • [USER_CLUSTER_NAME] 是您的用户集群的名称。
  • [CLUSTER_URL] 是用户集群的 Kubernetes API 服务器的网址。
  • [SERVER_CA_FILE] 是向 Kubernetes API 服务器颁发证书的 CA 的证书路径。这是您在上一部分中创建的证书文件。
  • [PROVIDER_CA_CERT] 是对 OpenID 提供方的证书进行签名的 CA 的证书路径。这与集群配置文件中 oidc:cacert 的值相同。
  • [CUSTOM_SCOPES] 是以英文逗号分隔的安全组的自定义范围列表。这与集群配置文件中 oidc:scopes 的值相同。
  • --extra-params [KEY]=[VALUE], ... 是要包含在向 OpenID 提供方发出的授权请求中的以英文逗号分隔的键值对列表。

此命令会生成名为 client-config.yaml 的客户端身份验证配置文件。请勿手动修改此文件。

使用适用于 OIDC 的 Kubectl 插件向用户集群进行身份验证

本部分面向已创建用户集群并且现在想要使用适用于 OIDC 的 Kubectl 插件的员工。

  1. 使用 client-config.yaml 文件初始化插件:

    kubectl oidc login --clientconfig-file=client-config.yaml --user [NAME] \
        --kubeconfig [KUBECONFIG_OUTPUT_PATH]

    其中:

    • [NAME] 是您的用户名。
    • [KUBECONFIG_OUTPUT_PATH] 是适用于 OIDC 的 Kubectl 插件将在其中存储凭据的 kubeconfig 文件的路径。

    kubectl oidc login 会启动浏览器,您可以在其中输入凭据。

    现在提供的 kubeconfig 文件包含一个 ID 令牌,kubectl 可使用该令牌向用户集群上的 Kubernetes API 服务器进行身份验证。

    注意:Windows 用户可能必须以 kubectl-oidc.exe login(而非 kubectl oidc login)的形式运行该命令。

  2. 通过运行任何 kubectl 命令来验证身份验证是否成功。例如:

    kubectl get nodes --kubeconfig [KUBECONFIG_OUTPUT_PATH]

将 OIDC 与 Google Cloud Console 搭配使用

本部分面向已创建用户集群并且现在想要使用 Google Cloud Console 向该集群进行身份验证的员工。

  1. 验证您的集群是否已针对 OIDC 进行了配置

  2. 验证您的集群是否已向 Google Cloud 注册(无论是在创建集群过程中自动注册还是手动注册)。

  3. 访问 Google Cloud 控制台中的 Kubernetes 集群页面。

    访问 Kubernetes 集群页面

  4. 在集群列表中,找到您的 GKE On-Prem 集群,然后点击登录

  5. 选择使用为集群配置的身份提供商服务执行身份验证,然后点击登录

    系统会将您重定向到您的身份提供商,您可能需要登录或同意 Google Cloud 控制台访问您的帐号。然后,系统会将您重定向回 Google Cloud 控制台中的 Kubernetes 集群页面。

排查 GKE On-Prem 中的 OIDC 问题

配置无效

如果 Google Cloud 控制台无法从集群中读取 OIDC 配置,则登录按钮将被停用。

提供商配置无效

如果您的身份提供方配置无效,点击登录后,身份提供方将显示错误屏幕。按照特定于提供方的说明正确配置提供方或您的集群。

权限无效

如果您完成了身份验证流程,但仍看不到集群的详细信息,请确保您已向与 OIDC 搭配使用的帐号授予了正确的 RBAC 权限。请注意,此帐号可能与您用于访问 Google Cloud 控制台的帐号不同。

Error: missing 'RefreshToken' field in 'OAuth2Token' in credentials struct

如果授权服务器提示是否同意,但您未提供所需的身份验证参数,则可能会遇到此错误。向 GKE On-Prem 配置文件的 oidc: extraparams 字段提供 prompt=consent 参数,并使用 --extra-params prompt=consent 标志重新生成客户端身份验证文件。