查看和查询虚拟机元数据


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

准备工作

  • 对于 Windows Server 虚拟机,请使用 PowerShell 3.0 或更高版本。我们建议您使用 ctrl+v 来粘贴复制的代码块。
  • 查看有关如何定义 Compute Engine 的虚拟机元数据、对其进行分类和安排的基础知识。如需了解详情,请参阅虚拟机元数据简介
  • 设置身份验证(如果尚未设置)。身份验证是通过其进行身份验证以访问 Google Cloud 服务和 API 的过程。如需从本地开发环境运行代码或示例,您可以按如下方式向 Compute Engine 进行身份验证。

    选择标签页以了解您打算如何使用本页面上的示例:

    控制台

    当您使用 Google Cloud 控制台访问 Google Cloud 服务和 API 时,无需设置身份验证。

    gcloud

    1. 安装 Google Cloud CLI,然后通过运行以下命令初始化 Google Cloud CLI:

      gcloud init
    2. 设置默认区域和可用区

    Python

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

    1. 安装 Google Cloud CLI。
    2. 如需初始化 gcloud CLI,请运行以下命令:

      gcloud init
    3. 为您的 Google 账号创建本地身份验证凭据:

      gcloud auth application-default login

    如需了解详情,请参阅 为本地开发环境设置身份验证

    REST

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

      安装 Google Cloud CLI,然后通过运行以下命令初始化 Google Cloud CLI:

      gcloud init

所需的角色

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

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

如需详细了解如何授予角色,请参阅管理访问权限

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

所需权限

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

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

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

以编程方式查询元数据

在虚拟机中,您可以使用 Linux 上的 curl 工具或 Windows 上的 Invoke-RestMethod 等工具,以编程方式查询默认或自定义元数据值。

元数据请求的组成部分

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

组件 说明
根网址

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

  • 
    http://metadata.google.internal/computeMetadata/v1
  • 
    http://169.254.169.254/v1
  • 
    http://metadata.goog/v1
请求标头

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


Metadata-Flavor: Google

查询单个元数据条目

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

Linux

  1. 连接到您的 Linux 虚拟机。
  2. 在您的 Linux 虚拟机中,使用 curl 工具进行查询。

    • 如需查询虚拟机实例元数据条目,请运行以下命令:

      curl "http://metadata.google.internal/computeMetadata/v1/instance/METADATA_KEY" -H "Metadata-Flavor: Google"
      
    • 如需查询项目元数据条目,请运行以下命令:

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

    METADATA_KEY 替换为您要查询其值的实例或项目元数据键。

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

    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/instance/METADATA_KEY")
      $value
      
    • 如需查询项目元数据条目,请运行以下命令:

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

    METADATA_KEY 替换为您要查询其值的实例或项目元数据键。

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

    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/instance/METADATA_DIRECTORY_NAME/" -H "Metadata-Flavor: Google"
      
    • 如需查询项目元数据目录,请运行以下命令:

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

    METADATA_DIRECTORY_NAME 替换为您要查询其列表的实例或项目元数据目录的名称。

    例如,请考虑 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/instance/METADATA_DIRECTORY_NAME/")
      $value
      
    • 如需查询项目元数据目录,请运行以下命令:

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

    METADATA_DIRECTORY_NAME 替换为您要查询其列表的实例或项目元数据目录的名称。

    例如,请考虑 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/instance/METADATA_DIRECTORY_NAME/?recursive=true" -H "Metadata-Flavor: Google"
      
    • 如需以递归方式查询项目元数据目录的列表,请运行以下命令:

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

    METADATA_DIRECTORY_NAME 替换为您要以递归方式查询列表的实例或项目元数据目录的名称。

    例如,以下命令会以递归方式查询实例元数据列表中的 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/instance/METADATA_DIRECTORY_NAME/?recursive=true")
      $value
      
    • 如需以递归方式查询项目元数据目录的列表,请运行以下命令:

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

    METADATA_DIRECTORY_NAME 替换为您要以递归方式查询列表的实例或项目元数据目录的名称。

    例如,以下命令会以递归方式查询实例元数据列表中的 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/instance/METADATA_KEY?alt=DATA_FORMAT" -H "Metadata-Flavor: Google"
      
    • 如需更改项目元数据条目的查询响应数据格式,请运行以下命令:

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

    替换以下内容:

    • METADATA_KEY:您要查询其值的实例或项目元数据键。
    • 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/instance/METADATA_KEY?alt=DATA_FORMAT")
      $value
      
    • 如需更改项目元数据条目的查询响应数据格式,请运行以下命令:

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

    替换以下内容:

    • METADATA_KEY:您要查询其值的实例或项目元数据键。
    • 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/instance/METADATA_KEY?wait_for_change=true" -H "Metadata-Flavor: Google"
      
    • 如需对项目元数据条目执行 wait-for-change 请求,请运行以下命令:

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

    METADATA_KEY 替换为您要查询其值的实例或项目元数据键。

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

示例

在此示例中,如果向 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 命令进行查询。

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

    • 如需对虚拟机实例元数据条目执行 wait-for-change 请求,请运行以下命令:

      $value = (Invoke-RestMethod `
              -Headers @{'Metadata-Flavor' = 'Google'} `
              -Uri "http://metadata.google.internal/computeMetadata/v1/instance/METADATA_KEY?wait_for_change=true")
      $value
      
    • 如需对项目元数据条目执行 wait-for-change 请求,请运行以下命令:

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

    METADATA_KEY 替换为您要为其执行 wait-for-change 请求的实例或项目元数据键。

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

示例

指定的元数据键发生更改后,查询会返回新值。 在此示例中,如果向 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/instance/METADATA_KEY" -H "Metadata-Flavor: Google"
      
    • 如需获取项目元数据条目的当前 ETag,请运行以下命令:

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

    METADATA_KEY 替换为您要查询其值的实例或项目元数据键。

    例如,以下命令会获取 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 工具命令结合使用:

    • 如需将 ETag 值用于实例元数据的 wait-for-change 请求,请运行以下命令:

      curl "http://metadata.google.internal/computeMetadata/v1/instance/METADATA_KEY?wait_for_change=true&last_etag=ETAG" -H "Metadata-Flavor: Google"
      
    • 如需将 ETag 值用于项目元数据的 wait-for-change 请求,请运行以下命令:

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

    替换以下内容:

    • METADATA_KEY:您要查询其值的实例或项目元数据键。
    • 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/instance/METADATA_KEY)
      
      $value.Headers.ETag
      
    • 如需获取项目元数据条目的当前 ETag,请运行以下命令:

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

    METADATA_KEY 替换为您要查询其值的实例或项目元数据键。

    例如,以下命令会获取 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 值:

    • 如需将 ETag 值用于实例元数据的 wait-for-change 请求,请运行以下命令:

      $value = (Invoke-RestMethod `
              -Headers @{'Metadata-Flavor' = 'Google'} `
              -Uri "http://metadata.google.internal/computeMetadata/v1/instance/METADATA_KEY?wait_for_change=true&last_etag=ETAG")
      $value
      
    • 如需将 ETag 值用于项目元数据的 wait-for-change 请求,请运行以下命令:

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

    替换以下内容:

    • METADATA_KEY:您要查询其值的实例或项目元数据键。
    • 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/instance/METADATA_KEY?wait_for_change=true&timeout_sec=TIMEOUT" -H "Metadata-Flavor: Google"
      
    • 如需对项目元数据条目执行具有超时值的 wait-for-change 请求,请运行以下命令:

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

    替换以下内容:

    • METADATA_KEY:您要查询其值的实例或项目元数据键。
    • 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/instance/METADATA_KEY?wait_for_change=true&timeout_sec=TIMEOUT")
      $value
      
    • 如需对项目元数据条目执行具有超时值的 wait-for-change 请求,请运行以下命令:

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

    替换以下内容:

    • METADATA_KEY:您要查询其值的实例或项目元数据键。
    • 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 发生临时服务器错误或临时维护事件。请重试请求。

限制

  • 元数据服务器会自动拒绝任何包含 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 控制台中,打开元数据页面。

    转到元数据

    • 元数据标签页中,您可以查看大多数自定义项目元数据,但 SSH 密钥元数据除外。
    • SSH 密钥标签页中,您可以查看所有项目级层 SSH 密钥元数据。

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 beta compute project-zonal-metadata describe 命令

gcloud beta 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/beta/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:虚拟机的名称

后续步骤