查询元数据服务器以获取维护事件通知


元数据服务器通过 scheduling/ 元数据目录列表和 maintenance-event 元数据键提供有关 Compute Engine 实例的调度选项和设置的信息。您可以使用这些元数据键来了解虚拟机的调度选项,并接收即将进行的维护事件通知。

在计算实例被实时迁移或终止之前,元数据服务器会收到维护事件通知。如需详细了解维护事件以及这些事件发生时的实例行为,请参阅主机维护概览

对于一组特定的虚拟机,您的虚拟机维护选项更加灵活。如需了解详情,请参阅监控和规划主机维护事件

准备工作

  • 对于 Windows Server 虚拟机,请使用 PowerShell 3.0 或更高版本。我们建议您使用 ctrl+v 来粘贴复制的代码块。
  • 如果您尚未设置身份验证,请进行设置。身份验证是通过其进行身份验证以访问 Google Cloud 服务和 API 的过程。如需从本地开发环境运行代码或示例,您可以通过选择以下选项之一向 Compute Engine 进行身份验证:

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

  • Install the Google Cloud CLI.

  • If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.

  • To initialize the gcloud CLI, run the following command:

    gcloud init
  • 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.

    If an authentication error is returned, and you are using an external identity provider (IdP), confirm that you have signed in to the gcloud CLI with your federated identity.

  • 如需了解详情,请参阅 Set up authentication for a local development environment。 如需了解详情,请参阅身份验证文档中的为本地开发环境设置 ADC

获取实时迁移通知

您可以定期查询 maintenance-event 元数据键,了解实例即将发生实时迁移的时间。

只有在您已将虚拟机的调度选项设置为 migrate 或者您的虚拟机挂接了 GPU 时,系统才会针对维护事件填充 maintenance-event 元数据。

此元数据键的值会在维护事件开始前 60 秒发生更改,让您的应用代码能够在维护事件之前触发您要执行的任何任务,例如备份数据或更新日志。

只有在以下情况下,Compute Engine 才会提前 60 秒发出警告:

  • 您已将虚拟机的可用性选项设置为在维护事件期间实时迁移。

  • 自上次维护事件以来,您已查询 maintenance-event 元数据键至少一次。

    • 如果您从未查询过 maintenance-event 元数据键,或者自上次迁移后未查询过元数据键,则 Compute Engine 会假定虚拟机不需要接收维护事件的提前警告。维护事件会跳过 60 秒的警告期而立即启动。

    • 如果您不想跳过 60 秒的警告期,请确保您的客户端代码会在两次迁移事件之间至少查询一次 maintenance-event 元数据键。您必须直接查询 maintenance-event 元数据键,以便 Compute Engine 确定您是否在监控此元数据键。查询更高级层的元数据不会触发提前通知。

对于挂接了 GPU 的虚拟机,该值会在虚拟机停止前 60 分钟发生更改,让您有时间关停虚拟机并在其他宿主机上再次重启虚拟机。挂接了 GPU 的虚拟机不会实时迁移,而是会停止并视情况重启。如需了解详情,请参阅处理 GPU 宿主机维护事件

查询维护事件元数据键

Linux 虚拟机

如需查询 Linux 虚拟机上的 maintenance-event 元数据键,请运行以下命令:

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

输出类似于以下内容:

NONE

您还可以使用 wait-for-change 选项。指定此选项后,请求仅会在维护事件即将开始或结束时返回输出。

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

Windows 虚拟机

如需查询 Windows 虚拟机上的 maintenance-event 元数据键,请运行以下命令:

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

输出类似于以下内容:

NONE

您还可以使用 wait-for-change 选项。指定此选项后,请求仅会在维护事件即将开始或结束时返回输出。

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

Python

您可以将 maintenance-event 元数据键与等待更新功能搭配使用,以便在维护事件即将开始和即将结束时向您的脚本和应用发送通知。这样,您就能自动执行可能需要在该事件前后运行的任意操作。

以下 Python 示例演示了如何将这两种功能一起实现。

import time
from typing import Callable, NoReturn, Optional

import requests


METADATA_URL = "http://metadata.google.internal/computeMetadata/v1/"
METADATA_HEADERS = {"Metadata-Flavor": "Google"}


def wait_for_maintenance(callback: Callable[[Optional[str]], None]) -> NoReturn:
    """Start an infinite loop waiting for maintenance signal.

    Args:
        callback: Function to be called when a maintenance is scheduled.

    Returns:
        Never returns, unless there's an error.
    """
    url = METADATA_URL + "instance/maintenance-event"
    last_maintenance_event = None
    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"]

        if r.text == "NONE":
            maintenance_event = None
        else:
            maintenance_event = r.text

        if maintenance_event != last_maintenance_event:
            last_maintenance_event = maintenance_event
            callback(maintenance_event)


def maintenance_callback(event: Optional[str]) -> None:
    """Example callback function to handle the maintenance event.

    Args:
        event: details about scheduled maintenance.
    """
    if event:
        print(f"Undergoing host maintenance: {event}")
    else:
        print("Finished host maintenance")


def main():
    wait_for_maintenance(maintenance_callback)


if __name__ == "__main__":
    main()

查看输出

maintenance-event 元数据键的初始默认值为 NONE

  • 对于挂接 GPU 的虚拟机、裸金属实例或其他不支持实时迁移的实例,在维护事件期间,该值会从 NONE 更改为 TERMINATE_ON_HOST_MAINTENANCE。此值会在终结事件开始前 60 分钟更新。

  • 对于调度选项为 migrate 的非 GPU 虚拟机,maintenance-event 值会发生如下变化:

    1. 在迁移事件开始时,值会从 NONE 更改为 MIGRATE_ON_HOST_MAINTENANCE。此值会在终结事件开始前 60 秒更新。
    2. 在整个事件持续期间以及您的虚拟机实时迁移期间,该值保持为 MIGRATE_ON_HOST_MAINTENANCE
    3. 在维护事件结束后,该值会恢复为 NONE
  • 对于单租户虚拟机,在主机维护事件期间,maintenance-event 元数据键值对不会更改,并且从事件开始到事件结束都保持为 NONE

对于支持高级维护功能的机器系列,您可以在维护事件之前查询元数据键 upcoming-maintenance。如果您的实例有可用的通知,您应该会看到类似于以下内容的值:

{
   "maintenanceType":"SCHEDULED"
   "canReschedule": "true"
   "latestWindowStartTime": "2025-08-28T21:56:21Z"
   "maintenanceStatus": "PENDING"
   "windowEndTime": "2025-08-29T01:56:20Z"
   "windowStartTime": "2025-08-28T21:56:26Z"
}

在维护事件之前,系统会填充 upcoming-maintenance 元数据键,如下所示:

  • C3、C3D:最多 7 天
  • C4D:最多 7 天
  • X4:最多 60 天
  • Z3:最多 7 天

后续步骤