向 OpenID Connect (OIDC) 进行身份验证

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

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

概览

GKE On-Prem 支持使用 OpenID Connect (OIDC) 作为与用户集群的 Kubernetes API 服务器进行交互的身份验证机制之一。为使集群用户能够自动完成身份验证流程,GKE On-Prem 提供了一个 kubectl 插件,即适用于 OIDC 的 Kubectl 插件。

在本练习中,您将配置 OpenID 提供方与 kubectl 之间的关系。

准备工作

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

选择一个身份提供商

无论您选择哪种方式,都可以按此处的说明使用适用于 OIDC 的 Kubectl 插件,以加快身份验证的配置和身份验证过程本身。本主题介绍如何使用 ADFS 以外的 OpenID 提供方。

下载适用于 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 插件

创建重定向 URI

在与 OpenID 提供方建立关系的过程中,您必须指定可供提供方用来返回 ID 令牌的重定向 URI。令牌转到适用于 OIDC 的 Kubectl 插件,该插件会在每个员工的本地机器上运行并侦听您选定的端口。选择适合此用途且大于 1024 的端口号。因此,重定向 URI 为:

http://localhost:[PORT]/callback

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

向 OpenID 提供方注册适用于 OIDC 的 Kubectl 插件

您必须先向 OpenID 提供方注册适用于 OIDC 的 Kubectl 插件,然后才能将该插件与该提供方结合起来使用。注册包括以下步骤:

  • 了解提供商的颁发者 URI。这是插件发送身份验证请求的位置。

  • 向提供方提供您的重定向 URI。

  • 建立客户端 ID。这是提供商用于标识插件的 ID。

  • 确定客户端密钥。插件使用此密钥向 OpenID 提供商进行身份验证。

  • 建立一个自定义范围,该插件可使用此范围来请求用户的安全群组。

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

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

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

在安装过程中,您可以使用 gkectl create-config 生成 GKE On-Prem 配置文件。配置包括以下 oidc 规范。使用特定于提供方的值来填充“oidc”:

oidc:
  issuerurl:
  kubectlredirecturl:
  clientid:
  clientsecret:
  username:
  usernameprefix:
  group:
  groupprefix:
  scopes:
  extraparams:
  usehttpproxy:
  capath:
  • issuerurl:您的 OpenID 提供方的网址,如 https://example.com/adfs。客户端应用(如适用于 OIDC 的 Kubectl 插件)向此网址发送授权请求。Kubernetes API 服务器使用此网址来发现用于验证令牌的公钥。必须使用 HTTPS。 此字段为必填字段。
  • kubectlredirecturl:适用于 OIDC 的 Kubectl 插件的 localhost 重定向网址。 您需要向 OpenID 提供方注册该重定向网址,以供分配给此集群的客户端 ID 使用。此字段是必填字段。
  • clientid:向 OpenID 提供方发出身份验证请求的客户端应用(如适用于 OIDC 的 Kubectl 插件)的 ID。此字段为必填字段。
  • clientsecret:客户端应用的密钥。 此字段为必填字段。
  • usehttpproxy:选择是否在集群中部署反向代理,以允许 Connect Agent 通过访问本地 OIDC 提供方来验证用户身份。值必须为字符串 "true""false"。此字段是必填字段。
  • username:用作用户名的 JWT 声明。默认值为 sub,这是最终用户的唯一标识符。您可以选择其他声明,如 emailname,具体取决于 OIDC 提供方。不过,email 以外的声明会以颁发者网址作为前缀,以防止命名与其他插件冲突。
  • usernameprefix:为防止与现有名称冲突而附加到用户名声明的前缀。如果未提供此标志,并且 username 是电子邮件地址以外的值,则前缀默认为 issueruri#。值 - 可用于停用所有前缀。
  • group:用作用户群组的 JWT 声明。如果存在声明,则它必须是字符串数组。
  • groupprefix:为防止与现有名称冲突而附加到群组声明的前缀。例如,假定群组名称为 foobar,前缀为 gid-,两者结合为 gid-foobar
  • scopes:以逗号分隔列表的形式发送到 OpenID 提供方的其他范围。
  • extraparams:要发送到 OpenID 提供方的其他键值参数。
  • capath:签署身份提供商的网络证书的证书授权机构 (CA) 的证书路径。

    GKE On-Prem 集群使用 TLS 来保护其组件之间的通信。要让 Kubernetes 在安装和节点引导期间自动生成客户端证书,必须使用 CA 安装 GKE On-Prem。

    默认情况下,GKE On-Prem 会在安装过程中创建一个新的 CA,以生成 TLS 证书。CA 和生成的证书存储在管理员集群本地。

示例:对群组进行身份验证和授权

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

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

因此,使用群组策略是最佳做法,因为 GID 既可以是永久性的,也更易于审核。

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

{
  '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-'
...

创建用户集群后,您接着可以使用 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

创建服务器证书授权机构 (CA) 证书

您的用户集群的 kubeconfig 将其主机的 CA 数据存储在其 certificate-authority-data 字段中。您需要解码该值并将解码后的值存储在诸如 server-ca-cert 这样的本地文件中:

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

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

针对 OpenID 设置集群并创建该集群后,用户可以通过将客户端身份验证配置文件传递给 kubectl oidc login 登录该集群。您可以通过输入以下命令生成客户端身份验证配置文件:

Linux

kubectl oidc client-config
--issuer-uri [ISSUER_URI] \
--redirect-uri [REDIRECT_URI] \
--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 [CA_CERT] \
--extra-params [KEY]=[VALUE]
> client-config.yaml
  • [ISSUER_URI] 是您的颁发者 URI。
  • [REDIRECT_URI] 是您的重定向 URI。
  • [CLIENT_ID] 是“kubectl”应用的客户端 ID。
  • [CLIENT_SECRET] 是为您生成的客户端密钥。
  • [USER_CLUSTER_NAME] 是您的用户集群的名称。
  • [CLUSTER_URL] 是用户集群的 Kubernetes API 服务器的网址。
  • --server-ca-file 接受您在上一部分创建的 CA 文件的路径。
  • [CA_CERT] 是颁发者的公共 CA 文件的路径。
  • [CUSTOM_SCOPES] 是用英文逗号分隔的列表,其中包含安全群组的自定义范围。
  • --extra-param 向 OIDC 提供方发送包含身份验证请求的键值对。

PowerShell

kubectl oidc client-config
--issuer-uri [ISSUER_URI] `
--redirect-uri [REDIRECT_URI] `
--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 [CA_CERT] `
--extra-params [KEY]=[VALUE]
> client-config.yaml
  • [ISSUER_URI] 是您的颁发者 URI。
  • [REDIRECT_URI] 是您的重定向 URI。
  • [CLIENT_ID] 是“kubectl”应用的客户端 ID。
  • [CLIENT_SECRET] 是为您生成的客户端密钥。
  • [USER_CLUSTER_NAME] 是您的用户集群的名称。
  • [CLUSTER_URL] 是用户集群的 Kubernetes API 服务器的网址。
  • --server-ca-file 接受您在上一部分创建的 CA 文件的路径。
  • [CA_CERT] 是颁发者的公共 CA 文件的路径。
  • [CUSTOM_SCOPES] 是用英文逗号分隔的列表,其中包含安全群组的自定义范围。
  • --extra-param 向 OIDC 提供方发送包含身份验证请求的键值对。

此命令会生成名为 client-config.yaml 的客户端身份验证文件。请勿手动修改此文件。 每个需要通过用户集群身份验证的员工都应拥有 client-config.yaml

TLS 证书简介

GKE On-Prem 用户集群使用 TLS 保护集群组件之间的所有通信。要让 Kubernetes 在安装和节点引导期间自动生成客户端证书,必须使用 CA 安装 GKE On-Prem。

默认情况下,GKE On-Prem 会在安装过程中创建一个新的 CA,以生成 TLS 证书。CA 和生成的证书存储在管理员集群本地。

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

如需使用客户端身份验证文件通过用户集群身份验证,请从本地机器或虚拟机执行以下步骤:

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

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

    其中:

    • [NAME] 是您选择的用户名。
    • [KUBECONFIG_OUTPUT_PATH] 是存储凭据的 kubeconfig 文件的输出位置。

    kubectl oidc login 会启动浏览器,供用户或员工输入其凭据。

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

  2. 您现在应该已通过身份验证。如需确定您是否已成功通过身份验证,请输入任意 kubectl 命令。例如:

    kubectl get nodes --kubeconfig [KUBECONFIG_OUTPUT_PATH]