你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

如何在现成虚拟机上构建工作负载

Azure 虚拟机

本文概述了在 Azure 现成虚拟机 (VM) 中进行构建的最佳做法,并包括可部署的示例方案。 与常规 VM 相比,现成 VM 以低得多的价格提供对计算容量的访问。 对于希望优化成本的组织来说,此折扣使其成为一个有吸引力的解决方案,但要节省成本是有条件的。 现成 VM 可能随时失去对计算的访问权限。 我们将此过程称为逐出。 在现成 VM 上运行的工作负载必须能够处理这些计算中断。 成功的关键是要具有合适的工作负载和灵活的业务流程机制。 以下建议适用于在现成 VM 上进行构建。

了解现成虚拟机

从技术层面讲,现成 VM 与常规 VM 相同。 它们使用相同的映像、硬件和磁盘,也可以说,它们的性能相同。 现成 VM 与常规 VM 的差别归结为优先级和可用性。 现成 VM 没有访问计算容量的优先级,在访问该计算容量后,它们无法保证可用性。 让我们更详细地讨论优先级和可用性。

无优先级访问。 常规 VM 对计算容量具有优先级访问。 只要对计算容量发出请求,它们就可访问。 另一方面,现成 VM 仅在有空闲计算容量时部署,并且仅在常规 VM 不需要基础硬件时才保持运行。

无可用性保证。 现成 VM 没有任何可用性保证。 它们不附带服务级别协议 (SLA)。 现成 VM 可能会在部署后立即或随时失去对计算容量的访问权限(逐出)。 由于存在逐出的可能性,现成 VM 的价格更便宜。 每当 Azure 需要恢复计算容量时,就会发送逐出通知并逐出现成 VM。 Azure 在实际逐出发生之前至少提前 30 秒发出通知。 有关详细信息,请参阅本文中的持续监视逐出。

了解现成虚拟机定价

现成 VM 的价格最多比常规(即用即付)VM 便宜 90%。 具体折扣因需求、VM 大小、部署区域和操作系统而异。 我们建议使用 Azure 现成 VM 定价工具来估算可节省的成本。 有关详细信息,请参阅:

还可以查询 Azure 零售价格 API,以编程方式获取任何感兴趣的 SKU 的现货价格。

了解可中断工作负载

可中断工作负载是现成 VM 的最佳用例。 可中断工作负载具有一些共同特征。 他们几乎没有时间限制,组织优先级较低,且处理时间较短。 它们运行的流程可能突然停止,然后在不损害基本组织流程的情况下恢复。 可中断工作负载的示例包括批处理应用程序、数据分析,以及为非生产环境创建持续集成/持续部署代理的工作负载。 这些功能与具有服务级别协议 (SLA)、粘性会话和有状态数据的常规或任务关键工作负载形成了对比。 下表提供了上述两种工作负载类型的示例。

可中断工作负载功能 常规工作负载功能
功能 极小甚至没有时间限制
组织优先级较低
处理时间短
服务级别协议 (SLA)
粘性会话要求
有状态工作负载

可以在不可中断工作负载中使用现成 VM,但这些 VM 不应成为计算容量的单一源。 根据需要使用尽可能多的常规 VM 来满足运行时间要求。

了解逐出

现成 VM 在创建后不附带服务级别协议 (SLA),并且可能随时失去对计算的访问权限。 我们将这种计算损失称为逐出。 计算的供应和需求将驱动逐出。 当对特定 VM 大小的需求超过特定水平时,Azure 会逐出现成 VM 以使计算可供常规 VM 使用。 需求因地点而异。 区域 A 中的需求增加不会影响区域 B 中的现成 VM。

现成 VM 有两个配置选项会影响逐出。 这些配置是现成 VM 的“逐出类型”和“逐出策略”。 在创建现成 VM 时设置这些配置。 “逐出类型”定义逐出条件。 “逐出策略”确定逐出对现成 VM 执行的操作。 让我们讨论这两个配置选项。

逐出类型

逐出是因容量变化或价格变化而导致的。 这些因素影响现成 VM 的方式取决于创建 VM 时选择的逐出类型。 逐出类型定义逐出条件。 逐出类型为“仅限容量的逐出”和“价格或容量逐出”。

仅限容量的逐出:这种逐出类型会在多余的计算容量消失时触发逐出。 默认情况下,价格上限为即用即付费率。 如果你愿意最高按照即用即付 VM 价格付费,请使用此逐出类型。

价格或容量逐出:这种逐出类型有两个触发器。 当多余的计算容量消失或 VM 的成本超过设置的最高价格时,Azure 会逐出现成 VM。 此逐出类型允许将最高价格设置为远低于即用即付价格。 使用此逐出类型可以设置你自己的价格上限。

逐出策略

为现成 VM 选择的逐出策略会影响其业务流程。 业务流程是指处理逐出的过程。 稍后将详细介绍业务流程。 逐出策略为“停止/解除分配策略”和“删除策略”。

停止/解除分配策略:当工作负载可以等待同一位置和 VM 类型释放容量时,停止/解除分配逐出策略是最佳选择。 停止/解除分配策略会停止 VM 并结束其与基础硬件达成的租约。 停止和解除分配现成 VM 的过程与停止和解除分配常规 VM 相同。 仍可在 Azure 中访问该 VM,并且以后可以重启同一 VM。 使用停止/解除分配策略时,VM 将失去计算容量和非静态 IP 地址。 但是,VM 数据磁盘将会保留,并且仍会产生费用。 VM 还会占用订阅中的核心。 即使已停止/解除分配 VM,也无法将其从其所在的 Azure 区域或局部区域中移动。 有关详细信息,请参阅 VM 开通状态和计费

删除策略:如果工作负载可以更改位置或 VM 大小,请使用“删除策略”。 更改位置和/或 VM 大小可以更快地重新部署 VM。 删除策略会删除 VM 和任何数据磁盘。 VM 不占用订阅中的核心。 有关逐出策略的详细信息,请参阅逐出策略

针对灵活业务流程进行设计

业务流程是在逐出后替换现成 VM 的过程。 它是构建可靠的可中断工作负载的基础。 良好的业务流程系统具有内置的灵活性。 灵活性是指设计的业务流程可提供多种选项,可使用多种 VM 大小,可部署到不同的区域,可以感知逐出,并考虑到了不同的逐出方案,从而提高工作负载的可靠性和速度。

下面概述了一些建议,以帮助你为可中断工作负载设计灵活业务流程。

针对速度进行设计

对于在现成 VM 上运行的工作负载,计算容量非常宝贵。 随时可能发生逐出会提高你对分配的计算时间的认知,并促使你做出优先考虑工作负载速度的有意义设计决策。 一般情况下,我们建议优化现有的计算时间。 应该生成一个预装了全部所需软件的 VM 映像。 预装的软件有助于最大程度地缩短从逐出到完全运行应用程序之间的时间。 建议避免将计算时间用于对工作负载用途没有价值的进程。 例如,数据分析工作负载应该将大部分计算时间集中在数据处理上,尽可能少地集中在收集逐出元数据上。 从应用程序中消除非必要进程。

使用多个 VM 大小和位置

建议构建一个业务流程,以使用多种 VM 类型和大小来提高灵活性。 目的是在业务流程中提供用于替换被逐出 VM 的选项。 Azure 以大致相同的价格提供功能类似的不同 VM 类型和大小。 应该筛选 VM 最小 vCPU 数/核心数和/或最小 RAM 量以及最高价格,以找到有能力运行你的工作负载且不超出预算的多个 VM。 每种 VM 类型有一个以百分比范围(0-5%、5-10%、10-15%、15-20%、20% 以上)表示的逐出率。 逐出率因区域而异。 对于不同区域中的相同 VM 类型,可以找到更合适的逐出率。 可以在门户中的“基本信息”选项卡下找到每种 VM 类型的逐出率。选择“大小”链接(“查看定价历史记录”或“查看所有大小”)。 还可以使用 Azure Resource Graph 以编程方式获取现成 VM 数据。 有关详细信息,请参阅:

使用最灵活的逐出策略

逐出的现成 VM 的逐出策略会影响替换过程。 删除逐出策略比停止/解除分配逐出策略更灵活。

首先考虑删除策略:如果你的工作负载可以处理删除逐出策略,我们建议使用这种策略。 删除策略允许业务流程将用于替换的现成 VM 部署到新的局部区域和 Azure 区域。 这种部署灵活性有助于工作负载比已停止/已解除分配的 VM 更快地找到备用计算容量。 已停止/已解除分配的 VM 必须在创建它的同一区域中等待备用计算容量。 对于删除策略,需要一个流程来监视应用程序外部的逐出,并协调部署到不同区域和/或使用不同的 VM SKU。

了解停止/解除分配策略:停止/解除分配策略的灵活性不如删除策略。 现成 VM 必须位于同一 Azure 区域和局部区域。 无法将已停止/已解除分配的 VM 移到另一个位置。 由于 VM 有固定的位置,因此当计算容量可用时,需要做好一些准备工作才能重新分配 VM。 无法预测计算容量何时可用。 因此,我们建议使用一个自动化计划管道在逐出后尝试重新部署。 逐出应触发该计划管道,并且重新部署尝试应持续检查计算容量,直到计算容量可用为止。

策略 When
删除 临时计算和数据
不想付费购买数据磁盘
最低预算
停止/解除分配 需要特定的 VM 大小
无法更改位置
应用程序安装过程持续很长时间
无限期等待
不单单受成本节省的驱动

持续监视逐出

监视对于现成 VM 上的工作负载可靠性至关重要。 现成 VM 在创建后不附带 SLA,随时可能被逐出。 提高现成 VM 上的工作负载可靠性的最佳方式是预测这些 VM 何时被逐出。 获取这些信息后,可以尝试正常关闭工作负载并触发自动化来协调替换。

使用 Scheduled Events:我们建议为每个 VM 使用 Scheduled Events 服务。 当 VM 将受到基础结构维护的影响时,Azure 会向 VM 发送信号。 逐出符合基础结构维护条件。 Azure 会在所有 VM 被逐出前至少 30 秒向所有 VM 发送 Preempt 信号。 使用名为 Scheduled Events 的服务,可以通过查询位于静态、不可路由的 IP 地址 169.254.169.254 的终结点来捕获此 Preempt 信号。

使用频繁查询:我们建议足够频繁地查询 Scheduled Events 终结点以协调正常关闭。 最多可以每隔一秒查询 Scheduled Events 终结点,但并非所有用例都需要一秒的频率。 这些查询必须来自现成 VM 上运行的应用程序。 查询不能来自外部源。 因此,查询将消耗 VM 计算容量并盗用主工作负载的处理能力。 需要根据具体的情况平衡这些竞争优先级。

自动化业务流程:在你收集 Preempt 信号后,业务流程应该对该信号采取行动。 由于存在时间限制,Preempt 信号应该尝试正常关闭工作负载,并启动一个自动化过程来替换现成 VM。 有关详细信息,请参阅:

构建部署系统

逐出后,业务流程需要通过一个自动化管道来部署新的现成 VM。 该管道应在可中断工作负载本身的外部运行,以确保持久运行。 部署管道的工作方式取决于为现成 VM 选择的逐出策略。

对于删除策略,我们建议构建一个使用不同 VM 大小并部署到不同区域的管道。 对于停止/解除分配策略,部署管道需要两个不同的操作。 对于 VM 的初始创建,该管道需要将适当大小的 VM 部署到正确的位置。 对于逐出的 VM,该管道需要尝试重启 VM,直到它正常工作。 Azure Monitor 警报和 Azure Functions 的组合是将部署系统自动化的多种方式之一。 管道可以使用 Bicep 模板。 这些模板是声明性和幂等性的,代表了基础结构部署的最佳做法。

准备立即逐出

现成 VM 可能指定为在创建后立即逐出,甚至可能在工作负载执行之前就被逐出。 仅凭有可用于创建现成 VM 的容量这一点,并不能说明该 VM 会持久保留。 现成 VM 在创建后不附带可用性保证 (SLA)。 业务流程需要考虑到立即逐出的情况。 Preempt 信号仍会在逐出之前至少提前 30 秒提供通知。

建议将 VM 运行状况检查合并到业务流程中,以便为立即逐出做好准备。 用于处理立即逐出的业务流程不能依赖于 Scheduled Events Preempt 信号。 只有 VM 本身可以查询 Preempt 信号,没有足够的时间可以启动应用程序、查询 Scheduled Events 终结点并正常关闭。 因此运行状况检查需要驻留在工作负载环境之外。 运行状况检查需要观察现成 VM 的状态,并在状态更改为“正在解除分配”或“正在停止”时启动部署管道来替换现成 VM。

为多个同时逐出做好规划

如果你正在运行现成 VM 的群集,应该将工作负载架构为可以承受多个同时逐出。 工作负载中的多个现成 VM 可能会同时逐出。 同时逐出多个 VM 可能会影响应用程序的吞吐量。 为避免这种情况,部署管道应该能够从多个 VM 收集信号并同时部署多个替换 VM。

针对正常关闭进行设计

VM 关闭过程应短于 30 秒,并允许 VM 在逐出前关闭。 关闭所需的时间取决于工作负载查询 Scheduled Events 终结点的频率。 查询终结点的频率越高,关闭过程所需的时间就越长。 关闭过程应释放资源、排空连接并刷新事件日志。 应该定期创建并保存检查点以保存上下文,并构建更有效的恢复策略。 检查点只是有关下一个 VM 需要对哪些进程或事务启动的信息。 它们应该指示 VM 是否应该从前一个 VM 停止的位置恢复,或者新的 VM 是否应该回滚更改并重新启动整个进程。 应该将检查点存储在现成 VM 环境之外。 有一个存储帐户就可以了。

测试业务流程

建议模拟逐出事件以在开发/测试环境中测试业务流程。 有关详细信息,请参阅模拟逐出

设计一个幂等工作负载

建议设计一个幂等工作负载。 多次处理某一事件的结果应该与处理该事件一次的结果相同。 尽管逐出会尽力确保正常关闭,但仍可能会导致强制关闭。 强制关闭可能会在完成之前终止进程。 幂等工作负载可以多次接收同一消息,并且结果保持不变。 有关详细信息,请参阅幂等性

使用应用程序预热期

大多数可中断工作负载会运行应用程序。 应用程序需要花费时间来安装和启动。 它们需要花费时间连接到外部存储并从检查点收集信息。 我们建议先为应用程序留出一段预热期,然后再允许它开始处理。 在预热期,应用程序将会启动、建立连接并准备好发挥作用。 应该仅在验证应用程序的运行状况后,才允许应用程序开始处理数据。

Diagram of the workload lifecycle with an application warmup period

配置用户分配的托管标识

建议使用用户分配的托管标识来简化身份验证和授权过程。 使用用户分配的托管标识可以避免将凭据放入代码,并且它们不像系统分配的托管标识那样与单个资源相关联。 用户分配的托管标识包含 Microsoft Entra ID 提供的、可以在业务流程期间重用并分配到现成 VM 的权限和访问令牌。 现成 VM 之间的令牌一致性有助于简化业务流程以及对现成 VM 上的工作负载资源的访问。

使用系统分配的托管标识时,新的现成 VM 可能会从 Microsoft Entra ID 获取不同的访问令牌。 如果你需要使用系统分配的托管标识,我们建议使工作负载弹性处理 403 Forbidden Error 响应。 业务流程需要从 Microsoft Entra ID 获取具有正确权限的令牌。 有关详细信息,请参阅托管标识

示例方案

该示例方案部署一个符合可中断工作负载条件的队列处理应用程序。 方案中的脚本是演示性的。 该方案将引导你执行一次性的手动推送来部署资源。 我们尚未为此实现提供部署管道。 但是,部署管道对于自动化业务流程至关重要。 示图说明了示例方案的体系结构。

Diagram of the example scenario architecture.

以下备注说明了体系结构的关键方面:

  1. VM 应用程序定义:VM 应用程序定义是在 Azure Compute Gallery 中创建的。 它定义应用程序名称、位置、操作系统和元数据。 应用程序版本是 VM 应用程序定义的带编号版本。 应用程序版本是 VM 应用程序的实例化。 它需要与现成 VM 位于同一区域。 应用程序版本链接到存储帐户中的源应用程序包。
  2. 存储帐户:存储帐户存储源应用程序包。 在此体系结构中,它是一个名为 worker-0.1.0.tar.gz 的 tar 压缩文件。 它包含两个文件。 其中一个文件是用于安装 .NET 辅助角色应用程序的 orchestrate.sh bash 脚本。
  3. 现成 VM:现成 VM 部署。 它必须与应用程序版本位于同一区域。 它在部署后将 worker-0.1.0.tar.gz 下载到 VM。 Bicep 模板在标准系列 VM 上部署 Ubuntu 映像。 这些配置符合此应用程序的需求,并非适用于应用程序的一般建议。
  4. 存储队列:.NET 辅助角色中运行的另一个服务包含消息队列逻辑。 Microsoft Entra ID 通过 RBAC 为现成 VM 授予使用用户分配的标识访问存储队列的权限。
  5. .NET 辅助角色应用程序:orchestrate.sh 脚本安装一个 .NET 辅助角色应用程序,该应用程序运行两个后台服务。 第一个服务查询 Scheduled Events 终结点,查找 Preempt 信号并将此信号发送到第二个服务。 第二个服务处理来自存储队列的消息,并侦听来自第一个服务的 Preempt 信号。 当第二个服务收到信号时,它会中断存储队列处理并开始关闭。
  6. 查询 Scheduled Events 终结点:将一个 API 请求发送到不可路由的静态 IP 地址 169.254.169.254。 该 API 请求查询 Scheduled Events 终结点以获取基础结构维护信号。
  7. Application Insights:该体系结构仅将 Application Insights 用于学习目的。 Application Insights 不是可中断工作负载业务流程的不可或缺组成部分。 我们包含 Application Insights 的目的是为了让你能够验证来自 .NET 辅助角色应用程序的遥测数据。 我们已将 .NET 辅助角色应用程序配置为向 Application Insights 发送遥测数据。 有关详细信息,请参阅从 .NET 应用程序启用实时指标

部署此方案

GitHub logo 我们创建了一个名为现成 VM 上的可中断工作负载的 GitHub 存储库,其中包含用于部署此体系结构的模板、脚本和相关分步说明。 可以在此存储库中找到有关体系结构和工程项目的更多技术详细信息。

后续步骤

有关现成虚拟机的详细信息,请参阅 Azure 现成虚拟机