查看和查询虚拟机元数据


每个虚拟机 (VM) 都将其元数据存储在元数据服务器的目录中。您的虚拟机可自动获得对该元数据服务器 API 的访问权限,而无需任何额外的授权。您可以使用本文档以下部分中所述的方法来查看和查询虚拟机元数据值:

如果您在访问元数据服务器时遇到错误,请参阅排查元数据服务器访问问题

准备工作

  • 对于 Windows Server 虚拟机,请使用 PowerShell 3.0 或更高版本。我们建议您使用 ctrl+v 来粘贴复制的代码块。
  • 查看有关如何定义 Compute Engine 的虚拟机元数据、对其进行分类和安排的基础知识。如需了解详情,请参阅虚拟机元数据简介
  • 设置身份验证(如果尚未设置)。身份验证是通过其进行身份验证以访问 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. Python

      如需在本地开发环境中使用本页面上的 Python 示例,请安装并初始化 gcloud CLI,然后使用您的用户凭据设置应用默认凭据。

      1. Install the Google Cloud CLI.
      2. To initialize the gcloud CLI, run the following command:

        gcloud init
      3. If you're using a local shell, then create local authentication credentials for your user account:

        gcloud auth application-default login

        You don't need to do this if you're using Cloud Shell.

      如需了解详情,请参阅 Set up authentication for a local development environment

      REST

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

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

        gcloud init

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

所需的角色

使用 Google Cloud 控制台、Google Cloud CLI 或 REST 从虚拟机外部查看自定义元数据需要以下角色和权限。如果您以编程方式从虚拟机内部查询元数据,则只需要用于连接到虚拟机的角色和权限。

如需获得从虚拟机外部查看查看自定义元数据所需的权限,请让管理员向您授予以下 IAM 角色:

如需详细了解如何授予角色,请参阅管理对项目、文件夹和组织的访问权限

这些预定义角色包含从虚拟机外部查看自定义元数据所需的权限。如需查看所需的确切权限,请展开所需权限部分:

所需权限

从虚拟机外部查看自定义元数据需要以下权限:

  • 如需查看自定义项目元数据:针对项目的 compute.projects.get 权限
  • 查看自定义的可用区级元数据:项目所需可用区中实例设置的 compute.instanceSettings.get 权限
  • 查看虚拟机实例的自定义元数据:虚拟机的 compute.instances.get 权限
  • 如果您的虚拟机使用服务账号:针对服务账号或项目的 iam.serviceAccounts.actAs

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

以编程方式查询元数据

您可以通过以编程方式从 Linux 或 Windows 虚拟机内查询元数据值条目,访问所有元数据。在虚拟机中,您可以使用 Linux 上的 curl 或 Windows 上的 Invoke-RestMethod 等工具,以编程方式通过以下方式之一查询元数据值:

元数据服务器端点

如需从虚拟机内以编程方式查询元数据,您可以使用以下元数据服务器端点:

  • 对于所有虚拟机,您可以使用 http 端点 (http://metadata.google.internal/computeMetadata/v1) 查询元数据服务器。
  • 对于受防护的虚拟机,您可以使用以下任一方法查询元数据服务器:

本文档中的大多数示例都使用 http 端点。不过,无论您使用的是 https 端点还是 http 端点,都可以访问所有相同的元数据条目。

元数据请求的组成部分

下表总结了元数据查询请求的主要部分。

组件 说明
根网址

所有元数据值都会定义为以下根网址下面的子路径:

  • http 端点
    • http://metadata.google.internal/computeMetadata/v1
    • http://169.254.169.254/computeMetadata/v1
    • http://metadata.goog/computeMetadata/v1
  • https 端点(预览版
    • https://metadata.google.internal/computeMetadata/v1
      这是预览阶段唯一支持的网址。
请求标头

此标头表明请求是为了检索元数据值而发出的(而非由不安全的来源意外发出),并且允许元数据服务器返回您请求的数据。如果您不提供此标头,则元数据服务器会拒绝您的请求。

Metadata-Flavor: Google

查询单个元数据条目

使用以下命令查询单个元数据条目。

Linux

  1. 连接到您的 Linux 虚拟机。
  2. 在您的 Linux 虚拟机中,使用 curl 工具进行查询。 如需查询虚拟机实例或项目元数据条目,请运行以下命令:

    curl "http://metadata.google.internal/computeMetadata/v1/PATH_TO_METADATA_ENTRY" -H "Metadata-Flavor: Google"
    

    PATH_TO_METADATA_ENTRY 替换为您要查询其值的虚拟机实例或项目元数据键的路径。如果密钥位于实例或项目目录的子目录中,请务必也添加该子目录。例如:

    • 如需查看存储在项目元数据中的 project-id 元数据键,请指定 project/project-id
    • 如需查看存储在虚拟机实例元数据中的 image 元数据键,请指定 instance/image
    • 如需查看可存储在项目或虚拟机实例元数据的 attributes 子目录中的 enable-oslogin,请根据用例指定 project/attributes/enable-oslogininstance/attributes/enable-oslogin

    例如,如需查询虚拟机的启动映像,请运行以下查询:

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

    输出类似于以下内容:

    projects/rhel-cloud/global/images/rhel-8-v20210122

Windows

  1. 连接到您的 Windows 虚拟机。
  2. 从 Windows 虚拟机中,使用 Invoke-RestMethod 命令进行查询。 如需查询虚拟机实例或项目元数据条目,请运行以下命令:

    $value = (Invoke-RestMethod `
              -Headers @{'Metadata-Flavor' = 'Google'} `
              -Uri "http://metadata.google.internal/computeMetadata/v1/PATH_TO_METADATA_ENTRY")
    $value
    

    PATH_TO_METADATA_ENTRY 替换为您要查询其值的虚拟机实例或项目元数据键的路径。如果密钥位于实例或项目目录的子目录中,请务必也添加该子目录。例如:

    • 如需查看存储在项目元数据中的 project-id 元数据键,请指定 project/project-id
    • 如需查看存储在虚拟机实例元数据中的 image 元数据键,请指定 instance/image
    • 如需查看可存储在项目或虚拟机实例元数据的 attributes 子目录中的 enable-oslogin,请根据用例指定 project/attributes/enable-oslogininstance/attributes/enable-oslogin

    例如,如需查询虚拟机的启动映像,请运行以下查询:

    PS C:\> 
    $value = (Invoke-RestMethod `
              -Headers @{'Metadata-Flavor' = 'Google'} `
              -Uri "http://metadata.google.internal/computeMetadata/v1/instance/image")
    $value
    

    输出类似于以下内容:

    projects/windows-cloud/global/images/windows-server-2019-dc-v20210112

查询元数据目录列表

使用以下命令查询元数据目录列表。目录列表是包含其他元数据键的元数据条目。以斜杠结尾的元数据条目表示目录列表

Linux

  1. 连接到您的 Linux 虚拟机。

  2. 如需从 Linux 虚拟机查询虚拟机实例或项目元数据目录,请运行以下命令:

      curl "http://metadata.google.internal/computeMetadata/v1/PATH_TO_METADATA_DIRECTORY/" -H "Metadata-Flavor: Google"
      

    PATH_TO_METADATA_DIRECTORY 替换为您要递归查询其列表的虚拟机实例或项目元数据目录的路径。例如:

    • 如需查看 attributes 项目元数据目录条目,请指定路径 project/attributes/
    • 如需查看 disks 虚拟机实例元数据目录条目,请指定路径 instance/disks/

    例如,disks/ 条目是包含挂接到虚拟机的磁盘的目录。如需查询 disks/ 条目,请完成以下步骤:

    1. 在磁盘目录上运行 curl 工具命令。

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

      输出类似于以下内容:

      0/
      1/
      2/
      
    2. 如需详细了解磁盘 0/ 目录,您可以查询该目录的特定网址:

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

      输出类似于以下内容:

      device-name
      index
      mode
      type
      
    3. 然后,您可以运行以下命令来查询磁盘 0/ 的磁盘类型 (type):

      user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/disks/0/type" -H "Metadata-Flavor: Google"
      

      输出类似于以下内容:

      PERSISTENT
      

Windows

disks/ 条目是挂接到虚拟机的磁盘的目录。 如需查询磁盘条目,请完成以下步骤:

  1. 连接到您的 Windows 虚拟机。

  2. 如需从 Windows 虚拟机查询虚拟机实例或项目元数据目录,请运行以下命令:

    $value = (Invoke-RestMethod `
              -Headers @{'Metadata-Flavor' = 'Google'} `
              -Uri "http://metadata.google.internal/computeMetadata/v1/PATH_TO_METADATA_DIRECTORY/")
    $value
    

    PATH_TO_METADATA_DIRECTORY 替换为您要递归查询其列表的虚拟机实例或项目元数据目录的路径。例如:

    • 如需查看 attributes 项目元数据目录条目,请指定路径 project/attributes/
    • 如需查看 disks 虚拟机实例元数据目录条目,请指定路径 instance/disks/

    例如,disks/ 条目是包含挂接到虚拟机的磁盘的目录。如需查询 disks/ 条目,请完成以下步骤:

    1. 在磁盘目录上使用 Invoke-RestMethod 命令

      PS C:\> 
      $value = (Invoke-RestMethod `
                -Headers @{'Metadata-Flavor' = 'Google'} `
                -Uri "http://metadata.google.internal/computeMetadata/v1/instance/disks/")
      $value
      

      输出类似于以下内容:

      0/
      1/
      2/
      
    2. 如需详细了解磁盘 0/ 目录,可以查询该目录的特定网址:

      PS C:\> 
      $value = (Invoke-RestMethod `
                -Headers @{'Metadata-Flavor' = 'Google'} `
                -Uri "http://metadata.google.internal/computeMetadata/v1/instance/disks/0/")
      $value
      

      输出类似于以下内容:

      device-name
      index
      mode
      type
      
    3. 然后,您可以运行以下命令来查询磁盘 0/ 的磁盘类型 (type):

      PS C:\> 
      $value = (Invoke-RestMethod `
                -Headers @{'Metadata-Flavor' = 'Google'} `
                -Uri "http://metadata.google.internal/computeMetadata/v1/instance/disks/0/type")
      $value
      

      输出类似于以下内容:

      PERSISTENT
      

以递归方式查询目录列表

如果要返回某个目录下的所有内容,请在您的请求中使用 recursive=true 查询参数:

Linux

  1. 连接到您的 Linux 虚拟机。

  2. 在您的 Linux 虚拟机中,使用 curl 工具进行查询。如需递归查询虚拟机实例或项目元数据目录的列表,请运行以下命令:

    curl "http://metadata.google.internal/computeMetadata/v1/PATH_TO_METADATA_DIRECTORY/?recursive=true" -H "Metadata-Flavor: Google"
    

    PATH_TO_METADATA_DIRECTORY 替换为您要递归查询其列表的虚拟机实例或项目元数据目录的路径。例如:

    • 如需查看 attributes 项目元数据目录条目,请指定路径 project/attributes/
    • 如需查看 disks 虚拟机实例元数据目录条目,请指定路径 instance/disks/

    例如,以下命令会递归查询 disks/ 目录的实例元数据列表。

      user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/disks/?recursive=true" -H "Metadata-Flavor: Google"
      

    输出类似于以下内容:

      [{"deviceName":"boot","index":0,"mode":"READ_WRITE","type":"PERSISTENT"},
      {"deviceName":"persistent-disk-1","index":1,"mode":"READ_WRITE","type":"PERSISTENT"},
      {"deviceName":"persistent-disk-2","index":2,"mode":"READ_ONLY","type":"PERSISTENT"}]
      

    默认情况下,递归内容以 JSON 格式返回。如果您希望以文本格式返回这些内容,请附加 alt=text 查询参数:

      user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/disks/?recursive=true&alt=text" -H "Metadata-Flavor: Google"
      

    输出类似于以下内容:

      0/device-name boot
      0/index 0
      0/mode READ_WRITE
      0/type PERSISTENT
      1/device-name persistent-disk-1
      1/index 1
      1/mode READ_WRITE
      1/type PERSISTENT
      2/device-name persistent-disk-1
      2/index 2
      2/mode READ_ONLY
      2/type PERSISTENT
      

Windows

  1. 连接到您的 Windows 虚拟机。

  2. 从 Windows 虚拟机中,使用 Invoke-RestMethod 命令进行查询。如需递归查询虚拟机实例或项目元数据目录的列表,请运行以下命令:

      $value = (Invoke-RestMethod -Headers @{'Metadata-Flavor' = 'Google'}
                -Uri "http://metadata.google.internal/computeMetadata/v1/PATH_TO_METADATA_DIRECTORY/?recursive=true")
      $value
      

    PATH_TO_METADATA_DIRECTORY 替换为您要递归查询其列表的虚拟机实例或项目元数据目录的路径。例如:

    • 如需查看 attributes 项目元数据目录条目,请指定路径 project/attributes/
    • 如需查看 disks 虚拟机实例元数据目录条目,请指定路径 instance/disks/

    例如,以下命令会递归查询 disks/ 目录的实例元数据列表。

    PS C:\> 
    $value = (Invoke-RestMethod `
              -Headers @{'Metadata-Flavor' = 'Google'} `
              -Uri "http://metadata.google.internal/computeMetadata/v1/instance/disks/?recursive=true")
    $value
    

    输出类似于以下内容:

    [{"deviceName":"boot","index":0,"mode":"READ_WRITE","type":"PERSISTENT"},
    {"deviceName":"persistent-disk-1","index":1,"mode":"READ_WRITE","type":"PERSISTENT"},
    {"deviceName":"persistent-disk-2","index":2,"mode":"READ_ONLY","type":"PERSISTENT"}]
    

    默认情况下,递归内容以 JSON 格式返回。如果您希望以文本格式返回这些内容,请附加 alt=text 查询参数:

    PS C:\> 
    $value = (Invoke-RestMethod `
              -Headers @{'Metadata-Flavor' = 'Google'} `
              -Uri "http://metadata.google.internal/computeMetadata/v1/instance/disks/?recursive=true&alt=text")
    $value
    

    输出类似于以下内容:

    0/device-name boot
    0/index 0
    0/mode READ_WRITE
    0/type PERSISTENT
    1/device-name persistent-disk-1
    1/index 1
    1/mode READ_WRITE
    1/type PERSISTENT
    2/device-name persistent-disk-1
    2/index 2
    2/mode READ_ONLY
    2/type PERSISTENT
    

设置查询输出的格式

默认情况下,每个端点都有一种预定义的响应格式。有些端点在默认情况下可能以 JSON 格式返回数据,而其他端点可能以字符串形式返回数据。您可以使用 alt=jsonalt=text 查询参数替换默认的数据格式规范,这些参数分别会返回 JSON 字符串格式的数据或纯文本形式的数据。

Linux

  1. 连接到您的 Linux 虚拟机。
  2. 在您的 Linux 虚拟机中,使用 curl 工具进行查询。如需更改虚拟机实例或项目元数据条目的查询响应数据格式,请运行以下命令:

    curl "http://metadata.google.internal/computeMetadata/v1/PATH_TO_METADATA_ENTRY?alt=DATA_FORMAT" -H "Metadata-Flavor: Google"
    

    替换以下内容:

    • PATH_TO_METADATA_ENTRY 替换为您要查询其值的虚拟机实例或项目元数据键的路径。如果密钥位于实例或项目目录的子目录中,请务必也添加该子目录。例如:

      • 如需查看存储在项目元数据中的 project-id 元数据键,请指定 project/project-id
      • 如需查看存储在虚拟机实例元数据中的 image 元数据键,请指定 instance/image
      • 如需查看可存储在项目或虚拟机实例元数据的 attributes 子目录中的 enable-oslogin,请根据用例指定 project/attributes/enable-oslogininstance/attributes/enable-oslogin
    • DATA_FORMAT:您所需的查询响应数据的格式,例如 textjson

示例

例如,tags会自动返回 JSON 格式的数据。您可以指定 alt=text 查询参数,以改为返回文本格式的数据。

默认查询

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

输出类似于以下内容:

  ["http-server", "db-client", "app-server", "mysql-server"]
  

使用格式设置的查询

  user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/tags?alt=text" -H "Metadata-Flavor: Google"
  

输出类似于以下内容:

  http-server
  db-client
  app-server
  mysql-server

Windows

  1. 连接到您的 Windows 虚拟机。
  2. 从 Windows 虚拟机中,使用 Invoke-RestMethod 命令进行查询。如需更改虚拟机实例或项目元数据条目的查询响应数据格式,请运行以下命令:

      $value = (Invoke-RestMethod -Headers @{'Metadata-Flavor' = 'Google'}
                -Uri "http://metadata.google.internal/computeMetadata/v1/PATH_TO_METADATA_ENTRY?alt=DATA_FORMAT")
      $value
      

    替换以下内容:

    • PATH_TO_METADATA_ENTRY 替换为您要查询其值的虚拟机实例或项目元数据键的路径。如果密钥位于实例或项目目录的子目录中,请务必也添加该子目录。例如:

      • 如需查看存储在项目元数据中的 project-id 元数据键,请指定 project/project-id
      • 如需查看存储在虚拟机实例元数据中的 image 元数据键,请指定 instance/image
      • 如需查看可存储在项目或虚拟机实例元数据的 attributes 子目录中的 enable-oslogin,请根据用例指定 project/attributes/enable-oslogininstance/attributes/enable-oslogin
    • DATA_FORMAT:您所需的查询响应数据的格式,例如 textjson

示例

例如,tags会自动返回 JSON 格式的数据。您可以指定 alt=text 查询参数,以改为返回文本格式的数据。

默认查询

  PS C:> 
  $value = (Invoke-RestMethod -Headers @{'Metadata-Flavor' = 'Google'}
            -Uri "http://metadata.google.internal/computeMetadata/v1/instance/tags")
  $value
  

输出类似于以下内容:

  ["http-server", "db-client", "app-server", "mysql-server"]
  

使用格式设置的查询

  PS C:> 
  $value = (Invoke-RestMethod -Headers @{'Metadata-Flavor' = 'Google'}
            -Uri "http://metadata.google.internal/computeMetadata/v1/instance/tags?alt=text")
  $value
  

输出类似于以下内容:

  http-server
  db-client
  app-server
  mysql-server

使用 wait-for-change 功能查询元数据更改

鉴于元数据值可能会在虚拟机运行时发生更改,元数据服务器会使用 wait-for-change 功能来接收元数据更改通知。借助此选项,仅当指定的元数据发生更改时,请求才会返回输出。

您可以对自定义元数据或服务器定义的元数据使用此功能;因此如果您的虚拟机或项目发生任何变化,或者有人更新了某个自定义元数据条目,您可以编程方式来响应这项更改。

例如,您可以对 tags 键执行请求,使系统仅在 tags 元数据的内容发生更改时才返回响应。请求返回后,会提供该元数据键的新值。

您还可以使用 wait-for-change 功能来匹配请求和设置超时值

使用 wait-for-change 功能时,请考虑以下事项:

  • 您只能对元数据端点执行 wait-for-change 请求,或以递归方式对目录内容执行该请求。您不能对目录列表执行 wait-for-change 请求。如果您尝试执行此操作,元数据服务器会拒绝您的请求,并返回 400 请求无效错误。

  • 此外,您也不能对服务账号令牌执行 wait-for-change 请求。如果您尝试向服务账号令牌网址发出 wait-for-change 请求,请求会立即失败并返回 400 请求无效错误。

如需执行 wait-for-change 请求,请查询元数据键并附加 ?wait_for_change=true 查询参数:

Linux

  1. 连接到您的 Linux 虚拟机。
  2. 在您的 Linux 虚拟机中,使用 curl 工具进行查询。如需对虚拟机实例或项目元数据条目执行 wait-for-change 请求,请运行以下命令:

    curl "http://metadata.google.internal/computeMetadata/v1/PATH_TO_METADATA_ENTRY?wait_for_change=true" -H "Metadata-Flavor: Google"
    

    PATH_TO_METADATA_ENTRY 替换为您要查询其值的虚拟机实例或项目元数据键的路径。如果密钥位于实例或项目目录的子目录中,请务必也添加该子目录。例如:

    • 如需查看存储在项目元数据中的 project-id 元数据键,请指定 project/project-id
    • 如需查看存储在虚拟机实例元数据中的 image 元数据键,请指定 instance/image
    • 如需查看可存储在项目或虚拟机实例元数据的 attributes 子目录中的 enable-oslogin,请根据用例指定 project/attributes/enable-oslogininstance/attributes/enable-oslogin

    指定的元数据键发生更改后,查询会返回新值。

示例

在此示例中,如果向 setInstanceTags method 方法发出请求,则请求会返回新值:

  user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/tags?wait_for_change=true" -H "Metadata-Flavor: Google"
  

输出类似于以下内容:

  http-server
  db-client
  

您还能以递归方式对目录内容执行 wait-for-change 请求:

  user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/attributes/?recursive=true&wait_for_change=true" -H "Metadata-Flavor: Google"
  

如果发生任何更改,元数据服务器就会返回新内容:

  {"foo":"bar","baz":"bat"}
  

Windows

  1. 连接到您的 Windows 虚拟机。
  2. 从 Windows 虚拟机中,使用 Invoke-RestMethod 命令进行查询。如需对虚拟机实例或项目元数据条目执行 wait-for-change 请求,请运行以下命令:

    $value = (Invoke-RestMethod `
              -Headers @{'Metadata-Flavor' = 'Google'} `
              -Uri "http://metadata.google.internal/computeMetadata/v1/PATH_TO_METADATA_ENTRY?wait_for_change=true")
    $value
    

    PATH_TO_METADATA_ENTRY 替换为您要查询其值的虚拟机实例或项目元数据键的路径。如果密钥位于实例或项目目录的子目录中,请务必也添加该子目录。例如:

    • 如需查看存储在项目元数据中的 project-id 元数据键,请指定 project/project-id
    • 如需查看存储在虚拟机实例元数据中的 image 元数据键,请指定 instance/image
    • 如需查看可存储在项目或虚拟机实例元数据的 attributes 子目录中的 enable-oslogin,请根据用例指定 project/attributes/enable-oslogininstance/attributes/enable-oslogin

    指定的元数据键发生更改后,查询会返回新值。

示例

指定的元数据键发生更改后,查询会返回新值。 在此示例中,如果向 setInstanceTags method 方法发出请求,则请求会返回新值:

  PS C:> 
  $value = (Invoke-RestMethod -Headers @{'Metadata-Flavor' = 'Google'}
            -Uri "http://metadata.google.internal/computeMetadata/v1/instance/tags?wait_for_change=true")
  $value
  

输出类似于以下内容:

  http-server
  db-client
  

您还能以递归方式对目录内容执行 wait-for-change 请求:

  PS C:> 
  $value = (Invoke-RestMethod -Headers @{'Metadata-Flavor' = 'Google'}
            -Uri "http://metadata.google.internal/computeMetadata/v1/instance/attributes?recursive=true&wait_for_change=true")
  $value
  

如果发生任何更改,元数据服务器就会返回新内容:

  {"foo":"bar","baz":"bat"}
  

使用 ETag

当您提交 wait-for-change 查询后,如果元数据内容发生了任何更改,元数据服务器就会返回响应。但是,由于元数据更新作业与发出的 wait-for-change 请求之间存在固有的竞态条件,因此通过一种可靠的方式来获悉您正在获取最新的元数据值将会很有帮助。

为实现此目的,您可以使用 last_etag 查询参数来将您提供的 ETag 值与保存在元数据服务器中的 ETag 值进行比较。如果这些 ETag 值一致,则系统将接受 wait-for-change 请求。如果这些 ETag 值不一致,则表明自您上次检索 ETag 值以后,元数据的内容已更改,并且元数据服务器会立即返回此最新值。

Linux 虚拟机

如需获取元数据键的当前 ETag 值,请完成以下步骤:

  1. 连接到您的 Linux 虚拟机。
  2. 向该键发出请求并输出标头。为此,请将 curl 工具-v 标志结合使用。如需获取虚拟机实例或项目元数据条目的当前 ETag,请运行以下命令:

    curl -v "http://metadata.google.internal/computeMetadata/v1/PATH_TO_METADATA_ENTRY" -H "Metadata-Flavor: Google"
    

    PATH_TO_METADATA_ENTRY 替换为您要查询其值的虚拟机实例或项目元数据键的路径。如果密钥位于实例或项目目录的子目录中,请务必也添加该子目录。例如:

    • 如需查看存储在项目元数据中的 project-id 元数据键,请指定 project/project-id
    • 如需查看存储在虚拟机实例元数据中的 image 元数据键,请指定 instance/image
    • 如需查看可存储在项目或虚拟机实例元数据的 attributes 子目录中的 enable-oslogin,请根据用例指定 project/attributes/enable-oslogininstance/attributes/enable-oslogin

    例如,以下命令会获取 tags 实例元数据键的当前 ETag 值。

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

    输出类似于以下内容:

    * About to connect() to metadata port 80 (#0)
    * Trying 169.254.169.254... connected
    * Connected to metadata (169.254.169.254) port 80 (#0)
    > GET /computeMetadata/v1/instance/tags HTTP/1.1
    > User-Agent: curl/7.19.7 (x86_64-pc-linux-gnu) libcurl/7.19.7 OpenSSL/0.9.8k zlib/1.2.3.3 libidn/1.15
    > Host: metadata
    > Accept: */*
    >
    < HTTP/1.1 200 OK
    < Content-Type: application/text
    < ETag: 411261ca6c9e654e
    < Date: Wed, 13 Feb 2013 22:43:45 GMT
    < Server: Metadata Server for VM
    < Content-Length: 26
    < X-XSS-Protection: 1; mode=block
    < X-Frame-Options: SAMEORIGIN
    <
    http-server
    db-client
  3. 然后,您可以将该 ETag 值与 wait-for-change 请求中的 curl 工具命令结合使用。如需对实例或项目元数据的 wait-for-change 请求使用 ETag 值,请运行以下命令:

      curl "http://metadata.google.internal/computeMetadata/v1/PATH_TO_METADATA_ENTRY?wait_for_change=true&last_etag=ETAG" -H "Metadata-Flavor: Google"
      

    替换以下内容:

    • PATH_TO_METADATA_ENTRY 替换为您要查询其值的虚拟机实例或项目元数据键的路径。如果密钥位于实例或项目目录的子目录中,请务必也添加该子目录。例如:

      • 如需查看存储在项目元数据中的 project-id 元数据键,请指定 project/project-id
      • 如需查看存储在虚拟机实例元数据中的 image 元数据键,请指定 instance/image
      • 如需查看可存储在项目或虚拟机实例元数据的 attributes 子目录中的 enable-oslogin,请根据用例指定 project/attributes/enable-oslogininstance/attributes/enable-oslogin
    • ETAG:元数据键的 ETag 值。

    在此示例中,以下命令使用 tags 键的 ETag 值并查询实例元数据条目。

      user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/tags?wait_for_change=true&last_etag=411261ca6c9e654e" -H "Metadata-Flavor: Google"
      

    元数据服务器会对您指定的 ETag 值进行匹配,如果该值发生更改,则请求将返回元数据键的新内容。

Windows 虚拟机

如需获取元数据键的当前 ETag 值,请完成以下步骤:

  1. 连接到您的 Windows 虚拟机。
  2. 向该键发出请求并输出标头。在 Windows 上,使用 Invoke-WebRequest 命令 。 如需获取虚拟机实例或项目元数据条目的当前 ETag,请运行以下命令:

      $value = (Invoke-WebRequest -Headers @{'Metadata-Flavor' = 'Google'} `
      -Uri http://metadata.google.internal/computeMetadata/v1/PATH_TO_METADATA_ENTRY)

    $value.Headers.ETag

    PATH_TO_METADATA_ENTRY 替换为您要查询其值的虚拟机实例或项目元数据键的路径。如果密钥位于实例或项目目录的子目录中,请务必也添加该子目录。例如:

    • 如需查看存储在项目元数据中的 project-id 元数据键,请指定 project/project-id
    • 如需查看存储在虚拟机实例元数据中的 image 元数据键,请指定 instance/image
    • 如需查看可存储在项目或虚拟机实例元数据的 attributes 子目录中的 enable-oslogin,请根据用例指定 project/attributes/enable-oslogininstance/attributes/enable-oslogin

    例如,以下命令会获取 tags 实例元数据键的当前 ETag 值。

      PS C:> 
      $value = (Invoke-WebRequest -Headers @{'Metadata-Flavor' = 'Google'} `
      -Uri http://metadata.google.internal/computeMetadata/v1/instance/tags)

    $value.Headers.ETag

    输出类似于以下内容:

      * About to connect() to metadata port 80 (#0)
      * Trying 169.254.169.254... connected
      * Connected to metadata (169.254.169.254) port 80 (#0)
      > GET /computeMetadata/v1/instance/tags HTTP/1.1
      > User-Agent: curl/7.19.7 (x86_64-pc-linux-gnu) libcurl/7.19.7 OpenSSL/0.9.8k zlib/1.2.3.3 libidn/1.15
      > Host: metadata
      > Accept: /
      >
      < HTTP/1.1 200 OK
      < Content-Type: application/text
      < ETag: 411261ca6c9e654e
      < Date: Wed, 13 Feb 2013 22:43:45 GMT
      < Server: Metadata Server for VM
      < Content-Length: 26
      < X-XSS-Protection: 1; mode=block
      < X-Frame-Options: SAMEORIGIN
      <
      http-server
      db-client

  3. 然后,您可以在 wait-for-change 请求中使用这个 ETag 值。如需对实例或项目元数据的 wait-for-change 请求使用 ETag 值,请运行以下命令:

      $value = (Invoke-RestMethod -Headers @{'Metadata-Flavor' = 'Google'}
              -Uri "http://metadata.google.internal/computeMetadata/v1/PATH_TO_METADATA_ENTRY?wait_for_change=true&last_etag=ETAG")
      $value
      

    替换以下内容:

    • PATH_TO_METADATA_ENTRY 替换为您要查询其值的虚拟机实例或项目元数据键的路径。如果密钥位于实例或项目目录的子目录中,请务必也添加该子目录。例如:

      • 如需查看存储在项目元数据中的 project-id 元数据键,请指定 project/project-id
      • 如需查看存储在虚拟机实例元数据中的 image 元数据键,请指定 instance/image
      • 如需查看可存储在项目或虚拟机实例元数据的 attributes 子目录中的 enable-oslogin,请根据用例指定 project/attributes/enable-oslogininstance/attributes/enable-oslogin
    • ETAG:元数据键的 ETag 值。

    在此示例中,以下命令使用 tags 键的 ETag 值并查询实例元数据条目。

      PS C:> 
      $value = (Invoke-RestMethod -Headers @{'Metadata-Flavor' = 'Google'}
                -Uri "http://metadata.google.internal/computeMetadata/v1/instance/tags?wait_for_change=true&last_etag=411261ca6c9e654e")
      $value
      

    元数据服务器会对您指定的 ETag 值进行匹配,如果该值发生更改,则请求将返回元数据键的新内容。

Python

以下 Python 示例演示了如何以编程方式监控元数据服务器的更改。

此示例将初始 ETag 设置为 0。在元数据服务器返回的响应中,不会将 0 作为 ETag 值。如果您在请求中将 0 指定为最后一个 ETag,则元数据服务器将以当前值和 ETag 进行响应。这样可省去获取初始值和 ETag 所需的一些代码。

last_etag = "0"

while True:
    r = requests.get(
        url,
        params={"last_etag": last_etag, "wait_for_change": True},
        headers=METADATA_HEADERS,
    )

    # During maintenance the service can return a 503, so these should
    # be retried.
    if r.status_code == 503:
        time.sleep(1)
        continue
    r.raise_for_status()

    last_etag = r.headers["etag"]

设置超时

如果您希望 wait-for-change 请求在特定秒数后超时,则可以设置 timeout_sec 参数。timeout_sec 参数会将请求的等待时间限制为您所指定的秒数,因此达到这一限制时,请求就会返回元数据键的当前内容。

当您设置 timeout_sec 参数时,无论元数据值是否已发生实际更改,请求始终会在指定的秒数后返回响应。超时值必须设置为整数值。

Linux

  1. 连接到您的 Linux 虚拟机。
  2. 在您的 Linux 虚拟机中,使用 curl 工具进行查询。如需对虚拟机实例或项目元数据条目执行具有超时值的 wait-for-change 请求,请运行以下命令:

      curl "http://metadata.google.internal/computeMetadata/v1/PATH_TO_METADATA_ENTRY?wait_for_change=true&timeout_sec=TIMEOUT" -H "Metadata-Flavor: Google"
      

    替换以下内容:

    • PATH_TO_METADATA_ENTRY 替换为您要查询其值的虚拟机实例或项目元数据键的路径。如果密钥位于实例或项目目录的子目录中,请务必也添加该子目录。例如:

      • 如需查看存储在项目元数据中的 project-id 元数据键,请指定 project/project-id
      • 如需查看存储在虚拟机实例元数据中的 image 元数据键,请指定 instance/image
      • 如需查看可存储在项目或虚拟机实例元数据的 attributes 子目录中的 enable-oslogin,请根据用例指定 project/attributes/enable-oslogininstance/attributes/enable-oslogin
    • TIMEOUT:超时值。

例如,以下命令会执行 wait-for-change 请求,该请求被设置为在 360 秒后超时:

  user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/tags?wait_for_change=true&timeout_sec=360" -H "Metadata-Flavor: Google"
  

Windows

  1. 连接到您的 Windows 虚拟机。
  2. 从 Windows 虚拟机中,使用 Invoke-RestMethod 命令进行查询。 如需对虚拟机实例或项目元数据条目执行具有超时值的 wait-for-change 请求,请运行以下命令:

      $value = (Invoke-RestMethod -Headers @{'Metadata-Flavor' = 'Google'}
              -Uri "http://metadata.google.internal/computeMetadata/v1/PATH_TO_METADATA_ENTRY?wait_for_change=true&timeout_sec=TIMEOUT")
      $value
      

    替换以下内容:

    • PATH_TO_METADATA_ENTRY 替换为您要查询其值的虚拟机实例或项目元数据键的路径。如果密钥位于实例或项目目录的子目录中,请务必也添加该子目录。例如:

      • 如需查看存储在项目元数据中的 project-id 元数据键,请指定 project/project-id
      • 如需查看存储在虚拟机实例元数据中的 image 元数据键,请指定 instance/image
      • 如需查看可存储在项目或虚拟机实例元数据的 attributes 子目录中的 enable-oslogin,请根据用例指定 project/attributes/enable-oslogininstance/attributes/enable-oslogin
    • TIMEOUT:超时值。

例如,以下命令会执行 wait-for-change 请求,该请求被设置为在 360 秒后超时:

  PS C:> 
  $value = (Invoke-RestMethod -Headers @{'Metadata-Flavor' = 'Google'}
            -Uri "http://metadata.google.internal/computeMetadata/v1/instance/tags?wait_for_change=true&timeout_sec=360")
  $value
  

状态代码

当您执行 wait-for-change 请求时,元数据服务器会返回标准 HTTP 状态代码以指示成功与否。如果发生错误,则网络状况可能会导致元数据服务器使您的请求失败,并返回错误代码。在此类情况下,您应该将应用设计成容错型,并且可以识别和处理这些错误。

元数据服务器返回的可能状态如下:

状态 说明
HTTP 200 大功告成!值已更改,或者您已达到指定的 timeout_sec,且请求已成功返回响应。
Error 400 您的请求无效。请修复查询并重试请求。
Error 404 您指定的元数据值不再存在。如果您的元数据在您等待更改时遭到删除,则元数据服务器也会返回此错误。
Error 503 发生临时服务器错误或临时维护事件。请重试请求。

使用 HTTPS 元数据服务器端点查询元数据

HTTPS 元数据服务器端点 (https://metadata.google.internal/computeMetadata/v1) 可为元数据服务器与虚拟机之间传输的信息提供额外的安全保障。

如需使用 HTTPS 元数据服务器端点,请查看以下要求:

  • 您必须申请访问 HTTPS 元数据服务器端点预览版。

  • 将项目添加到许可名单后,您就可以创建虚拟机了。该虚拟机必须满足以下要求:

    • 客机环境必须在虚拟机上运行
    • 虚拟机必须是安全强化型虚拟机。这是因为 HTTPS 元数据服务器需要使用统一的可扩展固件接口 (UEFI) 和虚拟可信平台模块 (vTPM) 来验证证书。

如需概览如何处理对 HTTPS 元数据服务器端点的查询,请参阅 HTTPS 元数据服务器端点。无论您使用的是 https 端点还是 http 端点,都可以对元数据服务器执行所有相同的查询。不过,如需调用 https 端点,您必须指定客户端身份证书的路径,在某些情况下还必须指定根证书的路径。

以下命令演示了如何使用 https 端点查询元数据服务器。

Linux

  1. 连接到您的 Linux 虚拟机。

  2. 在您的 Linux 虚拟机中,使用 curl 工具进行查询并指定客户端身份证书。(可选)您还可以指定根证书。

    curl "https://metadata.google.internal/computeMetadata/v1/PATH_TO_METADATA_ENTRY" \
      -E CLIENT_CERTIFICATE \
      [--cacert ROOT_CERTIFICATE] \
      -H "Metadata-Flavor: Google"
    

    替换以下内容:

    • PATH_TO_METADATA_ENTRY 替换为您要查询其值的虚拟机实例或项目元数据键的路径。如果密钥位于实例或项目目录的子目录中,请务必也添加该子目录。例如:

      • 如需查看存储在项目元数据中的 project-id 元数据键,请指定 project/project-id
      • 如需查看存储在虚拟机实例元数据中的 image 元数据键,请指定 instance/image
      • 如需查看可存储在项目或虚拟机实例元数据的 attributes 子目录中的 enable-oslogin,请根据用例指定 project/attributes/enable-oslogininstance/attributes/enable-oslogin
    • CLIENT_CERTIFICATE:客户端身份证书的路径:/run/google-mds-mtls/client.key
    • 可选:ROOT_CERTIFICATE:根证书的路径:/run/google-mds-mtls/root.crt

    例如,如需查询虚拟机的启动映像,请运行以下查询:

    user@myinst:~$ 
    curl "https://metadata.google.internal/computeMetadata/v1/instance/image" \
      -E /run/google-mds-mtls/client.key \
      -H "Metadata-Flavor: Google"
    

    输出类似于以下内容:

    projects/rhel-cloud/global/images/rhel-8-v20210122

    如果您看到错误消息,请参阅问题排查文档

Windows

  1. 连接到您的 Windows 虚拟机。

  2. 使用以下命令之一获取客户端身份证书

    • $cert = Get-PfxCertificate -FilePath "C:\ProgramData\Google\Compute Engine\mds-mtls-client.key.pfx"
      
    • $cert = Get-ChildItem Cert:\LocalMachine\My | Where-Object { $_.Issuer -like "google.internal" }
      
  3. 在 Windows 虚拟机中,使用 Invoke-RestMethod 命令并指定客户端身份证书以进行查询。

    PS C:\> 
    $value = (Invoke-RestMethod `
              -Headers @{'Metadata-Flavor' = 'Google'} -Certificate CLIENT_CERTIFICATE `
              -Uri "https://metadata.google.internal/computeMetadata/v1/PATH_TO_METADATA_ENTRY")
    $value
    

    替换以下内容:

    • CLIENT_CERTIFICATE:虚拟机上客户端身份证书的路径。这是在上一步中设置的 $cert 变量。
    • PATH_TO_METADATA_ENTRY 替换为您要查询其值的虚拟机实例或项目元数据键的路径。如果密钥位于实例或项目目录的子目录中,请务必也添加该子目录。例如:

      • 如需查看存储在项目元数据中的 project-id 元数据键,请指定 project/project-id
      • 如需查看存储在虚拟机实例元数据中的 image 元数据键,请指定 instance/image
      • 如需查看可存储在项目或虚拟机实例元数据的 attributes 子目录中的 enable-oslogin,请根据用例指定 project/attributes/enable-oslogininstance/attributes/enable-oslogin

    例如,如需查询 Windows Server 2019 虚拟机的启动映像,请运行以下查询:

    PS C:\> 
    $value = (Invoke-RestMethod `
              -Headers @{'Metadata-Flavor' = 'Google'} -Certificate $cert `
              -Uri "https://metadata.google.internal/computeMetadata/v1/instance/image")
    $value
    

    输出类似于以下内容:

    projects/windows-cloud/global/images/windows-server-2019-dc-v20210112

限制

  • 元数据服务器会自动拒绝任何包含 X-Forwarded-For 标头的请求。此标头通常表示该请求是代理的,可能不是由已获授权的用户发出的请求。出于安全考虑,所有此类请求都会遭到拒绝。

  • 请注意,使用 curl 命令在服务器中检索元数据时,请求路径不支持某些编码字符。编码字符仅在查询路径中受支持。

    例如,以下请求可能无法正常运行:

    curl "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/123456789-compute%40developer.gserviceaccount.com/?query_path=https%3A%2F%2Flocalhost%3A8200%2Fexample%2Fquery&another_param=true" -H "Metadata-Flavor: Google"

    为使此请求能够正常运行,您必须将请求路径中不受支持的编码字符 (%40) 替换为等效的受支持值 (@)。

    curl "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/1234567898-compute@developer.gserviceaccount.com/?query_path=https%3A%2F%2Flocalhost%3A8200%2Fexample%2Fquery&another_param=true" -H "Metadata-Flavor: Google"

    下表汇总了请求路径不支持的编码字符。

    编码字符 接受的值
    %21
    !
    %24
    $
    %27
    '
    %28
    (
    %29
    )
    %2A
    *
    %2C
    ,
    %40
    @

查看虚拟机的自定义元数据

您可以通过以下任一方式查看 Compute Engine 虚拟机的自定义元数据值:

查看项目元数据

如需查看应用于项目中所有虚拟机的自定义元数据,请使用以下方法之一。

控制台

  1. 在 Google Cloud 控制台中,转到元数据页面。

    转到元数据页面

    元数据页面上,您会看到项目的所有自定义项目元数据条目的列表。

gcloud

使用 gcloud compute project-info describe 命令来查询项目元数据:

gcloud compute project-info describe --flatten="commonInstanceMetadata[]"

输出类似于以下内容:

---
fingerprint: HcSFdS_1_1I=
items:
- key: ssh-keys
  value: USERNAME:ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDWZ...
kind: compute#metadata

REST

如需查询项目元数据,请创建对 project.get 方法GET 请求。

PROJECT_ID 替换为您的项目 ID。

GET https://compute.googleapis.com/compute/v1/projects/PROJECT_ID

输出类似于以下内容:

"kind": "compute#project",
"id": "XXXXXXX",
"creationTimestamp": "2018-12-10T08:34:33.616-08:00",
"name": "YOUR_PROJECT",
"commonInstanceMetadata": {
  "kind": "compute#metadata",
  "fingerprint": "XXXXXCdg=",
  "items": [
    {
      "key": "enable-guest-attributes",
      "value": "TRUE"
    },
    {
      "key": "enable-os-inventory",
      "value": "true"
    },
    {
      "key": "enable-osconfig",
      "value": "TRUE"
    },
    {
      "key": "enable-oslogin",
      "value": "TRUE"
    },
    {
      "key": "sshKeys",
      "value": "XXXXX"
    }
  ]
}, ...

查看可用区级元数据

如需查看应用于项目特定可用区中所有虚拟机实例的自定义元数据,请使用以下方法之一。

gcloud

如需查询自定义可用区元数据,请使用 gcloud compute project-zonal-metadata describe 命令

gcloud compute project-zonal-metadata describe \
    --zone=ZONE \
    --project=PROJECT_ID

替换以下内容:

  • PROJECT_ID:您的项目 ID
  • ZONE:要查看其可用区元数据的可用区。

输出类似于以下内容:

{
  "fingerprint": "VlRIl8dx9vk=",
  "metadata": {
    items: {
      "key-1": "value-1",
      "key-2": "value-2"
    }
  }
}

REST

如需查询自定义可用区元数据,请向 instanceSettings().get 方法发出 GET 请求

GET https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instanceSettings

替换以下内容:

  • PROJECT_ID:您的项目 ID
  • ZONE:要查看其可用区元数据的可用区。

输出类似于以下内容:

{
  "fingerprint": "VlRIl8dx9vk=",
  "metadata": {
    items: {
      "key-1": "value-1",
      "key-2": "value-2"
    }
  }
}

查看实例元数据

如需查看应用于项目中单个虚拟机的元数据,请使用以下方法之一。

控制台

  1. 在 Google Cloud 控制台中,前往虚拟机实例页面。

    转到“虚拟机实例”

  2. 点击要查看其元数据的虚拟机的名称。

    • 此虚拟机的 SSH 密钥。在安全性和访问权限部分中,查看 SSH 密钥字段。

      • None 表示实例元数据中未存储 SSH 密钥。

      • 任何其他值都表示实例元数据中存储了 SSH 密钥。

    • 项目的 SSH 密钥。在安全性和访问权限部分中,查看屏蔽项目范围 SSH 密钥字段。

      • On 表示元数据键 block-project-ssh-keys 的值在实例元数据中为 TRUE

      • Off 表示元数据键 block-project-ssh-keys 的值为 FALSE,或该键未设置。

    • 所有其他自定义元数据。查看自定义元数据部分。您将看到所有自定义元数据键和值(SSH 密钥元数据除外)。

gcloud

使用 gcloud compute instances describe 命令来查询实例元数据:

gcloud compute instances describe VM_NAME --flatten="metadata[]"

VM_NAME 替换为您要为其查找元数据的虚拟机的名称。

输出类似于以下内容:

---
fingerprint: MTgTJ5m-Cjs=
items:
- key: enable-oslogin
  value: 'true'
kind: compute#metadata

REST

如需查询特定虚拟机的元数据,请向 instances.get 方法发送 GET 请求。

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

输出类似于以下内容:

......
"metadata": {
"kind": "compute#metadata",
"fingerprint": "XXXXXXVo=",
"items": [
  {
    "key": "enable-oslogin",
    "value": "true"
  }
]
},....

替换以下内容:

  • PROJECT_ID:您的项目 ID
  • ZONE:该虚拟机所在的可用区
  • VM_NAME:虚拟机的名称

后续步骤