更改关联的服务账号


本文档介绍如何将现有虚拟机 (VM) 配置为使用其他服务账号。服务账号是一种特殊类型的账号,通常由应用或计算工作负载用于进行获得授权的 API 调用。

服务账号旨在用于工作负载(例如自定义应用)在没有最终用户参与的情况下访问 Google Cloud 资源或执行操作的场景。如需详细了解何时使用服务账号,请参阅使用服务账号的最佳做法

如果您的应用需要调用 Google Cloud API,Google 建议您将用户管理的服务账号关联到运行应用或工作负载的虚拟机。然后,向服务账号授予 IAM 角色,以便为服务账号(进而为虚拟机上运行的应用)授予对 Google Cloud 资源的访问权限。

准备工作

  • 设置身份验证(如果尚未设置)。身份验证是通过其进行身份验证以访问 Google Cloud 服务和 API 的过程。如需从本地开发环境运行代码或示例,您可以按如下方式向 Compute Engine 进行身份验证。

    Select the tab for how you plan to use the samples on this page:

    Console

    When you use the Google Cloud console to access Google Cloud services and APIs, you don't need to set up authentication.

    gcloud

    1. Install the Google Cloud CLI, then initialize it by running the following command:

      gcloud init
    2. Set a default region and zone.
    3. REST

      如需在本地开发环境中使用本页面上的 REST API 示例,请使用您提供给 gcloud CLI 的凭据。

        Install the Google Cloud CLI, then initialize it by running the following command:

        gcloud init

      如需了解详情,请参阅 Google Cloud 身份验证文档中的使用 REST 时进行身份验证

所需的角色

如需获得在虚拟机上配置服务账号所需的权限,请让您的管理员为您授予该虚拟机或项目的 Compute Instance Admin (v1) (roles/compute.instanceAdmin.v1) IAM 角色。如需详细了解如何授予角色,请参阅管理访问权限

此预定义角色可提供在虚拟机上配置服务账号所需的权限。如需查看所需的确切权限,请展开所需权限部分:

所需权限

在虚拟机上配置服务账号需要以下权限:

  • compute.instances.setServiceAccount
  • compute.instances.stop
  • compute.instances.start

您也可以使用自定义角色或其他预定义角色来获取这些权限。

概览

建议您按照以下步骤为虚拟机配置服务账号:

  1. 创建新的用户管理的服务账号(而不是使用 Compute Engine 默认服务账号),并仅向该服务账号授予所需的 IAM 角色所需的资源和操作。
  2. 将服务账号关联到虚拟机。
  3. 在虚拟机上设置云平台 (https://www.googleapis.com/auth/cloud-platform) 范围。这允许虚拟机的服务账号调用其有权使用的 Google Cloud API。
    • 如果您使用 Google Cloud 控制台指定服务账号,则虚拟机的访问权限范围会自动默认为 cloud-platform 范围。
    • 如果您使用 Google Cloud CLI 或 Compute Engine API 指定服务账号,则可以使用 scopes 参数设置访问权限范围。

设置服务账号

您可以创建用户管理的服务账号,也可以使用 Compute Engine 默认服务账号。建议使用用户管理的服务账号。

对于所选服务账号,请确保已分配所需的 Identity and Access Management (IAM) 角色。

由用户管理

如果您还没有用户管理的服务账号,请先创建一个服务账号。如需了解详细说明,请参阅设置服务账号

默认

如果您熟悉 Compute Engine 默认服务账号,并希望使用默认服务账号提供的凭据而不是创建新服务账号,则可以将 IAM 角色授予默认服务账号。

在将 IAM 角色分配给默认服务账号之前,请注意:

  • 向默认服务账号授予 IAM 角色会影响以默认服务账号的身份运行的所有虚拟机。例如,如果您向默认服务账号授予 roles/storage.objectAdmin 角色,则具有所需访问权限范围且以默认服务账号的身份运行的所有虚拟机都将具有 roles/storage.objectAdmin 角色授予的权限。同样,如果通过省略某些角色来限制访问权限,则会影响以默认服务账号的身份运行的所有虚拟机。

  • 根据您的组织政策配置,默认服务账号可能会自动获得项目的 Editor 角色。我们强烈建议您通过强制执行 iam.automaticIamGrantsForDefaultServiceAccounts 组织政策限制条件来停用自动角色授予功能。如果您的组织是在 2024 年 5 月 3 日之后创建的,则默认情况下会强制执行此限制条件。

    如果您停用自动角色授予功能,则必须决定向默认服务账号授予哪些角色,然后自行授予这些角色

    如果默认服务账号已具有 Editor 角色,我们建议您将 Editor 角色替换为权限较少的角色。如需安全地修改服务账号的角色,请使用 Policy Simulator 查看更改的影响,然后授予和撤消相应的角色

如果您不确定如何向默认服务账号授予 IAM 角色,请改为创建新用户管理的服务账号

关联服务账号并更新访问权限范围

如需更改虚拟机的服务账号和访问权限范围,您必须暂时停止该虚拟机。

如果服务账号与虚拟机位于不同的项目中,则您必须为不同项目中的资源配置服务账号

使用以下方法之一更改虚拟机的服务账号和访问权限范围。

控制台

  1. 转到虚拟机实例页面。

    转到“虚拟机实例”

  2. 点击要为其更改服务账号的虚拟机实例名称。

  3. 如果虚拟机未停止,请点击停止。等待虚拟机停止。

  4. 点击修改

  5. 向下滚动到服务账号部分。

  6. 从下拉列表中,选择要分配给虚拟机的服务账号。

    • 如果您选择用户管理的服务账号,则虚拟机的访问权限范围默认为建议的 cloud-platform 范围。如果用户管理的服务账号需要其他范围,请使用 gcloud CLI 或 Compute Engine API 关联该服务账号。
    • 如果您选择 Compute Engine 默认服务账号,则可以在 Google Cloud 控制台中修改其访问权限范围。
      • 如需更改范围,请在访问权限范围部分中,选择针对每个 API 设置访问权限,并根据需要设置适当的范围。
      • 建议 如果您不确定要设置的正确访问权限范围,请选择允许所有 Cloud API 的全面访问权限,然后确保通过设置服务账号的 IAM 角色来限制访问权限。
  7. 点击保存以保存更改。

  8. 点击启动/恢复以重启虚拟机。

gcloud

  1. 使用 instances stop 命令停止虚拟机。将 VM_NAME 替换为虚拟机实例的名称。

    gcloud compute instances stop VM_NAME
    
  2. 关联服务账号。如需关联服务账号,请使用 instances set-service-account 命令并提供虚拟机名称、服务账号电子邮件地址和所需的范围。如需详细了解如何设置访问权限范围,请参阅最佳做法

    gcloud compute instances set-service-account VM_NAME \
      --service-account=SERVICE_ACCOUNT_EMAIL \
      --scopes=SCOPES
    

    替换以下内容:

    • SERVICE_ACCOUNT_EMAIL:您创建的服务账号的电子邮件地址。例如:my-sa-123@my-project-123.iam.gserviceaccount.com。如需查看电子邮件地址,请参阅列出服务账号

      如果您要从虚拟机中移除服务账号,请使用 --no-service-account 标志。

    • VM_NAME:虚拟机实例的名称。

    • SCOPES--scopes 标志说明中提供的以英文逗号分隔的范围 URI 或别名列表。

      如果要移除虚拟机的所有范围,请改为使用 --no-scopes 标志。

    例如,以下命令将服务账号 my-sa-123@my-project-123.iam.gserviceaccount.com 分配给名为 example-instance 的虚拟机,并对该虚拟机设置访问权限范围,以允许对 Compute Engine 进行读写访问,同时允许对 Google Cloud Storage 进行只读访问:

    gcloud compute instances set-service-account example-instance \
      --service-account=my-sa-123@my-project-123.iam.gserviceaccount.com \
      --scopes=compute-rw,storage-ro
    
  3. 使用 instances start 命令启动虚拟机。将 VM_NAME 替换为虚拟机实例的名称。

    gcloud compute instances start VM_NAME
    

REST

  1. 使用 instances.stop 方法发出 POST 请求以停止虚拟机:

    POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/VM_NAME/stop
    

    替换以下内容:

    • PROJECT_ID:您的虚拟机所在的项目
    • ZONE:虚拟机所在的可用区
    • VM_NAME:您要停止的虚拟机的名称
  2. setServiceAccount 方法发出 POST 请求,以关联服务账号:

    POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/VM_NAME/setServiceAccount
    
    {
      "email": "SERVICE_ACCOUNT_EMAIL",
      "scopes": [
        "SCOPE_URI",
        "SCOPE_URI",
        ...
      ]
    }
    

    替换以下内容:

    • PROJECT_ID:此请求的项目 ID。
    • ZONE:此虚拟机所属的可用区。
    • VM_NAME:虚拟机的名称。
    • SERVICE_ACCOUNT_EMAIL:您创建的服务账号的电子邮件地址。例如:my-sa-123@my-project-123.iam.gserviceaccount.com。如需查看电子邮件地址,请参阅列出服务账号
    • SCOPE_URI:所需的范围 URI

    例如,以下请求使用服务账号电子邮件地址 my-sa-123@my-project-123.iam.gserviceaccount.com 并设置 Cloud Storage 和 BigQuery 范围:

    POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/VM_NAME/setServiceAccount
    
    {
      "email": "my-sa-123@my-project-123.iam.gserviceaccount.com",
      "scopes": [
        "https://www.googleapis.com/auth/bigquery",
        "https://www.googleapis.com/auth/devstorage.read_only"
      ]
    }
    
  3. 使用 instances.start 方法构造 POST 请求以启动虚拟机:

    POST https://www.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/VM_NAME/start
    

    替换以下内容:

    • PROJECT_ID:您的虚拟机所在的项目
    • ZONE:虚拟机所在的可用区
    • VM_NAME:您要启动的虚拟机的名称

查看虚拟机使用的服务账号

如需查看项目中的所有服务账号,请参阅列出服务账号

如果您需要确定虚拟机正在使用的服务账号,请完成以下过程之一:

控制台

  1. 转到虚拟机实例页面。

    转到“虚拟机实例”

  2. 点击要为其更改服务账号的虚拟机实例名称。

  3. 前往 API 和身份管理部分。本部分展示了虚拟机使用的服务账号和访问权限范围。

gcloud

运行 gcloud compute instances describe 命令

gcloud compute instances describe VM_NAME \
    --format json

输出类似于以下内容:

{
  ...
  "serviceAccounts":[
      {
        "email":"123845678986-compute@developer.gserviceaccount.com",
        "scopes":[
            "https://www.googleapis.com/auth/devstorage.full_control"
        ]
      }
  ]
  ...
   }

如果虚拟机未使用服务账号,您会收到不带 serviceAccounts 属性的响应。

元数据服务器

从虚拟机本身查询元数据服务器。向 http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/ 发出请求:

user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/" \
-H "Metadata-Flavor: Google"

如果您在创建实例时启用了一个或多个服务账号,则此 curl 命令将返回如下所示的输出:

123845678986-compute@developer.gserviceaccount.com/
default/

如果实例未使用服务账号,您会收到空响应。

最佳做法

  • 限制服务账号的权限并定期检查服务账号权限以确保其始终能满足需求。
  • 请谨慎删除服务账号。在删除之前,请确保您的关键应用不再使用该服务账号。如果您不确定某个服务账号是否正在使用,我们建议您停用该服务账号,而不是将其删除。已停用的服务账号可以在需要时重新启用。
  • 缓解您的服务账号的安全风险。如需了解详情,请参阅使用服务账号的最佳实践

后续步骤