常见问题解答和问题排查

Cloud Asset Inventory 是否为全球服务?

是。Cloud Asset API 不依赖于位置。它具有一个全球端点,该端点提供 Cloud Asset Inventory 中所有受支持的区域和全球资源的元数据。Cloud Asset API 可以在任何可用区中访问。

Cloud Asset Inventory 提供什么样的数据一致性?

Cloud Asset Inventory 可确保当前数据最终一致,并尽力确保历史数据一致。虽然在实践中发生这种情况的几率很低,但 Cloud Asset Inventory 可能会错过过去某个资产的一些更新。

为什么我无权使用 Cloud Asset API?

如果您无权导出资产,或者无权获取组织、项目或文件夹的历史记录,则系统会返回错误。

例如,若您不具备权限,则运行以下命令:

curl -X POST \
     -H "X-Goog-User-Project: BILLING_PROJECT_ID" \
     -H "Authorization: Bearer $(gcloud auth print-access-token)" \
     -H "Content-Type: application/json" \
     -d '{
          "outputConfig": {
            "gcsDestination": {
              "uri": "gs://BUCKET_NAME/FILENAME"
            }
          }
         }' \
         https://cloudasset.googleapis.com/v1/projects/PROJECT_ID:exportAssets

返回以下错误:

{
  "error": {
    "code": 403,
    "message": "The caller does not have permission",
    "status": "PERMISSION_DENIED",
    "details": [
      {
        "@type": "type.googleapis.com/google.rpc.DebugInfo",
        "detail": "[ORIGINAL ERROR] generic::permission_denied: Request
        denied by Cloud IAM."
      }
    ]
  }
}

要解决该问题,请向项目、文件夹或组织管理员请求访问权限。根据您尝试导出或获取其历史记录的资产的不同,您需要具备以下其中一个角色或包含所需 Cloud Asset API 权限的其他角色:

  • cloudasset.viewer

  • cloudasset.owner

如需详细了解角色和权限,请参阅了解角色

如需详细了解 Cloud Asset API 的访问权限控制选项,请参阅访问权限控制

为什么我的导出操作会返回权限被拒绝的错误?

除非您另有说明,否则 Cloud Asset Inventory 会使用有效项目中的默认 Cloud Asset Inventory 服务账号来管理 Pub/Sub 主题、Cloud Storage 存储桶和 BigQuery 表等资源。此服务账号会在您首次从项目调用 Cloud Asset Inventory API 时创建,并且默认情况下有权管理这些资源(前提是这些资源位于同一项目中)。

在以下情况下,您可能会收到权限被拒绝的错误:

  • 使用 REST API 时,该 API 不会设置有效的项目,因此 Cloud Asset Inventory 不知道要使用哪个服务账号。

  • 使用 gcloud CLI 所在的项目与 Pub/Sub 主题、Cloud Storage 存储桶或 BigQuery 表格的位置。这意味着,系统会使用当前项目的默认 Cloud Asset Inventory 服务账号来执行任务(如果存在),并且该账号可能没有写入其他项目资源的权限。

确保在发出导出请求时使用的是正确的服务账号 Pub/Sub 主题、Cloud Storage 存储分区或 BigQuery 表,您可以指定包含正确默认值的项目 ID Cloud Asset Inventory 服务账号。如果您要从一个项目导出到另一个项目, 您还需要向服务账号授予特定角色

gcloud

对于 gcloud CLI,请将 --billing-project 标志添加到您的 命令指定包含正确服务账号的项目 ID:

--billing-project=BILLING_PROJECT_ID

或者,您也可以在使用命令运行命令之前设置结算项目 gcloud CLI首先,检查结算项目是否有所不同 从核心项目中:

gcloud config list

然后,根据需要设置结算项目:

gcloud config set billing/quota_project BILLING_PROJECT_ID

请提供以下值:

  • BILLING_PROJECT_ID:具有以下属性的项目 ID: 已启用 Cloud Asset Inventory API 以及有权 管理目标 Pub/Sub 主题、Cloud Storage 存储桶或 BigQuery 表。

REST

对于 REST API,请添加 X-Goog-User-Project 标头以指定包含正确服务账号的项目 ID。使用 curl 时,您将设置 带有 -H 标志的标头:

-H "X-Goog-User-Project: BILLING_PROJECT_ID"

请提供以下值:

  • BILLING_PROJECT_ID:已启用 Cloud Asset Inventory API 的项目 ID,以及具有管理目标 Pub/Sub 主题、Cloud Storage 存储桶或 BigQuery 表的权限的服务账号。

将资产元数据从一个项目导出到另一个项目

如需导出一个项目 (PROJECT_A) 中的资产元数据,请执行以下操作: 另一个是 PROJECT_B,则必须指定默认值 PROJECT_A 中的 Cloud Asset Inventory 服务账号对 PROJECT_B 中的资源。这有两点好处:

  • 您可以将资产元数据从 PROJECT_A 导出到 Pub/Sub 主题、Cloud Storage 存储桶或 BigQuery 位于 PROJECT_B 的表格。

  • 您可以使用 PROJECT_A 从以下位置导出资产元数据: PROJECT_B写入 Pub/Sub 主题 Cloud Storage 存储桶,或位于 PROJECT_B

如需将资产元数据从一个项目导出到另一个项目中,请完成以下操作 操作说明:

  1. 确保 Cloud Asset Inventory API 是否已在您要运行请求的项目中启用, PROJECT_A

  2. 在以下位置至少调用 Cloud Asset Inventory API: PROJECT_A,用于创建默认的 Cloud Asset Inventory 服务账号。或者,您也可以手动创建:

    gcloud beta services identity create \
        --service=cloudasset.googleapis.com \
        --project=PROJECT_A_ID
    gcloud projects add-iam-policy-binding PROJECT_A_ID \
        --member=serviceAccount:service-PROJECT_A_NUMBER@gcp-sa-cloudasset.iam.gserviceaccount.com \
        --role=roles/cloudasset.serviceAgent
    

    如何查找 Google Cloud 项目编号

    控制台

    如需查找 Google Cloud 项目编号,请完成以下步骤:

    1. 前往 Google Cloud 控制台中的信息中心页面。

      转到信息中心

    2. 点击菜单栏中的切换器框。
    3. 请选择框中选择您的组织,然后搜索项目名称。
    4. 点击项目名称以切换到相应项目。项目编号显示在 项目信息卡片。

    gcloud CLI

    您可以使用以下命令检索 Google Cloud 项目编号:

    gcloud projects describe PROJECT_ID --format="value(projectNumber)"

  3. 向服务账号授予正确的权限。

    • 要通过 Pub/Sub 发布到 Feed,请授予 为该主题将 roles/pubsub.publisher 角色授予服务账号:

      gcloud pubsub topics add-iam-policy-binding projects/PROJECT_B_ID/topics/TOPIC_ID \
          --member=serviceAccount:service-PROJECT_A_NUMBER@gcp-sa-cloudasset.iam.gserviceaccount.com \
          --role=roles/pubsub.publisher
      
    • 如需写入 Cloud Storage 存储桶,请向存储桶上的服务账号授予 roles/storage.objectCreator 角色:

      gcloud storage buckets add-iam-policy-binding gs://BUCKET_NAME \
        --member=serviceAccount:service-PROJECT_A_NUMBER@gcp-sa-cloudasset.iam.gserviceaccount.com \
        --role=roles/storage.objectCreator
      
    • 如需写入 BigQuery 表,请向 BigQuery 表授予 拥有服务的 roles/bigquery.dataEditorroles/bigquery.user 角色 账号:

      gcloud projects add-iam-policy-binding PROJECT_B_ID \
          --member=serviceAccount:service-PROJECT_A_NUMBER@gcp-sa-cloudasset.iam.gserviceaccount.com \
          --role=roles/bigquery.user
      gcloud projects add-iam-policy-binding PROJECT_B_ID \
          --member=serviceAccount:service-PROJECT_A_NUMBER@gcp-sa-cloudasset.iam.gserviceaccount.com \
          --role=roles/bigquery.dataEditor
      

发出 Cloud Asset Inventory 请求时,请务必将 PROJECT_A 指定为要使用的项目。如需为 gcloud CLI 执行此操作,请将 --billing-project 标志设置为 PROJECT_A_ID。对于 REST,请设置 X-Goog-User-Project 设为 PROJECT_A_ID

为什么 Cloud Asset API 结果已过时?

系统会尽力确保 Cloud Asset API 中数据的新鲜度。虽然几乎所有 资源更新在数分钟内便可提供给客户,极少数情况下 Cloud Asset API 方法的结果将不包含最新的资产 更新。

为什么运行 ExportAssets 后输出临时文件?

ExportAssets 操作可能会在输出文件夹中创建临时文件。操作正在进行时,请勿移除这些临时文件。操作完成后,系统会自动移除临时文件。

如果临时文件仍然存在,则您可以在 ExportAssets 操作完成后,安全地移除这些临时文件。

为什么我的 Google Cloud CLI 或 Cloud Shell 凭据被拒绝?

如果包含用户项目的请求从 Google Cloud CLI 或 Cloud Shell 发送到 cloudasset.googleapis.com,您会收到如下所示的错误消息:

Your application has authenticated using end user credentials from the
Google Cloud CLI or Cloud Shell which are not supported by the
cloudasset.googleapis.com. We recommend that most server applications
use service accounts instead. For more information about service accounts
and how to use them in your application, see
https://cloud.google.com/docs/authentication/.

要解决此问题,请将用户项目设置为已启用 Cloud Asset API 的用户项目。 项目 ID。这可以通过在 HTTP 请求中指定 HTTP 标头 X-Goog-User-Project 来实现。

如果您使用的是 curl,则可通过添加以下参数来实现此目的:

-H "X-Goog-User-Project: PROJECT_ID"

如果您使用的是 gcloud CLI,请指定标志 --billing-project PROJECT_ID,以及 gcloud asset 命令,或使用以下命令:

gcloud config set billing/quota_project PROJECT_ID

为什么同一资产具有不同的祖先实体?

在调用 Cloud Asset API 获取不同的元数据类型时(例如同一资产的 RESOURCE 元数据和 IAM POLICY 元数据),ancestors 字段可能会在内容类型之间不一致。这是因为 每种内容类型都有不同的数据注入时间表,直到 提取过程完成后,可能会出现不一致的情况。查看 update_time 字段,以确保素材资源包含最新的 信息。

如果不一致的情况持续超过 24 小时,请与我们联系

应以怎样的频率调用 ExportAssets API?

我们建议为同一个项目、文件夹或 ExportAssets API 调用 有序组织;例如,在 上一个任务就完成了如需实时捕获资产更新,请考虑使用实时通知

接收到重复的资产更新

设置实时通知后,您可能会在 Pub/Sub 主题中收到重复的资产更新。这是由于系统自动尝试重新递送所造成的, Pub/Sub 不保证至少传送一次

为什么我没有收到项目删除通知?

项目关停后,您可以在 30 天内撤消操作。只有在项目被永久删除后,才会设置通知中的 deleted 字段。监控待处理的项目 您可以使用条件来设置 Feed, 针对项目的 lifecycleState,例如 temporal_asset.asset.resource.data.lifecycleState == "DELETE_REQUESTED"

如何使用 SearchAllResources API 检索资源的 JSON 表示法?

默认情况下,如果未指定 read_maskSearchAllResources 会返回以下标准字段:

  • name

  • assetType

  • project

  • folders

  • organization

  • displayName

  • description

  • location

  • labels

  • networkTags

  • kmsKeys

  • createTime

  • updateTime

  • state

  • additionalAttributes

  • parentFullResourceName

  • parentAssetType

如果您想检索资源元数据中的所有字段(除了上述字段之外),可以在搜索请求中指定 read_mask 标志(在 gcloud 中为 --read-mask)。

read_mask 是您要返回的一系列字段(以英文逗号分隔) 结果。某些字段(例如 versionedResourcesattachedResources)太大,因此默认不会包含在结果中。接收者 可以在 read_mask 中进行指定;或使用 "*" 包含所有可用字段read_mask 值的示例包括:"name,location""name,versionedResources""*"

下面是一个 gcloud 示例:

gcloud asset search-all-resources \
    --scope=organizations/123456 \
    --query="state=RUNNING" \
    --asset-types=compute.googleapis.com/Instance \
    --read-mask="name,versionedResources"