你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
本文介绍如何将辅助 Spot 节点池添加到现有 Azure Kubernetes 服务 (AKS) 群集中。
现成节点池是由Azure 现成虚拟机规模集支持的节点池。 借助 AKS 群集中的现成 VM,可以充分利用未使用的 Azure 容量,并大幅节省成本。 可用的未用容量因多个因素而异,如节点大小、区域、时间等。
部署现成节点池时,如果存在可用容量,Azure 会分配现成节点,并在单个默认域中部署支持现成节点池的现成规模集。 现成节点没有 SLA。 不提供高可用性保证。 如果 Azure 需要收回容量,Azure 基础设施会驱逐 Spot 节点。
现成节点非常适用于可处理中断、提前终止或逐出的工作负载。 例如,批处理作业、开发、测试环境和大型计算工作负载等工作负载可能非常适合在现成节点池上进行计划。
开始之前
- 本文假设读者基本了解 Kubernetes 和 Azure 负载均衡器的概念。 有关详细信息,请参阅 Azure Kubernetes 服务 (AKS) 的 Kubernetes 核心概念。
- 如果没有 Azure 订阅,请在开始之前创建一个免费帐户。
- 当创建群集以使用现成节点池时,该群集还必须将虚拟机规模集用于节点池和标准 SKU 负载均衡器。 创建群集后,还必须添加另一个节点池,本教程将介绍具体操作。
- 本文要求运行 Azure CLI 2.14 或更高版本。 运行
az --version即可查找版本。 如果需要进行安装或升级,请参阅安装 Azure CLI。
限制
创建和管理具有 Spot 节点池的 AKS 群集时,以下限制适用:
- 现成节点池不能是默认节点池,只能用作辅助池。
- 不能同时升级控制平面和节点池。 您必须分别升级它们,或者删除 Spot 节点池,以同时升级控制平面和其余节点池。
- 现成节点池必须使用虚拟机规模集。
-
ScaleSetPriority或SpotMaxPrice一经创建便无法更改。 - 设置
SpotMaxPrice时,值必须为 -1,或者为小数点后最多五位的正值。 - 现成节点池具有
kubernetes.azure.com/scalesetpriority:spot标签、排斥kubernetes.azure.com/scalesetpriority=spot:NoSchedule,且系统 pod 具有反亲和性。 - 必须添加相应容许和亲和性以在现成节点池中计划工作负载。
将 Spot 节点池添加到 AKS 群集
向现有集群添加 Spot 节点池时,该集群必须已启用多个节点池。 创建启用了多个节点池的 AKS 群集时,默认情况下会创建一个 priority 为 Regular 的节点池。 若要添加 Spot 节点池,必须将 priority 的值指定为 Spot。 有关创建包含多个节点池的 AKS 群集的更多详细信息,请参阅使用多个节点池。
- 使用
az aks nodepool add命令创建具有Spot的priority的节点池。
export SPOT_NODEPOOL="spotnodepool"
az aks nodepool add \
--resource-group $RESOURCE_GROUP \
--cluster-name $AKS_CLUSTER \
--name $SPOT_NODEPOOL \
--priority Spot \
--eviction-policy Delete \
--spot-max-price -1 \
--enable-cluster-autoscaler \
--min-count 1 \
--max-count 3 \
--no-wait
在上一个命令中,priority 为 Spot 使节点池成为现成节点池。 参数 eviction-policy 设置为 Delete,这是默认值。 将逐出策略设置为 Delete 时,节点池的底层规模集中的节点会在被逐出时删除。
也可以将逐出策略设置为 Deallocate,这意味着底层规模集中的节点会在逐出时设置为 stopped-deallocated 状态。 处于 stopped-deallocated 状态的节点会占用您的计算配额,并可能在群集扩缩容或升级时引发问题。
priority 和 eviction-policy 值只能在创建节点池时设置。 以后不能更新这些值。
上一条命令还会启用集群自动扩缩容器,我们建议将其与 Spot 节点池配合使用。 根据群集中运行的工作负载,群集自动缩放程序将纵向扩展和缩减节点数。 对于 Spot 节点池,如果在发生驱逐后仍然需要更多节点,集群自动扩缩器将增加节点数量。 如果更改节点池可以具有的最大节点数,还需要调整与群集自动缩放程序关联的 maxCount 值。 如果不使用集群自动扩缩器,那么在发生驱逐后,Spot 节点池最终会减少到 0,并且需要手动操作才能获得任何额外的 Spot 节点。
重要
仅将能够容忍中断的工作负载安排到 Spot 节点池上,例如批处理作业和测试环境。 建议在现成节点池上设置排斥和容许,确保仅在现成节点池上计划可处理节点逐出的工作负载。 例如,上述命令会添加排斥 kubernetes.azure.com/scalesetpriority=spot:NoSchedule,因此在此节点上仅计划具有相应容许的 pod。
验证 Spot 节点池
- 使用
az aks nodepool show命令验证您的节点池已成功添加,并确认scaleSetPriority为Spot。
az aks nodepool show --resource-group $RESOURCE_GROUP --cluster-name $AKS_CLUSTER --name $SPOT_NODEPOOL
结果:
{
"artifactStreamingProfile": null,
"availabilityZones": null,
"capacityReservationGroupId": null,
"count": 3,
"creationData": null,
"currentOrchestratorVersion": "1.30.10",
"eTag": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"enableAutoScaling": true,
"enableCustomCaTrust": false,
"enableEncryptionAtHost": false,
"enableFips": false,
"enableNodePublicIp": false,
"enableUltraSsd": false,
"gatewayProfile": null,
"gpuInstanceProfile": null,
"gpuProfile": null,
"hostGroupId": null,
"id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourcegroups/xxxxxxxxxxxxxxxx/providers/Microsoft.ContainerService/managedClusters/xxxxxxxxxxxxxxxx/agentPools/xxxxxxxxxxxx",
"kubeletConfig": null,
"kubeletDiskType": "OS",
"linuxOsConfig": null,
"maxCount": 3,
"maxPods": 30,
"messageOfTheDay": null,
"minCount": 1,
"mode": "User",
"name": "xxxxxxxxxxxx",
"networkProfile": {
"allowedHostPorts": null,
"applicationSecurityGroups": null,
"nodePublicIpTags": null
},
"nodeImageVersion": "AKSUbuntu-2204gen2containerd-xxxxxxxx.xx.x",
"nodeInitializationTaints": null,
"nodeLabels": {
"kubernetes.azure.com/scalesetpriority": "spot"
},
"nodePublicIpPrefixId": null,
"nodeTaints": [
"kubernetes.azure.com/scalesetpriority=spot:NoSchedule"
],
"orchestratorVersion": "x.xx.xx",
"osDiskSizeGb": 128,
"osDiskType": "Managed",
"osSku": "Ubuntu",
"osType": "Linux",
"podIpAllocationMode": null,
"podSubnetId": null,
"powerState": {
"code": "Running"
},
"provisioningState": "Creating",
"proximityPlacementGroupId": null,
"resourceGroup": "xxxxxxxxxxxxxxxx",
"scaleDownMode": "Delete",
"scaleSetEvictionPolicy": "Delete",
"scaleSetPriority": "Spot",
"securityProfile": {
"enableSecureBoot": false,
"enableVtpm": false,
"sshAccess": "LocalUser"
},
"spotMaxPrice": -1.0,
"status": null,
"tags": null,
"type": "Microsoft.ContainerService/managedClusters/agentPools",
"typePropertiesType": "VirtualMachineScaleSets",
"upgradeSettings": {
"drainTimeoutInMinutes": null,
"maxSurge": null,
"maxUnavailable": null,
"nodeSoakDurationInMinutes": null,
"undrainableNodeBehavior": null
},
"virtualMachineNodesStatus": null,
"virtualMachinesProfile": null,
"vmSize": "Standard_DS2_v2",
"vnetSubnetId": null,
"windowsProfile": null,
"workloadRuntime": "OCIContainer"
}
将 Pod 调度到 Spot 节点上运行
若要计划 pod 在现成节点上运行,可添加与应用到现成节点的排斥相对应的容许和节点相关性。
以下示例显示了 YAML 文件的一部分,该文件定义了与kubernetes.azure.com/scalesetpriority=spot:NoSchedule排斥相对应的容忍度以及与kubernetes.azure.com/scalesetpriority=spot标签相对应的节点亲和性(通过requiredDuringSchedulingIgnoredDuringExecution和preferredDuringSchedulingIgnoredDuringExecution节点相关性规则在上一步中使用):
spec:
containers:
- name: spot-example
tolerations:
- key: "kubernetes.azure.com/scalesetpriority"
operator: "Equal"
value: "spot"
effect: "NoSchedule"
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: "kubernetes.azure.com/scalesetpriority"
operator: In
values:
- "spot"
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: another-node-label-key
operator: In
values:
- another-node-label-value
当你部署一个具有此容忍和节点亲和性的 Pod 时,Kubernetes 会成功将该 Pod 调度到已应用相应污点和标签的节点上。 在此示例中,以下规则适用:
- 节点必须具有包含键
kubernetes.azure.com/scalesetpriority的标签,并且该标签的值必须为spot。 - 节点最好具有包含键
another-node-label-key的标签,并且该标签的值必须为another-node-label-value。
如需了解更多信息,请参见将 Pod 分配给节点。
升级现成节点池
升级现成节点池时,AKS 会在内部发出隔离和逐出通知,但不应用清空。 没有可用于升级 Spot 节点池的激增节点。 除这些更改外,升级 Spot 节点池时的行为与其他类型的节点池一致。
有关升级的详细信息,请参阅升级 AKS 群集。
现成池的最高价格
根据区域和 SKU 的不同,现成实例的定价有所浮动。 有关详细信息,请参阅适用于 Linux 和 Windows 的定价信息。
使用可变定价,你可以设置最高价格,以美元 (USD) 为单位,最多可使用五个小数位。 例如,值 0.98765 表示最高价格为 0.98765 美元/小时。 如果您将最高价格设置为 -1,则实例不会因价格原因被逐出。 只要有可用容量和配额,实例价格将按竞价实例当前价格和标准实例当前价格中的较低者计算。
后续步骤
在本文中,你已了解如何将 Spot 节点池添加到 AKS 群集。 有关如何跨节点池调度 Pod 的详细信息,请参阅AKS 中高级调度器功能的最佳做法。