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

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

如需了解如何向 Google Cloud API 对 Kubernetes 工作负载进行身份验证,请改为参阅 Workload Identity

概览

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

准备工作

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

使用以下任一方法设定默认的 gcloud 设置:

  • 使用 gcloud init(如果您想要在系统引导下完成默认设置)。
  • 使用 gcloud config(如果您想单独设置项目 ID、区域和地区)。

使用 gcloud init

如果您收到 One of [--zone, --region] must be supplied: Please specify location 错误,请完成本部分。

  1. 运行 gcloud init 并按照说明操作:

    gcloud init

    如果您要在远程服务器上使用 SSH,请使用 --console-only 标志来防止命令启动浏览器:

    gcloud init --console-only
  2. 按照说明授权 gcloud 使用您的 Google Cloud 帐号。
  3. 创建新配置或选择现有配置。
  4. 选择 Google Cloud 项目。
  5. 为可用区级集群选择默认 Compute Engine 可用区,或为区域级集群或 Autopilot 集群选择区域。

使用 gcloud config

  • 设置默认项目 ID
    gcloud config set project PROJECT_ID
  • 如果您使用的是可用区级集群,请设置默认计算可用区
    gcloud config set compute/zone COMPUTE_ZONE
  • 如果您使用的是 Autopilot 集群或区域级集群,请设置默认计算区域
    gcloud config set compute/region COMPUTE_REGION
  • gcloud 更新到最新版本:
    gcloud components update

对用户进行身份验证

GKE 通过 gcloud 命令行工具为您管理最终用户身份验证。gcloud 工具可向 Google Cloud 对用户进行身份验证,设置 Kubernetes 配置,获取集群的 OAuth 访问令牌,并保持访问令牌为最新。您可以控制对集群 Identity and Access Management (IAM) 或 Kubernetes 基于角色的访问权限控制 (RBAC) 的访问权限。

在 OAuth 与 GKE 集成之前,预配的 X.509 证书或静态密码是唯一可用的身份验证方法。在运行 GKE 1.12 及更高版本的新集群上,不再推荐这些方法默认停用。如果您使用旧版身份验证方法,我们建议您迁移这些方法

使用 OAuth 进行身份验证

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

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

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

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

    kubectl cluster-info
    

对服务进行身份验证

有时,您可能需要通过无用户交互的服务(例如 CI/CD 流水线脚本)向 GKE 集群的 API 服务器进行身份验证。如何实现这一点取决于服务运行的环境。

同一 GKE 集群中的服务

如果您的服务在要连接的 GKE 集群的 Pod 中运行,请使用 Kubernetes 服务帐号进行身份验证。

  1. 创建一个 Kubernetes 服务帐号并将其关联到您的 Pod。如果您的 Pod 已有 Kubernetes 服务帐号,则可以跳过此步骤。

    在本示例中,我们使用 cicd-ns 命名空间中名为 cicd 的 Kubernetes 服务帐号。

  2. 使用 Kubernetes RBAC 为 Kubernetes 服务帐号授予正确的权限。

    以下示例在 prod 命名空间中授予 edit 权限:

    kubectl create rolebinding cicd \
        --clusterrole=edit \
        --serviceaccount=cicd-ns:cicd \
        --namespace=prod
    
  3. 运行时,在服务调用 kubectl 后,它会自动接收您配置的凭据。

Google Cloud 中的服务

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

  1. 为您的 Compute Engine 环境分配 Google 服务帐号。如果您的服务在 Compute Engine 虚拟机内运行,请为实例分配一个 Google 服务帐号。如果您的服务在 GKE 集群内运行,请使用 Workload Identity 将您的 Pod 配置为作为 Google 服务帐号运行。

    在本示例中,我们使用 ci-cd-pipeline@PROJECT_ID.iam.gserviceaccount.com 作为 Google 服务帐号。

  2. 为该 Google 服务帐号授予对集群的访问权限。

    在本示例中,我们授予 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
    
  3. 检索集群凭据:

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

    您的服务将自动使用在环境中设置的 Google 服务帐号进行身份验证。

其他环境中的服务

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

  1. 为您的服务创建 Google 服务帐号。如果您已有 Google 服务帐号,则可以跳过此步骤。

    在本示例中,我们创建了一个名为 ci-cd-pipeline 的服务帐号:

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

    在本示例中,我们使用 ci-cd-pipeline@PROJECT_ID.iam.gserviceaccount.com 作为 Google 服务帐号,并授予 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
    

    您还可以使用 Kubernetes RBAC 授予此访问权限,以实现更精细的控制。

  3. 为您的 Google 服务帐号创建并下载密钥。在运行时将其用于您的服务:

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

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

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

没有 gcloud 的环境

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

  1. 为您的服务创建 Google 服务帐号。如果您已有 Google 服务帐号,则可以跳过此步骤。

    在本示例中,我们创建了一个名为 ci-cd-pipeline 的服务帐号:

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

    在本示例中,我们使用 ci-cd-pipeline@PROJECT_ID.iam.gserviceaccount.com 作为 Google 服务帐号,并授予 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
    

    您还可以使用 Kubernetes RBAC 授予此访问权限,以实现更精细的控制。

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

    在本示例中,密钥文件名为 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:
        auth-provider:
          name: gcp
    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. 您的服务现在可以调用 kubectl 并将作为 Google 服务帐号进行身份验证。

旧版身份验证方法

在 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,并且客户端证书没有任何对该集群的授权。

后续步骤