使用服务身份进行身份验证

Google Distributed Cloud (GDC) 空气隔离环境中的服务身份可为工作负载或服务提供专用身份,以便以编程方式安全地访问资源和微服务。这些是应用或工作负载(而非人员)使用的特殊身份,不能用于人员登录。与用户账号类似,您可以向服务身份授予权限和角色,以定义其获授权可访问的内容。

您可能会注意到,此概念使用了两个术语。GDC 控制台主要使用“服务身份”一词,而 gdcloud 命令和 API 交互通常使用“服务账号一词。后者反映了底层 Kubernetes 自定义资源 ProjectServiceAccount 的名称。这两个术语指的是同一事物:工作负载的非人类身份。本文档主要使用“服务身份”一词。

服务身份有助于管理 GDC 基础架构,例如:

  • 内部 Distributed Cloud 服务和工作负载,用于安全访问 Distributed Cloud 控制平面应用编程接口 (API)。例如,数据库服务与 Kubernetes API 交互以创建和删除数据库。
  • Distributed Cloud 中的客户工作负载,用于访问 Distributed Cloud 服务并进行授权的应用编程接口 (API) 调用。例如,服务身份可以使用 Vertex AI Workbench 笔记本通过 Speech-to-Text API 转写音频文件来管理客户。
  • 要与分布式云联合的外部工作负载。例如,服务身份可以管理 Distributed Cloud 外部的应用,该应用可将文档数字化,但希望使用光学字符识别 (OCR) API 来替换其当前的 OCR 引擎。
  • 分布式云服务或系统控制器,用于安全地访问客户资源或用户集群。例如,服务身份可以管理身份验证和授权工作流,其中在管理员集群中运行的服务控制器需要在客户管理的用户集群中运行工作负载。

您可以使用 GDC 控制台、gdcloud CLI 或 API 管理服务身份的账号。借助 gdcloud CLI,服务身份功能基于全局 ProjectServiceAccount API 构建。由于 ProjectServiceAccount 资源是全局配置的,因此可在 gdcloud 领域中的所有可用区内运行。

准备工作

您只能在项目内创建服务身份。如需了解如何创建项目,请参阅创建项目

管理服务身份涉及服务身份(由 ProjectServiceAccount 资源表示)及其关联的凭据(公钥/私钥对)。如需获得管理服务身份及其凭据所需的权限,请让组织 IAM 管理员或项目 IAM 管理员向您授予相应项目的项目 IAM 管理员 (project-iam-admin) 角色。

创建服务身份

创建服务身份包括创建账号及其关联的凭据。

创建账号

如需为服务身份创建账号,请使用 GDC 控制台、gdcloud CLI 或 API 在项目中创建 ProjectServiceAccount 资源。

控制台

  1. 登录 GDC 控制台。
  2. 在导航菜单中,选择身份和访问权限 > 服务身份
  3. 点击创建服务身份。 系统会打开服务身份详细信息页面。
  4. 服务身份名称字段中,输入服务身份的名称。例如:testserviceidentity
  5. 点击创建

gdcloud

创建账号:

gdcloud iam service-accounts create NAME \
    --project=PROJECT

替换以下值:

  • NAMEProjectServiceAccount 的名称。该名称在项目命名空间中必须是唯一的。
  • PROJECT:要在其中创建服务身份的项目。如果已设置 gdcloud init,请省略 --project 标志。

此命令会在管理 API 服务器上的项目命名空间中创建 ProjectServiceAccount

API

  1. 创建 ProjectServiceAccount 自定义资源 YAML 文件,例如 my-project-sa.yaml

    apiVersion: resourcemanager.global.gdc.goog/v1
    kind: ProjectServiceAccount
    metadata:
      name: NAME
      namespace: PROJECT
    spec:
      keys:
      - algorithm: ALGORITHM
      id: KEY_ID
      key: BASE64_ENCODED_KEY
      validAfter: "START_TIME"
      validBefore: "EXPIRATION_TIME"
    

    执行以下变量替换操作:

    • NAMEProjectServiceAccount 资源的名称。该名称在项目命名空间中必须是唯一的。
    • PROJECT:要在其中创建服务身份的项目。
    • ALGORITHM:密钥的算法。仅支持 ES256 密钥。
    • KEY_ID:密钥的唯一标识符。该 ID 用于确定要使用哪个密钥进行验证。
    • BASE64_ENCODED_KEY:用于验证的 PEM 格式的 base64 编码公钥。用于生成此公钥的私钥应采用 ECDSA P256 PEM 格式。
    • START_TIME:密钥生效的开始时间,例如 2025-02-07T00:59:34Z
    • EXPIRATION_TIME:密钥的过期时间,例如 2026-02-07T00:59:34Z
  2. ProjectServiceAccount 自定义资源应用于全局 API 服务器:

    kubectl --kubeconfig GLOBAL_API_SERVER_KUBECONFIG apply -f my-project-sa.yaml
    

    GLOBAL_API_SERVER_KUBECONFIG 变量替换为全局 API 服务器的 kubeconfig 文件的路径。

创建凭据

如需让工作负载或应用以服务身份(由您创建的账号表示)进行身份验证,您需要生成凭据。创建凭据涉及生成加密私钥和公钥对,并将公钥与服务身份相关联。

如需为服务身份创建凭据,请使用 GDC 控制台、gdcloud CLI 或 API。

控制台

  1. 登录 GDC 控制台。
  2. 在导航菜单中,依次选择身份和访问权限 > 服务身份
  3. 点击要在密钥中添加的服务身份的名称。
  4. 点击创建新密钥
  5. 新密钥会显示在密钥列表中,并且系统会显示一个对话框,确认您已成功创建密钥。

gdcloud

gdcloud 命令会创建应用默认凭据 JSON 文件以及公钥/私钥对:

gdcloud iam service-accounts keys create APPLICATION_DEFAULT_CREDENTIALS_FILENAME \
    --project=PROJECT \
    --iam-account=NAME \
    --ca-cert-path=CA_CERTIFICATE_PATH

替换以下值:

  • APPLICATION_DEFAULT_CREDENTIALS_FILENAME:JSON 文件的名称。
  • PROJECT:选择要为其创建密钥的项目。 如果已设置 gdcloud init,则可以省略 --project 标志。
  • NAME:要为其添加密钥的服务身份的名称。
  • CA_CERTIFICATE_PATH:可选:用于验证身份验证端点的证书授权机构 (CA) 证书路径。如果您未指定此路径,系统会使用系统 CA 证书。 您必须在系统 CA 证书中安装 CA。

Distributed Cloud 会将公钥添加到用于验证私钥签名的 JSON Web 令牌 (JWT) 的密钥中。ProjectServiceAccount私钥会写入应用默认凭据 JSON 文件。

以下示例展示了应用默认凭据 JSON 文件:

{
"type": "gdch_service_account",
"format_version": "1",
"project": "project_name",
"private_key_id": "abcdef1234567890",
"private_key": "-----BEGIN PRIVATE KEY-----\nETC\n-----END PRIVATE KEY-----\n",
"name": "service_identity_name",
"ca_cert_path": "/path/to/ca.crt",
"token_uri": "https://service-identity.<Domain>/authenticate"
}

此示例使用以下值:

  • project:组织中的项目命名空间。
  • private_key_id:分配给密钥的 ID。
  • private_key:CLI 生成的 PEM 格式的 ECDSA P256 私钥。
  • name:服务身份的名称。
  • ca_cert_path:用于验证身份验证端点的证书授权机构 (CA) 证书的路径。
  • token_uri:身份验证端点的地址。

API

  1. 生成公钥和私钥对。以下命令以 openssl 为例,这是一种常用的此类工具。

    openssl ecparam -name prime256v1 -genkey -noout -out "key.pem"
    openssl ec -in "key.pem" -pubout > "pub.pem"
    
  2. 对公钥进行 Base64 编码并检索其密钥 ID:

    KEY_ID=$(openssl pkey -in key.pem -pubout -outform der | openssl dgst -sha256 | sed 's/^.* //')
    BASE64_ENCODED_KEY=$(cat pub.pem | base64)
    
  3. 创建或更新 ProjectServiceAccount 自定义资源 YAML 文件,包括上一步中生成的密钥信息:

    apiVersion: resourcemanager.global.gdc.goog/v1
    kind: ProjectServiceAccount
    metadata:
      name: NAME
      namespace: PROJECT
    spec:
      keys:
      - algorithm: ALGORITHM
      id: KEY_ID
      key: BASE64_ENCODED_KEY
      validAfter: "START_TIME"
      validBefore: "EXPIRATION_TIME"
    

    执行以下变量替换操作:

    • NAMEProjectServiceAccount 资源的名称。该名称在项目命名空间中必须是唯一的。
    • PROJECT:您要在其中创建密钥的项目。
    • ALGORITHM:密钥的算法。仅支持 ES256 密钥。
    • KEY_ID:密钥的唯一标识符。该 ID 用于确定要使用哪个密钥进行验证。
    • BASE64_ENCODED_KEY:用于验证的 PEM 格式的 base64 编码公钥。用于生成此公钥的私钥应采用 ECDSA P256 PEM 格式。
    • START_TIME:密钥生效的开始时间,例如 2025-02-07T00:59:34Z
    • EXPIRATION_TIME:密钥的过期时间,例如 2026-02-07T00:59:34Z
  4. ProjectServiceAccount 自定义资源应用到全局 API 服务器:

    kubectl --kubeconfig GLOBAL_API_SERVER_KUBECONFIG apply -f my-project-sa.yaml
    

    GLOBAL_API_SERVER_KUBECONFIG 变量替换为全局 API 服务器的 kubeconfig 文件的路径。

  5. 创建包含私钥的应用默认凭据 JSON 文件。确保 JSON 文件中的 KEY_ID 变量设置为与您在 ProjectServiceAccount 规范中使用的 KEY_ID 变量相同的值。

    cat <<EOF > "key_file.json"
    {
      "format_version": "1",
      "name": "NAME",
      "private_key": "$(tr '\n' '\t' < "key.pem" | sed 's/\t/\\n/g')",
      "private_key_id": "KEY_ID",
      "project": "PROJECT",
      "token_uri": "AUTH_URL",
      "type": "gdch_service_account"
    }
    EOF
    

    执行以下变量替换操作:

    • NAME:服务身份的名称。
    • KEY_ID:密钥的唯一标识符。该 ID 用于确定要验证的密钥,并且必须与 ProjectServiceAccount 规范中使用的 KEY_ID 值一致。
    • PROJECT:组织中的项目命名空间。
    • AUTH_URL:身份验证端点的地址。

如需详细了解如何使用生成的密钥文件以该服务身份对 gcloud CLI 进行身份验证,请参阅使用密钥授权服务身份部分。

查看服务身份

本部分介绍了如何查看服务身份及其关联的公钥。

查看服务身份列表

如需查看项目中的服务身份列表,请使用 GDC 控制台或 gdcloud CLI。

控制台

  1. 登录 GDC 控制台。
  2. 选择一个项目。
  3. 在导航菜单中,点击身份和访问权限 > 服务身份,查看项目的服务身份列表。

gdcloud

列出项目中的服务身份账号:

gdcloud iam service-accounts list \
    --project=PROJECT

PROJECT 替换为项目 ID。

查看服务身份的公钥列表

列出项目中向服务身份账号注册的公钥:

gdcloud iam service-accounts keys list \
    --project=PROJECT \
    --iam-account=NAME

替换以下内容:

  • PROJECT:项目 ID。
  • NAME:要使用的服务身份账号的名称。

授予服务身份权限

如需向服务身份授予权限,请使用 GDC 控制台或 gdcloud CLI 创建角色绑定,为其分配一个或多个角色。

控制台

  1. 登录 GDC 控制台。
  2. 选择一个项目。
  3. 在导航菜单中,依次选择身份和访问权限 > 访问权限
  4. 成员列表中,点击 添加成员。 系统会显示用户和角色页面。
  5. 成员类型列表中选择服务身份
  6. 服务身份列表中,选择要为其分配角色绑定的服务身份。
  7. 角色列表中,选择要分配给服务身份的角色,例如 Backup Creator
  8. 可选:如需添加其他角色,请点击添加其他角色。 选择其他角色。
  9. 点击 Add(添加)。

gdcloud

您可以将服务身份账号绑定到项目命名空间内的角色,也可以绑定到其他命名空间中的角色。

  • 将账号绑定到项目命名空间中的角色:

    gdcloud iam service-accounts add-iam-policy-binding \
        --project=PROJECT \
        --role=ROLE \
        --iam-account=NAME
    

    替换以下内容:

    • PROJECT:要在其中创建角色绑定的项目。如果已设置 gdcloud init,则可以省略 --project 标志。
    • ROLE:要分配给账号的预定义角色。以 Role/name 格式指定角色,其中 Role 是 Kubernetes 类型 IAMRolename 是预定义角色的名称。例如,如需分配 Project Viewer 角色,请将角色设置为 IAMRole/project-viewer
    • NAME:要使用的服务身份账号的名称。
  • 将账号绑定到其他命名空间中的角色:

    gdcloud iam service-accounts add-iam-policy-binding \
        --role=ROLE \
        --role-namespace=ROLE_NAMESPACE \
        --iam-account=NAME
    

    替换以下内容:

    • ROLE:要分配给账号的预定义角色。以 Role/name 格式指定角色,其中 Role 是 Kubernetes 类型 IAMRolename 是预定义角色的名称。例如,如需分配 Project Viewer 角色,请将角色设置为 IAMRole/project-viewer
    • ROLE_NAMESPACE:要与账号绑定的角色(项目命名空间除外)的命名空间。
    • NAME:要使用的服务身份账号的名称。

进行身份验证并使用服务身份

如需将 gdcloud 和其他工具配置为以服务身份运行,您必须先使用服务身份的密钥文件向 gdcloud 进行身份验证。完成身份验证后,您可以使用服务身份的凭据生成令牌或 kubeconfig 文件。

使用密钥授权服务身份

gdcloud auth activate-service-account 命令使用服务身份对 gcloud CLI 进行身份验证。这样一来,您就可以使用服务身份账号权限(而非用户账号)对分布式云资源执行操作。

使用密钥授权服务身份:

  1. 如果您还没有凭据密钥文件,请创建一个

  2. 运行以下命令以激活服务身份:

    gdcloud auth activate-service-account --key-file=KEY_FILE
    

    KEY_FILE 替换为凭据密钥文件的路径,该文件通常采用 JSON 格式。

    成功激活后,gdcloud 会使用服务身份的凭据,而不是您的用户凭据。

授权服务身份后,您可以为其打印身份令牌。您可以使用此令牌作为不记名令牌来验证 HTTP 请求。这意味着,令牌会授予持有它的任何一方访问 AUDIENCES 参数中定义的服务。

为指定的服务身份账号打印身份令牌:

gdcloud auth print-identity-token --audiences=AUDIENCES

AUDIENCES 替换为令牌的目标收件人或服务。只能指定一个受众群体。

生成 kubeconfig 文件

授权服务身份后,您可以生成 kubeconfig 文件以向集群进行身份验证。

  1. 设置 gdcloud core/organization_console_url 属性:

    gdcloud config set core/organization_console_url
    https://GDC_URL
    

    GDC_URL 替换为贵组织的网址。

  2. 生成 kubeconfig 文件以使用有效的服务身份访问集群:

    • 对于可用区级集群

      export KUBECONFIG=KUBECONFIG_PATH
      gdcloud clusters get-credentials CLUSTER_NAME --zone ZONE
      

      替换以下内容:

      • KUBECONFIG_PATH:您要保存生成的 kubeconfig 文件的路径。
      • CLUSTER_NAME:可用区级集群的名称。

      • ZONE:集群所在可用区的名称。

    • 对于全局 API 服务器

      export KUBECONFIG=KUBECONFIG_PATH
      gdcloud clusters get-credentials global-api
      

      KUBECONFIG_PATH 替换为您要保存生成的 kubeconfig 文件的路径。

系统会生成一个 kubeconfig 文件,该文件配置为以服务身份进行身份验证。以下示例展示了一个 YAML 文件:

apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: <REDACTED>
    server: <REDACTED>
  name: cluster-name
contexts:
- context:
    cluster: cluster-name
    user: gdch_console-<REDACTED>_cluster-name
  name: cluster-name-gdch_console-<REDACTED>_cluster-name
current-context: cluster-name-gdch_console-gdc1-staging-gpcdemolabs-com_cluster-name
kind: Config
preferences: {}
users:
- name: gdch_console-<REDACTED>_cluster-name
  user:
    exec:
      apiVersion: client.authentication.k8s.io/v1
      args:
      - --audience=<REDACTED>
      command: gdcloud-k8s-auth-plugin
      env: null
      installHint: Run 'gdcloud components install gdcloud-k8s-auth-plugin' to use
        plugin
      interactiveMode: Never
      provideClusterInfo: false

删除服务身份

删除服务身份后,ProjectServiceAccount 及其关联的公钥会被删除,现有的私钥会失效,应用将无法再通过该服务身份访问项目资源。

如需删除服务身份,请使用 GDC 控制台或 gdcloud CLI。

控制台

  1. 登录 GDC 控制台。
  2. 在导航菜单中,依次选择身份和访问权限 > 服务身份
  3. 选中要删除的服务身份对应的复选框。
  4. 点击删除
  5. 系统会显示确认对话框。在请在下面输入以下内容进行确认字段中,输入 remove
  6. 点击删除

gdcloud

运行以下命令可删除服务身份:

gdcloud iam service-accounts delete NAME \
    --project=PROJECT

替换以下内容:

  • NAME:要删除的服务身份账号的名称。
  • PROJECT:项目 ID。

删除凭据

如果您想停用特定密钥对,但不想删除整个服务身份账号,可以从服务身份账号中删除其公钥。此操作会使相应的私钥失效。

如需删除公钥,请使用 GDC 控制台或 gdcloud CLI。

控制台

  1. 登录 GDC 控制台。
  2. 在导航菜单中,依次选择身份和访问权限 > 服务身份
  3. 点击包含要删除的密钥的服务身份的名称。
  4. 点击删除
  5. 在确认对话框中点击删除

gdcloud

从项目中的服务身份账号中移除具有相应密钥 ID 的公钥:

gdcloud iam service-accounts keys delete KEY_ID \
    --project=PROJECT \
    --iam-account=NAME

替换以下内容:

  • KEY_ID:密钥的唯一标识符。
  • PROJECT:项目 ID。
  • NAME:服务身份账号的名称。