向 Kubernetes API 服务器进行身份验证


本页面介绍了在连接到 Google Kubernetes Engine (GKE) 集群中的 Kubernetes API 服务器时受支持的身份验证方法。

如需了解如何向 Google Cloud API 对 Kubernetes 工作负载进行身份验证,请参阅适用于 GKE 的工作负载身份联合

概览

Kubernetes API 服务器有多种身份验证方法。在 GKE 中,建议使用 OAuth 身份验证进行集群身份验证并会为您自动配置。

准备工作

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

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

对用户进行身份验证

GKE 通过 Google Cloud CLI 为您管理最终用户身份验证。gcloud CLI 可向 Google Cloud 对用户进行身份验证,设置 Kubernetes 配置,获取集群的 OAuth 访问令牌,并保持访问令牌为最新。

通过验证 kubectl 提供的凭据,并检索与用户或服务账号身份关联的电子邮件地址,所有 GKE 集群都配置为接受 Google Cloud 用户和服务账号身份。因此,这些账号的凭据必须包含 userinfo.email OAuth 范围以成功进行身份验证。

当您使用 gcloud 为新集群或现有集群设置环境的 kubeconfig 时,gcloud 会为 kubectl 提供 gcloud 自身使用的相同凭据。例如,如果使用 gcloud auth login,您的个人凭据会提供给 kubectl,包括 userinfo.email 范围。这样一来,GKE 集群就能够对 kubectl 客户端进行身份验证。

或者,您可以选择对 kubectl 进行配置,使其在 Compute Engine 实例上运行时使用 Google Cloud 服务账号的凭据。不过,默认情况下,userinfo.email 范围并不包含在 Compute Engine 实例创建的凭据中。因此,您必须明确添加此范围,例如在创建 Compute Engine 实例时使用 --scopes 标志。

您可以使用 Identity and Access Management (IAM) 或 Kubernetes 基于角色的访问权限控制 (RBAC) 向集群中的操作授权。

使用 OAuth 进行身份验证

如需使用 OAuth 方法向您的集群进行身份验证,请执行以下操作:

  1. 使用您的凭据登录 gcloud CLI。这会打开一个网络浏览器,以完成向 Google Cloud 进行身份验证的过程:

    gcloud auth login
    
  2. 检索特定集群的 Kubernetes 凭据:

    gcloud container clusters get-credentials CLUSTER_NAME \
        --zone=COMPUTE_ZONE
    
  3. 验证您是否通过身份验证:

    kubectl cluster-info
    

当用户或 Google Cloud 服务账号经过身份验证后,还必须获得授权才能对 GKE 集群执行任何操作。如需详细了解如何配置授权,请参阅基于角色的访问权限控制

对应用进行身份验证

您还可以从 Pod 中的应用向 API 服务器进行身份验证,而无需进行用户互动,例如通过 CI/CD 流水线中的脚本。如何实现这一点取决于应用运行的环境。

同一集群中的应用

如果您的应用在同一 GKE 集群中运行,请使用 Kubernetes 服务账号进行身份验证。

  1. 创建一个 Kubernetes 服务账号并将其关联到您的 Pod。如果您的 Pod 已有 Kubernetes 服务账号,或者您想要使用命名空间的默认服务账号,请跳过此步骤。

  2. 使用 Kubernetes RBAC 向 Kubernetes 服务账号授予应用所需的权限。

    以下示例向 cicd-ns 命名空间中名为 cicd 的服务账号授予 prod 命名空间中资源的 view 权限:

    kubectl create rolebinding cicd-secret-viewer \
        --namespace=prod \
        --clusterrole=view \
        --serviceaccount=cicd-ns:cicd
    
  3. 在运行时,当您的应用发送 Kubernetes API 请求时,API 服务器会对服务账号凭据进行身份验证。

Google Cloud 中的应用

如果您的应用在 Google Cloud 内但在目标集群之外运行(例如 Compute Engine 虚拟机或其他 GKE 集群),您应使用环境中提供的 IAM 服务账号凭据向 API 服务器进行身份验证。

  1. 向您的环境分配 IAM 服务账号。如果您的应用在 Compute Engine 虚拟机内运行,请向实例分配 IAM 服务账号。如果您的应用在其他 GKE 集群中运行,请使用适用于 GKE 的工作负载身份联合将 Pod 配置为作为 IAM 服务账号运行。

    下面的示例使用 ci-cd-pipeline@PROJECT_ID.iam.gserviceaccount.com 作为 IAM 服务账号。

  2. 向 IAM 服务账号授予对集群的访问权限。

    以下示例授予 roles/container.developer IAM 角色,该角色可提供对集群内 Kubernetes API 对象的访问权限:

    gcloud projects add-iam-policy-binding PROJECT_ID \
        --member=serviceAccount:ci-cd-pipeline@PROJECT_ID.iam.gserviceaccount.com \
        --role=roles/container.developer
    

    或者,您也可以使用 RBAC 向 IAM 服务账号授予对集群的访问权限。从同一集群中的应用运行 kubectl create rolebinding 命令,并使用 --user=ci-cd-pipeline@PROJECT_ID.iam.gserviceaccount.com 而不是 --service-account 标志。

  3. 检索集群凭据:

    gcloud container clusters get-credentials CLUSTER_NAME \
        --zone=COMPUTE_ZONE
    

    应用将使用在环境中设置的 IAM 服务账号自动进行身份验证。

其他环境中的应用

如果您的应用从 Google Cloud 外部的环境中进行身份验证,则它无法访问代管式 IAM 服务账号凭据。如需检索集群凭据,您可以创建 IAM 服务账号,下载其密钥,然后在运行时从您的服务中使用该密钥,以通过 gcloud CLI 检索集群凭据。

  1. 为您的应用创建 IAM 服务账号。如果您已有 IAM 服务账号,请跳过此步骤。

    以下命令会创建一个名为 ci-cd-pipeline 的 IAM 服务账号:

    gcloud iam service-accounts create ci-cd-pipeline
    
  2. 向该 IAM 服务账号授予对集群的访问权限。

    以下命令会向 ci-cd-pipeline@PROJECT_ID.iam.gserviceaccount.com IAM 服务账号授予 roles/container.developer IAM 角色:

    gcloud projects add-iam-policy-binding PROJECT_ID \
        --member=serviceAccount:ci-cd-pipeline@PROJECT_ID.iam.gserviceaccount.com \
        --role=roles/container.developer
    

    您也可以使用 RBAC 向 IAM 服务账号授予对集群的访问权限。从同一集群中的应用运行 kubectl create rolebinding 命令,并使用 --user=ci-cd-pipeline@PROJECT_ID.iam.gserviceaccount.com 而不是 --service-account 标志。

  3. 为您的 IAM 服务账号创建并下载密钥。在运行时向您的应用提供该密钥:

    gcloud iam service-accounts keys create gsa-key.json \
        --iam-account=ci-cd-pipeline@PROJECT_ID.iam.gserviceaccount.com
    
  4. 在运行时,在运行应用的环境中,使用您的 IAM 服务账号密钥向 gcloud CLI 进行身份验证:

    gcloud auth activate-service-account ci-cd-pipeline@PROJECT_ID.iam.gserviceaccount.com \
        --key-file=gsa-key.json
    
  5. 使用 gcloud CLI 检索集群凭据:

    gcloud config set project PROJECT_ID
    gcloud container clusters get-credentials CLUSTER_NAME \
        --zone=COMPUTE_ZONE
    

没有 gcloud 的环境

建议使用 gcloud CLI 检索集群凭据,因为这种方法能够灵活应对控制平面 IP 轮替凭据轮替等集群事件。但是,如果您无法在环境中安装 gcloud CLI,则仍可以创建静态 kubeconfig 文件来对集群进行身份验证:

  1. 为您的应用创建 IAM 服务账号。如果您已有 IAM 服务账号,请跳过此步骤。

    以下命令会创建一个名为 ci-cd-pipeline 的 IAM 服务账号:

    gcloud iam service-accounts create ci-cd-pipeline
    
  2. 向该 IAM 服务账号授予对集群的访问权限。

    以下命令会向 ci-cd-pipeline@PROJECT_ID.iam.gserviceaccount.com IAM 服务账号授予 roles/container.developer IAM 角色:

    gcloud projects add-iam-policy-binding PROJECT_ID \
        --member=serviceAccount:ci-cd-pipeline@PROJECT_ID.iam.gserviceaccount.com \
        --role=roles/container.developer
    

    您还可以创建自定义 IAM 角色,以精细控制授予的权限。

  3. 为您的 IAM 服务账号创建并下载密钥。

    在以下示例中,密钥文件名为 gsa-key.json

    gcloud iam service-accounts keys create gsa-key.json \
        --iam-account=ci-cd-pipeline@PROJECT_ID.iam.gserviceaccount.com
    
  4. 获取集群的 endpointclusterCaCertificate 值:

    gcloud container clusters describe CLUSTER_NAME \
        --zone=COMPUTE_ZONE \
         --format="value(endpoint)"
    
    gcloud container clusters describe CLUSTER_NAME \
        --zone=COMPUTE_ZONE \
        --format="value(masterAuth.clusterCaCertificate)"
    
  5. 创建一个包含以下内容的 kubeconfig.yaml 文件:

    apiVersion: v1
    kind: Config
    clusters:
    - name: CLUSTER_NAME
      cluster:
        server: https://endpoint
        certificate-authority-data: masterAuth.clusterCaCertificate
    users:
    - name: ci-cd-pipeline-gsa
      user:
        exec:
          apiVersion: client.authentication.k8s.io/v1beta1
          args:
          - --use_application_default_credentials
          command: gke-gcloud-auth-plugin
          installHint: Install gke-gcloud-auth-plugin for kubectl by following
            https://cloud.google.com/kubernetes-engine/docs/how-to/cluster-access-for-kubectl#install_plugin
          provideClusterInfo: true
    contexts:
    - context:
        cluster: CLUSTER_NAME
        user: ci-cd-pipeline-gsa
      name: CLUSTER_NAME-ci-cd
    current-context: CLUSTER_NAME-ci-cd
    

    替换以下内容:

    • CLUSTER_NAME:您的集群的名称。
    • endpoint:您在上一步中为 endpoint 获取的值。
    • masterAuth.clusterCaCertificate:您在上一步中为 clusterCaCertificate 获取的值(无需解码 base64 编码的证书)。
  6. 在您的环境中,将 kubeconfig.yamlgsa-key.json 与您的应用一起部署。在运行时,在运行应用的环境中设置以下环境变量:

    export KUBECONFIG=path/to/kubeconfig.yaml
    export GOOGLE_APPLICATION_CREDENTIALS=path/to/gsa-key.json
    
  7. 您的应用现在可以向 Kubernetes API 发送请求,并将以 IAM 服务账号的身份进行身份验证。

旧版身份验证方法

在 OAuth 与 GKE 集成之前,预配的 X.509 证书或静态密码是唯一可用的身份验证方法,但现在不再推荐使用此方法,应该停用。这些方法具有更大的危害集群安全的攻击面,在运行 GKE 1.12 及更高版本的集群上默认处于停用状态。如果您使用旧版身份验证方法,我们建议您将其停用。

如果启用,则具有 container.clusters.getCredentials 权限的用户可以检索客户端证书和静态密码。roles/container.adminroles/ownerroles/editor 角色都具有此权限,因此请慎用这些角色。详细了解 GKE 中的 IAM 角色

停用静态密码身份验证

静态密码是 API 服务器验证的用户名和密码组合。在 GKE 中,此身份验证方法称为基本身份验证。

如需更新现有集群并移除静态密码,请运行以下命令:

gcloud container clusters update CLUSTER_NAME --no-enable-basic-auth

停用客户端证书身份验证

使用证书身份验证时,客户端提供一份 API 服务器可向指定的证书颁发机构验证的证书。在 GKE 中,集群根证书授权机构 (CA) 对客户端证书进行签名。

客户端证书身份验证会影响对 Kubernetes API 服务器的授权。如果对集群启用了旧版基于特性的访问权限控制 (ABAC) 授权,则默认情况下客户端证书可以对 API 服务器进行身份验证并对其执行任何操作。另一方面,如果启用了基于角色的访问权限控制 (RBAC),则客户端证书必须获得对 Kubernetes 资源的特定授权。

如需在不生成静态密码的情况下创建集群,请使用 --no-issue-client-certificate 标志:

gcloud container clusters create CLUSTER_NAME \
    --no-issue-client-certificate

目前,无法从现有集群中移除客户端证书。如需停止对现有集群使用客户端证书身份验证,请确保您已对该集群启用了 RBAC,并且客户端证书没有任何对该集群的授权。

后续步骤