每个实例都将其元数据存储在元数据服务器上。您可以使用 Compute Engine API 在实例上以编程方式查询元数据服务器。可以查询实例的相关信息,例如实例的主机名、实例 ID、启动和关停脚本、自定义元数据和服务帐号信息。您的实例无需任何额外的授权即可自动访问元数据服务器 API。
元数据服务器在与启动和关停脚本结合使用时会特别有用,因为您可以使用元数据服务器以编程方式获取实例独有的信息,而无需额外的授权。例如,您可以编写一个启动脚本来获取实例外部 IP 地址的元数据键值对,并在您的脚本中使用该 IP 来设置数据库。由于每个实例的默认元数据键都相同,因此您可以重复使用您的脚本,而无需针对每个实例更新该脚本。这有助于您为应用创建更加可靠的代码。
元数据以 key:value
格式存储。每个实例都可以访问一组默认的元数据条目。您还可以设置自定义元数据。
要访问元数据服务器,您可以查询元数据网址。
如需了解如何检查元数据服务器端点的版本,请参阅检查服务器端点的版本。
准备工作
- 如果您要使用本指南中的命令行示例,请执行以下操作:
- 安装或更新到 gcloud 命令行工具的最新版本。
- 设置默认区域和可用区。
- 如果您要使用本指南中的 API 示例,请设置 API 访问权限。
执行此任务所需的权限
您必须拥有以下权限才能执行此任务:
- 针对实例的
compute.instances.setMetadata
权限(如果要设置实例元数据) - 针对项目的
compute.projects.setCommonInstanceMetadata
权限(如果要设置项目级元数据) - 针对项目的
compute.projects.get
权限(如果只需获取元数据) - 针对实例的
compute.instances.get
权限(如果只需获取元数据)
项目元数据和实例元数据
您可以为项目和实例分配元数据。项目元数据会传播到项目内的所有虚拟机 (VM) 实例,而实例元数据只会对该实例产生影响。
默认元数据键
Compute Engine 定义了一组默认元数据条目,用于提供有关您实例或项目的信息。默认元数据始终由服务器定义和设置,您无法手动修改其中任何元数据对。
以下是项目可用的默认元数据。某些元数据条目是包含其他元数据键的目录。此类条目的元数据名称会以斜杠结尾,因此很容易识别。例如,attributes/
是包含其他键的目录,而 numeric-project-id
是映射到值的元数据键。
相对于 http://metadata.google.internal/computeMetadata/v1/project/ |
|
---|---|
元数据条目 | 说明 |
attributes/ |
为此项目设置的自定义元数据值的目录。 |
attributes/disable-legacy-endpoints |
对此项目中的所有实例停用旧版元数据服务器端点。除非您的项目使用旧版端点,否则请务必设置 disable-legacy-endpoints=TRUE 。请将您的应用更新为使用 v1 端点。
|
attributes/enable-oslogin |
如果您设置了 enable-oslogin=TRUE ,则会对您的项目启用 OS Login SSH 密钥管理功能。 |
attributes/vmdnssetting |
配置如何针对您项目中的实例设置内部 DNS 名称的格式。如需详细了解内部 DNS 名称,请参阅配置 DNS 名称。 |
attributes/ssh-keys |
如果您的项目和实例未配置为使用 OS Login 进行 SSH 密钥管理,您可以使用此特性来配置 SSH 公钥,以用于连接此项目中的实例。如果有多个 SSH 密钥,则各个密钥之间将以换行符 (\n ) 分隔。此值为一个字符串。由 OS Login 管理的 SSH 密钥不会显示在此元数据值中。
示例: |
numeric-project-id |
此实例的数字项目 ID(项目编号)(而非 Google Cloud Console 中显示的项目名称)。此值与 project-id 元数据条目值不同。 |
project-id |
项目 ID。 |
以下是实例可用的默认元数据列表:
相对于 http://metadata.google.internal/computeMetadata/v1/instance/ |
|
---|---|
元数据条目 | 说明 |
attributes/ |
在启动或关停期间传递给此实例的自定义元数据值的目录。请参阅下面的指定自定义元数据。 |
attributes/enable-oslogin |
如果您设置了 enable-oslogin=TRUE ,则会对此实例启用 OS Login SSH 密钥管理功能。 |
attributes/vmdnssetting |
配置如何针对此实例设置内部 DNS 名称的格式。如需详细了解内部 DNS 名称,请参阅配置 DNS 名称。 |
attributes/ssh-keys |
如果您的实例未配置为使用 OS Login 进行 SSH 密钥管理,您可以使用此特性配置 SSH 公钥,以用于连接此实例。如果有多个 SSH 密钥,则各个密钥之间将以换行符 (\n ) 分隔。此值为一个字符串。由 OS Login 管理的 SSH 密钥不会显示在此元数据值中。
示例:
|
cpu-platform |
实例的 CPU 平台。 |
description |
此实例的自由文本说明;可以使用 --description 标志分配或在 API 中设置。 |
disks/ |
挂接到此实例的磁盘目录。 |
guest-attributes/ |
自定义实例元数据值,可用于发布有关不常更改状态的通知、少量数据或更改次数很少的数据。这些值可用于指示启动脚本的完成时间,或用于向其他应用提供有关其他不常见状态的通知。虚拟机实例上的任何用户或进程都可以对“guest-attributes”元数据中的命名空间和键执行读写操作。 |
hostname |
此实例的主机名。 |
id |
此实例的 ID。这是由 Compute Engine 生成的唯一数字 ID。如果您不想使用实例名称,则此 ID 可以帮助您有效识别实例。 |
machine-type |
此实例的机器类型的元数据值,其格式如下:projects/projectnum/machineTypes/machine-type |
name |
实例名称。 |
network-interfaces/ |
实例的网络接口目录。 |
network-interfaces/<index>/forwarded-ips/ |
针对位于 <index> 的网络接口,当前指向此虚拟机实例的所有外部 IP 地址的目录。具体来说,此元数据条目提供由将数据包引向此实例的转发规则处理的外部 IP 地址列表。 |
scheduling/ |
包含实例调度选项的目录。 |
scheduling/on-host-maintenance |
此实例的透明维护事件行为设置。您可以使用 --on_host_maintenance 标志或通过 API 设置此值。
|
scheduling/automatic-restart |
此实例的自动重启设置。您可以使用 ‑‑automatic_restart 标志或通过 API 设置此值。
|
scheduling/preemptible |
此实例的抢占式设置。如果此值为 TRUE ,则表示此实例为抢占式实例。该值是在您创建实例时设置的,无法更改。
|
maintenance-event |
指示透明维护事件正影响此实例的路径。如需了解详情,请参阅透明维护通知。 |
service-accounts/ |
与此实例关联的服务帐号的目录。 |
service-accounts/service-account-name/token |
OAuth2 访问令牌,可用于对应用进行身份验证。
|
service-accounts/service-account-name/identity |
实例独有的 JSON Web 令牌。您必须在针对此实例元数据值的请求中添加 audience 参数。例如:?audience=http://www.example.com 。如需了解如何请求和验证实例身份令牌,请参阅验证实例身份。 |
tags |
与实例关联的任何标记。 |
zone |
运行此实例的地区的元数据值。该值的格式如下:
projects/projectnum/zones/zone
|
获取元数据
如要查询元数据服务器的内容,您可以从虚拟机实例中向以下根网址发出请求。请使用 http://metadata.google.internal/computeMetadata/v1/
网址向元数据服务器发出请求。
所有元数据值都会定义为这些根网址下面的子路径。
您只能从关联的实例中查询默认元数据值。而不能从其他实例或者直接从本地计算机查询实例的默认元数据。您可以使用 curl
或 wget
等标准工具,从实例中查询其元数据服务器。
在查询元数据时,您必须在所有请求中提供以下标头:
Metadata-Flavor: Google
此标头表明请求是为了检索元数据值而发出的(而非由不安全的来源意外发出),并且允许元数据服务器返回您请求的数据。如果您不提供此标头,则元数据服务器会拒绝您的请求。
X-Forwarded-For 标头
元数据服务器会自动拒绝任何包含 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 | @ |
元数据信息是否安全?
当您发出从元数据服务器获取信息的请求时,您的请求和后续元数据响应永远不会传到运行虚拟机实例的物理主机以外。
查询目录列表
元数据服务器使用目录来整理某些元数据键。以斜杠结尾的元数据条目表示目录。例如,disks/
条目是包含挂接到该实例的磁盘的目录:
user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/disks/" -H "Metadata-Flavor: Google" 0/ 1/ 2/
同样,如果您需要进一步了解 0/
磁盘目录,可以查询该目录的特定网址:
user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/disks/0/" -H "Metadata-Flavor: Google" device-name index mode type
查询端点
元数据键如果不是目录,就是返回一个或多个值的端点。例如,要查询特定磁盘的模式,请查询以下端点:
user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/disks/0/mode" -H "Metadata-Flavor: Google" READ_WRITE
默认情况下,每个端点都有一种预定义的响应格式。某些端点可能会默认返回 JSON 格式的数据,而其他端点则可能会返回字符串格式的数据。您可以使用 alt=json
或 alt=text
查询参数替换默认的数据格式规范,这些参数分别会返回 JSON 字符串格式的数据或纯文本形式的数据。
例如,tags
键会自动返回 JSON 格式的数据。您可以指定 alt=text
查询参数,以改为返回文本格式的数据:
user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/tags" -H "Metadata-Flavor: Google" ["bread","butter","cheese","cream","lettuce"]
user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/tags?alt=text" -H "Metadata-Flavor: Google" bread butter cheese cream lettuce
以递归方式查询元数据
如果要返回某个目录下的所有内容,请在您的请求中使用 recursive=true
查询参数:
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
设置布尔值
对于接受布尔值(TRUE
或 FALSE
)的字段,还可以使用以下值:
状态 | 替代值 |
---|---|
TRUE | Y、Yes、1 |
FALSE | N、No、0 |
布尔值不区分大小写。例如,您可以使用 False
、false
或 FALSE
停用某项功能。
设置自定义元数据
您可以通过 Google Cloud Console、gcloud
命令行工具或 Compute Engine API 为实例或项目设置自定义元数据。如果您要将任意值传递给您的项目或实例,或设置启动和关停脚本,自定义元数据会很有用。
自定义元数据大小限制
Compute Engine 会对所有元数据条目实施总大小限制(即 512 KB)。此外,它还会对每个 key
和 value
应用最大大小限制,如下所示:
- 每个元数据
key
的大小上限为 128 字节 - 每个元数据
value
的大小上限为 256 KB
尤其需要注意的是,SSH 密钥会以自定义元数据的形式存储在 ssh-keys
密钥下。如果此密钥的元数据内容超过 256 KB 的限制,您将无法添加更多 SSH 密钥。如果您受到此限制约束,请考虑移除未使用的密钥以为新密钥释放元数据空间。
如果您直接提供启动或关停脚本内容,则启动和关停脚本内容也可能会存储为自定义元数据,并计入这些大小限制。为了避免出现这种情况,请将启动或关停脚本存储为文件,并将其托管在 Cloud Storage 等外部位置,然后在创建实例时提供启动脚本网址。这些文件会下载到虚拟机实例上,而不是存储在元数据服务器中。
设置实例元数据
您可以使用 Cloud Console、gcloud
工具或 API 设置实例的自定义元数据。实例元数据仅适用于特定实例。
在创建实例期间设置元数据
控制台
- 在 Cloud Console 中,转到虚拟机实例页面。
- 点击创建实例。
- 在创建新实例页面上,填写实例的属性。
- 在元数据部分中,根据需求为您的自定义元数据填写任意数量的键值对。
- 点击创建以创建实例。
gcloud
在 gcloud
命令行工具中,使用 --metadata
标志设置自定义元数据。
gcloud compute instances create example-instance \ --metadata foo=bar
API
在 API 中,提供自定义元数据作为请求中元数据属性的一部分:
POST https://compute.googleapis.com/compute/v1/projects/myproject/zones/us-central1-a/instances { "... } ] } ], "metadata": { "items": [ { "key": "foo", "value": "bar" } ] }, .. }
更新正在运行的实例的元数据
控制台
- 在 Google Cloud Console 中,转到虚拟机实例页面。
- 点击您想要更新其元数据的实例。
- 点击页面顶部的修改按钮。
- 在自定义元数据下,点击添加一项或修改现有的元数据条目。
- 保存更改。
gcloud
使用 gcloud
工具更新实例元数据是一项附加性操作。请仅指定您要添加或更改的元数据键。如果您提供的键已经存在,则系统将使用新值来更新该键对应的值。
在 gcloud
命令行工具中,使用 instances add-metadata
命令:
gcloud compute instances add-metadata instance-name \ --metadata bread=mayo,cheese=cheddar,lettuce=romaine
如果您要将 lettuce=romaine
条目更改为 lettuce=green
,请使用以下命令:
gcloud compute instances add-metadata instance-name \ --metadata lettuce=green
如果您要移除 lettuce=romaine
条目,请指定现有键并排除对应的值。
gcloud compute instances remove-metadata instance-name \ --keys lettuce
API
在 API 中,向 instances().setMetadata
方法发出请求。请提供新元数据值和当前 fingerprint
值的列表。
指纹是由 Compute Engine 生成的随机字符串,可用于执行乐观锁定。请提供匹配的指纹值以执行您的请求。每次请求后指纹都会更改,因此如果您提供的指纹不匹配,请求将被拒绝。如此,一次就只能进行一项更新,以免发生冲突。
若要获取实例的当前指纹并查看实例的任何现有键值对,请发送 instances().get
请求:
GET https://compute.googleapis.com/compute/v1/projects/myproject/zones/us-central1-a/instances/example-instance { ... "name": "example-instance", "metadata": { "kind": "compute#metadata", "fingerprint": "zhma6O1w2l8=" "items": [ { "key": "foo", "value": "bar" } ] }, ... }
接下来,向 instances().setMetadata
方法发出请求,并设置您的自定义元数据键值对。如果您想要保留实例的现有键值对,则必须将这些现有键值对和新键值对都加入此请求中:
POST https://compute.googleapis.com/compute/v1/projects/myproject/zones/us-central1-a/instances/example-instance/setMetadata { "fingerprint": "zhma6O1w2l8=", "items": [ { "key": "foo", "value": "bar" }, { "key": "baz", "value": "bat" } ] }
如需从实例中移除所有元数据键值对,请指定 instances().setMetadata
请求并排除 items
属性。请注意,您仍必须添加当前的元数据指纹属性,这样 instances().setMetadata
请求才能成功:
POST https://compute.googleapis.com/compute/v1/projects/myproject/zones/us-central1-a/instances/example-instance/setMetadata { "fingerprint": "5rC_DXxBUZw=" }
设置项目级自定义元数据
您可以设置项目级元数据,以将元数据应用于项目中的所有实例。
例如,如果您定义了项目级元数据对 baz=bat
,则该元数据对将自动应用于项目中的所有实例。
控制台
- 在 Google Cloud Console 中,转到元数据页面。
- 点击修改。
- 添加或修改元数据条目。
- 保存更改。
gcloud
在 gcloud
命令行工具中,使用 project-info add-metadata
命令。例如:
gcloud compute project-info add-metadata \ --metadata foo=bar,baz=bat
使用 describe
命令查看元数据:
gcloud compute project-info describe
例如,您可能会得到类似如下内容的响应:
... commonInstanceMetadata: fingerprint: RfOFY_-eS64= items: - key: baz value: bat - key: foo value: bar - key: ssh-keys ...请使用等号指定一个元数据键值对,例如
key=value
;多个键值对以空格分隔。
您可以视情况使用 --metadata-from-file
标志指定一个或多个要从中读取元数据的文件。您可以使用 project-info remove-metadata
命令移除元数据值。
API
在 API 中,向 projects().setCommonInstanceMetadata
方法发出请求,并提供所有新元数据值。
如需执行乐观锁定,您可以选择提供指纹。指纹是由 Compute Engine 生成的随机字符串。每次请求后指纹都会更改,因此如果您提供的指纹不匹配,请求将被拒绝。
如果您未提供指纹,则无需执行一致性检查,并且 projects().setCommonInstanceMetadata
请求将会成功。此行为与 instances().setMetadata
不同,后者始终需要指纹。
如需获取实例的当前指纹,请执行 project().get
请求并复制指纹值:
GET https://compute.googleapis.com/compute/v1/projects/myproject { "name": "myproject", "commonInstanceMetadata": { "kind": "compute#metadata", "fingerprint": "FikclA7UBC0=", ... }
接着,向 projects().setCommonInstanceMetadata
方法发出请求,并设置您的自定义元数据键值对:
POST https://compute.googleapis.com/compute/v1/projects/myproject/setCommonInstanceMetadata { "fingerprint": "FikclA7UBC0=", "items": [ { "key": "foo", "value": "bar" } ] }
查询自定义元数据
您可以通过 Cloud Console、gcloud
命令行工具或 API 查询自定义实例或项目元数据。
控制台
如需查看项目级自定义元数据,请转到元数据页面。
要查看实例的自定义元数据,请执行以下操作:
- 转到“虚拟机实例”页面。
- 点击您要查看其元数据的实例。
- 在自定义元数据下方,查看该实例的自定义元数据。
gcloud
查询项目元数据:
gcloud compute project-info describe \ --flatten="commonInstanceMetadata[]"
查询实例元数据:
gcloud compute instances describe example-instance \ --flatten="metadata[]"
使用 --flatten
标志将输出范围限定为相关的元数据键。例如,以下实例的自定义元数据键值对为 foo:bar
。
$ gcloud compute instances describe example-instance ... metadata: fingerprint: Cad2L9eKNR0= items: - key: foo value: bar kind: compute#metadata ...
如需查询键 foo
的值,请运行以下命令:
gcloud compute instances describe example-instance \
--flatten="metadata[foo]"
---
bar
API
如需查询项目的元数据,请对 projects().get
方法执行空请求:
GET https://compute.googleapis.com/compute/v1/projects/myproject
如需查询实例的元数据,请对 instance().get
方法执行空请求:
GET https://compute.googleapis.com/compute/v1/projects/myproject/zones/us-central1-a/instances/example-instance
设置和查询客机特性
客机特性是指应用在实例上运行期间可写入的特定类型的自定义元数据。实例上的任何应用或用户都可以对这些客机特性元数据值执行数据读取和写入操作。
何时使用客机特性
客机特性仅适用于需要少量不常更改的数据的用例,最适合使用客机特性的用例具有以下特征:
- 每个虚拟机实例的查询次数限制为每分钟最多 10 次查询。
- 查询作业的爆发速率不超过每秒 3 次查询。如果超出此速率上限,Compute Engine 可能会任意移除正在写入的客机特性。移除此数据是为了确保能将其他关键系统数据写入服务器。
客机属性非常适合您需要发布少量不常见数据的情况。例如,客机特性在以下用例中会很实用:
- 启动脚本可以通过在客机特性中设置自定义状态值来发送初始化成功信号。
- 配置管理代理可以将客机操作系统名称和版本发布到客机特性。
- 库存管理代理可以将虚拟机实例中安装的软件包列表发布到客机特性。
- 工作负载编排软件可以通过在客机特性中设置自定义状态值,向软件控制层发送客机内部操作的完成信号。
客机特性不能替代事件流、Pub/Sub 或其他形式的数据存储和配置代码库。
对于实例内部的读取和写入操作,元数据服务器会提供实例级的自动身份验证和授权。每个实例只能对自己的元数据服务器执行读取或写入操作。一个实例的元数据服务器不可供其他实例访问。用户和服务帐号只有在其 Identity and Access Management (IAM) 角色具备 compute.instances.getGuestAttributes
权限的情况下,才能从实例外部读取实例的客机特性。
为您的实例启用客机特性
默认情况下,客机特性处于停用状态。如需启用客机特性,请在个别实例或项目级元数据中设置必要的元数据值:
控制台
创建实例时,请在实例元数据中设置 enable-guest-attributes
:
- 在 Google Cloud Console 中,转到虚拟机实例页面。
- 点击创建实例。
- 在创建新实例页面上,填写所需的实例属性。
- 在元数据部分中,添加键为
enable-guest-attributes
且值为TRUE
的元数据条目。 - 点击创建以创建实例。
在项目级元数据中设置 enable-guest-attributes
,使其应用于项目中的所有实例:
- 在 Google Cloud Console 中,转到元数据页面。
- 点击修改。
- 添加一个键为
enable-guest-attributes
且值为TRUE
的元数据条目。或者,将值设置为FALSE
以停用该功能。 - 点击保存以应用更改。
在现有实例的元数据中设置 enable-guest-attributes
:
- 在 Google Cloud Console 中,转到虚拟机实例页面。
- 点击要为其设置元数据值的实例的名称。
- 在实例详情页面的顶部,点击修改以修改实例设置。
- 在自定义元数据下方,添加一个元数据条目,其中键为
enable-guest-attributes
,值为TRUE
。或者,将值设置为FALSE
以在实例上停用该功能。 - 在实例详情页面的底部,点击保存以将更改应用于实例。
gcloud
创建实例时,在实例元数据中设置 enable-guest-attributes
:
在 gcloud
命令行工具中使用 gcloud compute instances create
命令,并设置 enable-guest-attributes=TRUE
以启用客机特性。将 instance-name
替换为您的实例名称。
gcloud compute instances create instance-name \ --metadata enable-guest-attributes=TRUE
在项目级元数据中设置 enable-guest-attributes
,使其应用于项目中的所有实例:
在 gcloud
命令行工具中使用 project-info add-metadata
命令,并设置 enable-guest-attributes=TRUE
以启用客机特性:
gcloud compute project-info add-metadata \ --metadata enable-guest-attributes=TRUE
您也可以将 enable-guest-attributes
设为 FALSE
以停用客机特性。
在现有实例的元数据中设置 enable-guest-attributes
:
在 gcloud
命令行工具中使用 instances add-metadata
命令,并设置 enable-guest-attributes=TRUE
以启用客机特性。将 instance-name
替换为您的实例名称。
gcloud compute instances add-metadata instance-name \ --metadata enable-guest-attributes=TRUE
您也可以将 enable-guest-attributes
设为 FALSE
,以对实例停用客机特性。
设置客机特性
在虚拟机实例中运行的任何进程都可以写入客机特性值,包括没有 sudo 或管理员级权限的脚本和应用。实例外部的用户或服务帐号不能写入客机特性元数据值。
例如,您可以在自己的实例中使用 curl
请求向 guest-attributes
元数据路径写入值:
curl -X PUT --data "value" http://metadata.google.internal/computeMetadata/v1/instance/guest-attributes/namespace/key -H "Metadata-Flavor: Google"
替换以下内容:
namespace
:key
的逻辑分组。客机特性必须具有命名空间。value
:要写入的值。key
:guest-attributes
中用于存储值的元数据路径。
对于 namespace
和 key
字段,只能使用字母、数字、下划线 (_
) 和连字符 (-
)。
获取客机特性
如果用户或服务帐号的 IAM 角色具备 compute.instances.getGuestAttributes
权限,则该用户或服务帐号便可读取客机特性。此外,实例中的任何用户或应用也都可以读取该特定实例的元数据值。
在虚拟机中运行的任何进程都可以写入客机特性值,包括没有 sudo 或管理员级权限的脚本和应用。例如,您可以在自己的实例中使用 curl
请求从 guest-attributes
元数据路径中读取值:
curl http://metadata.google.internal/computeMetadata/v1/instance/guest-attributes/namespace/key -H "Metadata-Flavor: Google"
替换以下内容:
namespace
:您要查询的guest-attributes
键的命名空间。key
:您要从中读取元数据值的guest-attributes
路径。
您也可以在一个请求中返回所有客机特性值。将 namespace
替换为您要查询的 guest-attributes
键的命名空间。
curl http://metadata.google.internal/computeMetadata/v1/instance/guest-attributes/namespace/ -H "Metadata-Flavor: Google"
gcloud
使用 gcloud
命令行工具读取实例中的客机特性元数据值。例如,您可以检索实例的所有值:
gcloud compute instances get-guest-attributes instance-name \ --zone zone
如需检索特定命名空间下的所有值,请加入 --query-path
标志和您定义的命名空间:
gcloud compute instances get-guest-attributes instance-name \ --query-path=namespace \ --zone zone
如需检索特定命名空间下的所有值,请加入 --query-path
标志、相应命名空间和您所定义的值对应的键:
gcloud compute instances get-guest-attributes instance-name \ --query-path=namespace/key \ --zone zone
替换以下内容:
instance-name
:您要从中读取客机特性元数据值的实例的名称。namespace
:您要查询的guest-attributes
键的命名空间。key
:guest-attributes
元数据中用于存储值的路径。zone
:实例所在的地区。
API
使用 compute.instances.getguestattributes
API 方法:
GET https://compute.googleapis.com/compute/v1/projects/project-id/zones/zone/instances/instance-name/getGuestAttributes?queryPath=namespace/key
替换以下内容:
project-id
:您的项目 ID。zone
:实例所在的地区。instance-name
:您要从中读取客机特性元数据值的实例的名称。namespace
:您要查询的guest-attributes
键的命名空间。key
:guest-attributes
元数据中用于存储值的路径。
如需检索 namespace
的所有键,请省略 key
:
GET https://compute.googleapis.com/compute/v1/projects/project-id/zones/zone/instances/instance-name/getGuestAttributes?queryPath=namespace
如需检索该实例在每个命名空间中的所有键,请完全省略 namespace
和 queryPath
:
GET https://compute.googleapis.com/compute/v1/projects/project-id/zones/zone/instances/instance-name/getGuestAttributes
或者,如果您有 OAuth 令牌,则可以使用 curl
:
curl -H "Authorization: Bearer oauth-token" https://compute.googleapis.com/compute/v1/projects/project-id/zones/zone/instances/instance-name/getGuestAttributes?queryPath=namespace/key
替换以下内容:
oauth-token
:您的 OAuth 令牌。project-id
:您的项目 ID。zone
:实例所在的地区。instance-name
:您要从中读取客机特性元数据值的实例的名称。namespace
:您要查询的guest-attributes
键的命名空间。key
:guest-attributes
元数据中用于存储值的路径。
删除客机特性
您还可以删除客机特性。例如,使用 curl
删除特定键:
curl -X DELETE http://metadata.google.internal/computeMetadata/v1/instance/guest-attributes/namespace/key -H "Metadata-Flavor: Google"
替换以下内容:
namespace
:您要删除的guest-attributes
键的命名空间。key
:guest-attributes
中用于存储值的路径。
对组织或文件夹停用客机特性
如果您不希望您的组织或文件夹中的任何实例启用客机特性,则可以完全替换并停用该功能。
对您的组织或文件夹设置 constraints/compute.disableGuestAttributesAccess
限制条件,将 project-id
替换为您的项目名称:
gcloud resource-manager org-policies enable-enforce \ constraints/compute.disableGuestAttributesAccess \ --project project-id
如需详细了解如何设置和管理针对组织的限制条件,请参阅使用限制条件。
等待更新
鉴于元数据值可能会在实例运行时发生更改,元数据服务器会使用 wait-for-change 功能来接收元数据更改通知。借助这项功能,您可以执行挂起的 HTTP GET
请求,让系统仅在您指定的元数据发生更改时返回响应。您可以对自定义元数据或服务器定义的元数据使用此功能;因此如果您的实例或项目发生任何变化,或者有人更新了某个自定义元数据,您可以编程方式来响应这项更改。例如,您可以对 tags
键执行请求,使系统仅在 tags 元数据的内容发生更改时才返回响应。请求返回后,会提供该元数据键的新值。
如需执行 wait-for-change 请求,请查询元数据键并附加 ?wait_for_change=true
查询参数:
user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/tags?wait_for_change=true" -H "Metadata-Flavor: Google"
指定的元数据键发生更改后,查询会返回新值。在此示例中,如果向 setInstanceTags 方法发出请求,则请求会返回新值:
user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/tags?wait_for_change=true" -H "Metadata-Flavor: Google" cheese lettuce
您还能以递归方式对目录内容执行 wait-for-change 请求:
user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/attributes/?recursive=true&wait_for_change=true" -H "Metadata-Flavor: Google"
如果发生任何更改,则元数据服务器会返回新内容:
user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/attributes/?recursive=true&wait_for_change=true" -H "Metadata-Flavor: Google" {"cheese":"lettuce","cookies":"cream"}
您还可以使用 wait-for-change 功能来匹配请求和设置超时值。
使用 ETag
当您提交简单的 wait-for-change 查询后,如果元数据内容发生了任何更改,元数据服务器就会返回响应。但是,由于元数据更新作业与发出的 wait-for-change 请求之间存在固有的竞争条件,因此通过一种可靠的方式来获悉您正在获取最新的元数据值将会很有帮助。
为实现此目的,您可以使用 last_etag
查询参数来将您提供的 ETag 值与保存在元数据服务器中的 ETag 值进行比较。如果这些 ETag 值一致,则系统将接受 wait-for-change 请求。如果这些 ETag 值不一致,则表明自您上次检索 ETag 值以后,元数据内容已更改,因此元数据服务器会立即返回此最新值。
如需获取元数据键的最新 ETag 值,请向该键发出请求并输出标头。在 curl
中,您可以使用 -v
标志来执行此操作:
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 < cheese lettuce
然后,您可以在 wait-for-change 请求中使用该 ETag 值:
user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/tags?wait_for_change=true&last_etag=411261ca6c9e654e" -H "Metadata-Flavor: Google"
元数据服务器会对您指定的 ETag 值进行匹配,如果该值发生更改,则请求将返回元数据键的新内容。
以下 Python 示例演示了如何以编程方式监控元数据服务器的更改:
设置超时值
如果您希望 wait-for-change 请求在特定秒数后超时,则可以设置 timeout_sec=<timeout-in-seconds>
查询参数。timeout_sec
参数会将请求的等待时间限制为您所指定的秒数,因此达到这一限制时,请求就会返回元数据键的当前内容。以下示例 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"
当您设置 timeout_sec
参数时,无论元数据值是否已发生实际更改,请求始终会在指定的秒数后返回响应。超时值必须设置为整数值。
状态代码
当您执行 wait-for-change 请求时,元数据服务器会返回标准 HTTP 状态代码以指示成功与否。如果发生错误,则网络状况可能会导致元数据服务器使您的请求失败,并返回错误代码。在此类情况下,您应该将应用设计成容错型,并且可以识别和处理这些错误。
元数据服务器返回的可能状态如下:
状态 | 说明 |
---|---|
HTTP 200 |
大功告成!值已更改,或者您已达到指定的 timeout_sec ,且请求已成功返回响应。 |
Error 400 |
您的请求无效。请修复查询并重试请求。 |
Error 404 |
您指定的元数据值不再存在。如果您的元数据在您等待更改时遭到删除,则元数据服务器也会返回此错误。 |
Error 503 |
发生临时服务器错误或临时维护事件。请重试请求。 |
获取实时迁移通知
元数据服务器通过 scheduling/
目录和 maintenance-event
特性提供有关实例的调度选项和设置的信息。您可以使用这些特性来了解虚拟机实例的调度选项,并使用此元数据,在维护事件即将发生时通过 maintenance-event
特性接收通知。默认情况下,所有虚拟机实例都设置为实时迁移,因此元数据服务器将在虚拟机实例实时迁移前收到维护事件通知。如果您选择在维护期间终结虚拟机实例,并且设置了 automaticRestart
特性,则 Compute Engine 将会自动终结您的虚拟机实例并视情况重启这些实例。如需详细了解维护事件以及这些事件发生时的实例行为,请参阅调度选项和设置。
您可以定期查询 maintenance-event
特性,了解何时会发生维护事件。此特性的值会在维护事件开始前 60 秒发生更改,让您的应用代码能够在维护事件之前触发您要执行的任何任务,例如备份数据或更新日志。Compute Engine 还会提供 Python 脚本示例来演示如何检查维护事件通知。
只有在以下情况下,Compute Engine 才会提前 60 秒发出警告:
您已将实例的可用性选项设置为在维护事件发生时实时迁移。
自上次维护事件以来,您已查询
maintenance-event
特性至少一次。如果您从未查询过maintenance-event
特性,或者自上次迁移后未查询过该特性,则 Compute Engine 会假定实例并不需要接收维护事件的提前警告。维护事件会跳过 60 秒的警告期而立即启动。如果您不想跳过 60 秒的警告期,请确保您的客户端代码会在两次迁移事件之间至少查询一次maintenance-event
特性。
如需查询 maintenance-event
特性,请运行以下命令:
user@myinst:~$ curl http://metadata.google.internal/computeMetadata/v1/instance/maintenance-event -H "Metadata-Flavor: Google" NONE
maintenance-event
特性的初始默认值为 NONE
。
对于 GPU 实例,在发生维护事件时,属性会从
NONE
更改为TERMINATE_ON_HOST_MAINTENANCE
。此特性会在终结事件开始前 60 分钟更新。对于调度选项为
migrate
的非 GPU 实例,maintenance-event
特性会发生如下变化:- 在迁移事件开始时,值会从
NONE
更改为MIGRATE_ON_HOST_MAINTENANCE
。此特性会在终结事件开始前 60 秒更新。 - 在整个事件持续期间以及您的虚拟机实时迁移期间,该值保持为
MIGRATE_ON_HOST_MAINTENANCE
。 - 在维护事件结束后,该值会恢复为
NONE
。
- 在迁移事件开始时,值会从
您可以将 maintenance-event
特性与等待更新功能搭配使用,以便在维护事件即将开始和结束时向您的脚本和应用发送通知。如此,您就能够自动执行可能需要在该事件前后运行的任意操作。以下 Python 示例演示了如何将这两种功能一起实现。
用于查询维护事件的 Python 脚本示例
检查服务器端点的版本
当前版本:v1
Compute Engine 可以提供多个元数据版本,但我们建议您始终使用可用的最新元数据服务器版本。Compute Engine 可以随时向元数据服务器添加新条目,并向响应添加新字段。请定期回来查看变化情况。
如需检查元数据服务器端点的版本,请查看您用来向服务器发出请求的 URI。
元数据端点版本 | URI |
---|---|
v0.1(已弃用) | http://metadata.google.internal/0.1/meta-data/… |
v1beta1(已弃用) | http://metadata.google.internal/computeMetadata/v1beta1/… |
v1 | http://metadata.google.internal/computeMetadata/v1/… |
停用旧版端点
您可以在项目级或实例级停用这些端点。
如需停用 v0.1 和 v1beta1 元数据服务器端点,请按照设置自定义元数据的说明来设置 disable-legacy-endpoints=TRUE
。
例如,如要使用 gcloud
命令行工具在项目级停用元数据服务器端点,请运行以下命令:
gcloud compute project-info add-metadata \ --metadata disable-legacy-endpoints=TRUE
转换到 v1 元数据服务器端点
如需了解如何从 v0.1 或 v1beta1 端点转换到 v1 端点,请参阅迁移至 v1 元数据服务器端点。