为 Azure 虚拟机规模集实例终止通知

规模集实例可以选择接收实例终止通知,并为终止操作设置预定义的延迟超时。 终止通知通过 Azure 元数据服务 - Scheduled Events 发送,该服务为影响性操作(如重新启动和重新部署)提供通知和延迟。 解决方案将另一个事件“终止”添加到 Scheduled Events 列表中,终止事件的关联延迟将取决于用户在其规模集模型配置中指定的延迟限制。

一旦通过调用相应的元数据服务终结点在 Scheduled Events 中进行了注册,规模集实例不需要等待指定的超时,就能在删除实例前过期。 收到终止通知后,实例可以选择在终止超时到期之前随时删除。 无法在现成实例上启用终止通知。

启用终止通知

可以通过多种方式在规模集实例上启用终止通知,详见以下示例。

Azure 门户

创建新的规模集时,可以通过以下步骤启用终止通知。

  1. 转到“虚拟机规模集”。
  2. 选择“+ 添加”,创建新的规模集。
  3. 转到“管理”选项卡。
  4. 找到“实例终止”部分。
  5. 对于“实例终止通知”,选择“启用” 。
  6. 对于“终止延迟(分钟)”,设置所需的默认超时值。
  7. 创建新的规模集后,选择“查看 + 创建”按钮。

还可以在现有的规模集上启用终止通知。

  1. 导航到所需的规模集
  2. 转到“配置”选项卡
  3. 对于“启用实例终止通知”,选择“启用”。
  4. 对于“终止延迟(分钟)”,设置所需的默认超时值。
  5. 选择“保存”按钮。

REST API

以下示例对规模集模型启用终止通知。

PUT on `/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachineScaleSets/{vmScaleSetName}?api-version=2019-03-01`
{
  "properties": {
    "virtualMachineProfile": {
            "scheduledEventsProfile": {
                "terminateNotificationProfile": {
                    "notBeforeTimeout":"PT5M",
                    "enable":true
                }
            }
        }
    }        
}

上面的代码块为规模集中所有实例的任何终止操作指定 5 分钟的超时延迟(如 PT5M 所示)。 字段 notBeforeTimeout 可以接受采用 ISO 8601 格式,在 5 到 15 分钟之间的任何值。 可以通过修改上文所述的 terminateNotificationProfile 下的 notBeforeTimeout 属性来更改终止操作的默认超时 。

对规模集模型启用 scheduledEventsProfile 并设置 notBeforeTimeout 后,将各个实例更新为最新模型以反映更改 。

注意

只能使用 API 版本 2019-03-01 及更高版本对规模集实例启用终止通知

Azure PowerShell

创建新的规模集时,可以使用 New-AzVmssConfig cmdlet 对规模集启用终止通知。

此示例脚本使用配置文件演示如何创建规模集和相关资源:创建完整的虚拟机规模集。 通过将参数 TerminateScheduledEventsTerminateScheduledEventNotBeforeTimeoutInMinutes 添加到用于创建规模集的配置对象来提供“配置终止”通知。 以下示例以 10 分钟的延迟超时启用这项功能。

重要

从 2023 年 11 月开始,使用 PowerShell 和 Azure CLI 创建的 VM 规模集将默认为灵活业务流程模式(如果未指定业务流程模式)。 若要详细了解此更改以及你应采取哪些操作,请访问针对 VMSS PowerShell/CLI 客户的中断性变更 - Microsoft 社区中心

New-AzVmssConfig `
  -Location "VMSSLocation" `
  -SkuCapacity 2 `
  -OrchestrationMode "Flexible" `
  -SkuName "Standard_DS2" `
  -TerminateScheduledEvents $true `
  -TerminateScheduledEventNotBeforeTimeoutInMinutes 10

使用 Update-AzVmss cmdlet 对现有规模集启用终止通知。

Update-AzVmss `
  -ResourceGroupName "myResourceGroup" `
  -VMScaleSetName "myScaleSet" `
  -TerminateScheduledEvents $true `
  -TerminateScheduledEventNotBeforeTimeoutInMinutes 15

上述示例对现有规模集启用终止通知,并为终止事件设置 15 分钟的超时。

对规模集模型启用计划事件并设置超时后,将各个实例更新为最新模型以反映更改。

Azure CLI 2.0

以下示例用于在创建新规模集时启用终止通知。

az group create --name <myResourceGroup> --location <VMSSLocation>
az vmss create \
  --resource-group <myResourceGroup> \
  --name <myVMScaleSet> \
  --image Ubuntu2204 \
  --admin-username <azureuser> \
  --generate-ssh-keys \
  --terminate-notification-time 10

上面的示例首先创建一个资源组,然后创建一个新的规模集,并启用了 10 分钟的默认超时终止通知。

以下示例用于在现有规模集中启用终止通知。

az vmss update \  
  --resource-group <myResourceGroup> \
  --name <myVMScaleSet> \
  --enable-terminate-notification true \
  --terminate-notification-time 10

获取终止通知

终止通知通过 Scheduled Events 传递,它是一项 Azure 元数据服务。 Azure 元数据服务公开在 VM 中使用可访问的 REST 终结点运行虚拟机的相关信息。 该信息通过不可路由的 IP 提供,因此不会在 VM 外部公开。

首次为事件发出请求时,会为规模集启用 Scheduled Events。 首次调用时可能会延迟响应最多两分钟。 定期查询终结点,以便检测即将发生的维护事件以及正在进行的维护活动的状态。

如果规模集实例在 24 小时内未发出请求,则为规模集禁用 Scheduled Events。

终结点发现

对于启用了 VNET 的 VM,元数据服务可通过不可路由的静态 IP (169.254.169.254) 使用。

最新版本的计划事件的完整终结点是:

'http://169.254.169.254/metadata/scheduledevents?api-version=2019-01-01'

查询响应

响应包含计划事件的数组。 数组为空意味着目前没有计划事件。

如果有计划事件,响应会包含事件的数组。 对于“终止”事件,响应将如下所示:

{
    "DocumentIncarnation": {IncarnationID},
    "Events": [
        {
            "EventId": {eventID},
            "EventType": "Terminate",
            "ResourceType": "VirtualMachine",
            "Resources": [{resourceName}],
            "EventStatus": "Scheduled",
            "NotBefore": {timeInUTC},
        }
    ]
}

DocumentIncarnation 是一个 ETag,它提供了一种简单的方法来检查自上次查询以来事件有效负载是否已更改。

若要详细了解上述每个字段,请参阅适用于 WindowsLinux 的 Scheduled Events 文档。

响应事件

了解了即将发生的事件并完成正常关闭逻辑后,可以通过使用 EventId 对元数据服务进行 POST 调用来批准未完成的事件。 POST 调用向 Azure 指示可以继续删除 VM。

下面是 POST 请求正文中所需的 json。 请求应包含 StartRequests 列表。 每个 StartRequest 都包含要加速的事件的 EventId:

{
	"StartRequests" : [
		{
			"EventId": {EventId}
		}
	]
}

确保规模集中的每个 VM 仅批准与该 VM 相关的 EventID。 VM 可以通过实例元数据获取自身的 VM 名称。 此名称采用“{scale-set-name}_{instance-id}”的格式,将显示在上述查询响应的“资源”部分中。

还可以参阅示例脚本,来查询和响应事件 Python

提示和最佳实践

  • 仅对“删除”操作提供终止通知 - 如果规模集中已启用 scheduledEventsProfile,则所有删除操作(手动删除或自动缩放启动的缩放)都将生成终止事件。 重新启动、重置映像、重新部署和停止/解除分配等其他操作不会生成终止事件。
  • 无需强制等待超时 - 你可以在收到事件后和事件的 NotBefore 时间到期之前,随时启动终止操作。
  • 超时时强制删除 - 生成事件后,没有任何延长超时值的功能。 超时过期后,将处理挂起的终止事件,并删除 VM。
  • 可修改超时值 - 你可以在删除实例之前随时修改超时值,方法是修改规模集模型的 notBeforeTimeout 属性,并将 VM 实例更新为最新模型。
  • 批准所有挂起的删除 - 如果未批准的 VM_1 上有挂起的删除,并且你已批准 VM_2 上的另一个终止事件,则在批准 VM_1 的终止事件或其超时之前,不会删除 VM_2。 批准 VM_1 终止事件后,将删除 VM_1 和 VM_2。
  • 批准所有同时删除 - 扩展上述示例,如果 VM_1 和 VM_2 具有相同的 NotBefore 时间,则必须批准这两个终止事件,否则在超时到期之前,两个 VM 都不会被删除。

故障排除

无法启用 scheduledEventsProfile

如果收到“错误的请求”错误并显示错误消息“在‘VirtualMachineProfile’类型的对象中找不到成员‘scheduledEventsProfile’”,请检查用于规模集操作的 API 版本。 需要计算 API 版本 2019-03-01 或更高版本。

未能获取终止事件

如果无法通过 Scheduled Events 获取任何终止事件,请检查用于获取事件的 API 版本。 终止事件需要元数据服务 API 版本 2019-01-01 或更高版本。

'http://169.254.169.254/metadata/scheduledevents?api-version=2019-01-01'

通过不正确的 NotBefore 时间获取终止事件

对规模集模型启用 scheduledEventsProfile 并设置 notBeforeTimeout 后,将各个实例更新为最新模型以反映更改 。

后续步骤

了解如何在虚拟机规模集上部署应用程序