跳到内容
观澜涉川 · 札记EN

在 Azure Kubernetes Service 中使用 Azure Spot 实例

· 约 2 分钟阅读

出于成本优化的考虑,在 AKS (Azure Kubernetes Service) 可使用 Spot 实例作为工作节点。但是,Spot 实例可能在任何时间被 Azure 关机。不过每种类型的虚拟机都有一个驱逐率( Eviction Rate),该驱逐率以百分比范围表示,例如 0%-5%、5%-10%、10%-15%、15%-20% 或 20% 以上。基于具体需求,要综合考虑成本、VM规格和驱逐率等因素,选择合适的VM类型。同时每个VM类型的驱逐率是随着时间变化的,可能需要定期地更新工作负载所需要的VM类型。

查询相关因素

VM 的规格

不同类型的VM有不同的内存、本地存储等,比如Dadsv5 系列就有不同的类型。在网页上检索效率低,可使用 Azure CLI 或者编程语言获取。比如使用 Azure CLI 命令:

Terminal window
az vm list-sizes

驱逐率和价格历史

参考《Use Azure Spot Virtual Machines》 一文,可在 Azure Resource Graph Explorer 中查询不同 VM 类型的驱逐率:

SpotResources
| where type =~ 'microsoft.compute/skuspotevictionrate/location'
| where sku.name in~ ('standard_d2s_v4', 'standard_d4s_v4')
| where location in~ ('eastus', 'southcentralus')
| project skuName = tostring(sku.name), location, spotEvictionRate = tostring(properties.evictionRate)
| order by skuName asc, location asc

使用如下查询获取价格历史:

SpotResources
| where type =~ 'microsoft.compute/skuspotpricehistory/ostype/location'
| where sku.name in~ ('standard_d2s_v4', 'standard_d4s_v4')
| where properties.osType =~ 'linux'
| where location in~ ('eastus', 'southcentralus')
| project skuName = tostring(sku.name), osType = tostring(properties.osType), location, latestSpotPriceUSD = todouble(properties.spotPrices[0].priceUSD)
| order by latestSpotPriceUSD asc

修改节点池的VM类型

直接修改节点池的 VM 类型是不可能的。为了尽量保证 AKS 服务在线,可使用新的 VM 类型创建新的节点池,然后再删除老的节点池。删除节点池的操作可能会持续很长时间。期间 AKS 会对节点执行清空 (Drain)操作,并可能会失败。

删除节点池时的常见失败是由于 Pod Disruption Budget (POD)策略。Azure 在错误信息中,给出了相关链接 《Troubleshoot UpgradeFailed errors due to eviction failures caused by PDBs》,并建议在删除节点时使用 --ignore-pod-disruption-budget true 选项。但在当前的 az 版本里,应该使用 --ignore-pdb 选项。

如果使用 Pulumi、Terraform 等工具管理基础设置,那么并不能直接在删除时添加 --ignore-pdb 选项。同时,由于删除节点池非常耗时,有可能导致 CD 流水线超时。一种可行的方法是,将修改节点池VM类型的操作分为两次代码提交和多个执行步骤:

  1. 在第一次的代码提交中,使用新的节点池名称(节点池的名称最大长度是 6 个字符),创建新的节点池
  2. 执行部署
  3. 在第二次代码提交中,删除旧的节点池
  4. 执行部署。这一次部署可能失败,如果失败了,那就在 Azure Portal 上手动再次点击删除。直至删除成功

整个部署多长可能非常耗时。