本页面介绍什么是 Spot 虚拟机及其在 Google Kubernetes Engine (GKE) 中的运作方式。如需了解如何使用 Spot 虚拟机,请参阅使用 Spot 虚拟机。
GKE 中的 Spot 虚拟机概览
Spot 虚拟机是一种价格低于标准 Compute Engine 虚拟机但不保证可用性的 Compute Engine 虚拟机 (VM) 实例。Spot 虚拟机提供与标准虚拟机相同的机器类型和选项。
您可以在集群和节点池中使用 Spot 虚拟机来运行无状态、批量或容错工作负载,这些工作负载可以容忍 Spot 虚拟机的临时性造成的中断。
Spot 虚拟机在 Compute Engine 需要标准虚拟机资源之前仍然可用。为了最大限度地提高成本效益,请结合使用 Spot 虚拟机与在 GKE 上运行费用经过优化的 Kubernetes 应用的最佳做法。
如需详细了解 Spot 虚拟机,请参阅 Compute Engine 文档中的 Spot 虚拟机。
Spot 虚拟机的优势
Spot 虚拟机和抢占式虚拟机具有诸多优势,具体如下所示:
与抢占式虚拟机(在 24 小时后过期)相比,Spot 虚拟机没有到期时间。Spot 虚拟机仅在 Compute Engine 在其他位置需要资源时终止。
Spot 虚拟机在 GKE 中的工作原理
当您创建具有 Spot 虚拟机的集群或节点池时,GKE 会创建类似于代管式实例组 (MIG) 的底层 Compute Engine Spot 虚拟机。使用 Spot 虚拟机的节点的行为类似于标准 GKE 节点,但不保证可用性。当需要使用 Spot 虚拟机所用的资源来运行标准虚拟机时,Compute Engine 会终止这些 Spot 虚拟机以在其他位置使用资源。
终止并正常关闭 Spot 虚拟机
当 Compute Engine 需要收回 Spot 虚拟机使用的资源时,系统会向 GKE 发送终止通知。 Spot 虚拟机在收到终止通知 30 秒后终止。
在运行 GKE 1.20 及更高版本的集群上,kubelet 安全节点关停功能默认启用。Kubelet 会注意到终止通知,并正常终止节点上运行的 Pod。 如果 Pod 是 Deployment 的一部分,则控制器会创建并安排新 Pod,以替换已终止的 Pod。
kubelet 会根据节点池的 GKE 版本尽力提供如下正常终止时间段:
- 高于 1.22.8-gke.200:非系统 Pod 为 15 秒,之后还会为系统 Pod(具有
system-cluster-critical
或system-node-critical
优先级类)提供额外 15 秒来正常终止。 - 1.22.8-gke.200 及更早版本:非系统 Pod 为 25 秒,之后还会为系统 Pod(具有
system-cluster-critical
或system-node-critical
优先级类)提供额外 5 秒来正常终止。
在节点正常终止期间,kubelet 会更新 Pod 的状态,为终止的 Pod 分配 Failed
阶段和 Terminated
原因。
当节点数少于 100 的集群的终止 Pod 数量达到阈值 1,000,或者节点数超过 100 的集群的终止 Pod 数量达到阈值 5,000 时,垃圾回收功能会清理 Pod。
您还可以使用以下命令手动删除已终止的 Pod:
kubectl get pods --all-namespaces | grep -i NodeShutdown | awk '{print $1, $2}' | xargs -n2 kubectl delete pod -n
kubectl get pods --all-namespaces | grep -i Terminated | awk '{print $1, $2}' | xargs -n2 kubectl delete pod -n
安排 Spot 虚拟机上的工作负载
GKE 会自动将 cloud.google.com/gke-spot=true
和 cloud.google.com/gke-provisioning=spot
(适用于运行 GKE 1.25.5-gke.2500 或更高版本的节点)标签添加到使用 Spot 虚拟机的节点。您可以使用 Pod 规范中的 nodeSelector 字段,在使用 Spot 虚拟机的特定节点上调度特定的 Pod。以下示例使用 cloud.google.com/gke-spot
标签:
apiVersion: v1
kind: Pod
spec:
nodeSelector:
cloud.google.com/gke-spot: "true"
或者,您可以使用节点亲和性指示 GKE 在 Spot 虚拟机上调度 Pod,类似于以下示例:
apiVersion: v1
kind: Pod
spec:
...
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: cloud.google.com/gke-spot
operator: In
values:
- "true"
...
您还可以使用 nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution
指示 GKE 将 Pod 放置在使用 Spot 虚拟机的节点上。不建议首选 Spot 虚拟机,因为 GKE 可能会将 Pod 调度到使用标准虚拟机的现有可行节点上。
使用污点和容忍进行安排
为避免系统中断,请使用节点污点来确保 GKE 不将关键工作负载调度到 Spot 虚拟机上。当您为使用 Spot 虚拟机的节点设置污点时,GKE 仅在这些节点上调度具有相应容忍的 Pod。
如果使用节点污点,请确保您的集群还至少有一个使用标准 Compute Engine 虚拟机的节点池。GKE 可以将使用标准虚拟机的节点池作为安全的位置来调度 DNS 等关键系统组件。
如需了解如何对 Spot 虚拟机使用节点污点,请参阅对 Spot 虚拟机使用污点和容忍。
将 Spot 虚拟机与 GPU 节点池搭配使用
Spot 虚拟机支持使用 GPU。当您创建新的 GPU 节点池时,GKE 会自动向新节点添加 nvidia.com/gpu=present:NoSchedule
污点。只有具有相应容忍设置的 Pod 可以在这些节点上运行。GKE 会自动将此容忍设置添加到请求 GPU 的 Pod 上。
在创建使用 Spot 虚拟机的 GPU 节点池之前,您的集群必须至少具有一个使用标准虚拟机的非 GPU 节点池。如果您的集群只有一个使用 Spot 虚拟机的 GPU 节点池,则 GKE 不会向这些节点添加 nvidia.com/gpu=present:NoSchedule
污点。因此,GKE 可能会将系统工作负载调度到使用 Spot 虚拟机的 GPU 节点池上,这可能会导致 Spot 虚拟机中断,并且可能会增加资源消耗量,因为 GPU 节点比非 GPU 节点的成本更高。
集群自动扩缩器和节点自动预配
您可以使用集群自动扩缩程序和节点自动预配功能来根据工作负载的需求自动扩缩集群和节点池。集群自动扩缩器和节点自动预配功能都支持使用 Spot 虚拟机。
Spot 虚拟机和节点自动预配
节点自动预配功能会自动在集群中创建和删除节点池,以满足工作负载的需求。当您使用 nodeSelector
或节点亲和性安排需要使用 Spot 虚拟机的工作负载时,节点自动预配功能会创建新的节点池来容纳工作负载的 Pod。GKE 会自动将 cloud.google.com/gke-spot=true:NoSchedule
污点添加到新节点池中的节点。只有具有相应容忍设置的 Pod 可以在这些节点池中的节点上运行。您必须为部署添加相应的容忍设置,以允许 GKE 将 Pod 放在 Spot 虚拟机上:
tolerations:
- key: cloud.google.com/gke-spot
operator: Equal
value: "true"
effect: NoSchedule
您可以确保 GKE 仅使用容忍设置以及用于过滤 Spot 虚拟机的 nodeSelector
或节点亲和性规则在 Spot 虚拟机上安排 Pod。
如果您仅使用容忍设置来调度工作负载,则 GKE 可以将 Pod 调度到 Spot 虚拟机或具有容量的现有标准虚拟机上。如果您需要在 Spot 虚拟机上调度工作负载,则除了容忍设置之外,请使用 nodeSelector
或节点亲和性。如需了解详情,请参阅在 Spot 虚拟机上调度工作负载。
Spot 虚拟机和集群自动扩缩器
集群自动扩缩器会根据需求自动添加和移除节点池中的节点。如果您的集群具有无法放置在现有 Spot 虚拟机上的 Pod,则集群自动扩缩器会添加使用 Spot 虚拟机的新节点。
默认政策
从 GKE 1.24.1-gke.800 版开始,您可以定义自动扩缩器位置政策。当资源可用且默认位置政策设置为 ANY
时,集群自动扩缩器会尝试预配 Spot 虚拟机节点池。在此政策中,Spot 虚拟机被抢占的风险较低。对于其他虚拟机类型,默认的集群自动扩缩器分布政策为 BALANCED
。
升级使用 Spot 虚拟机的 Standard 节点池
如果使用 Spot 虚拟机的 Standard 集群节点池配置为使用超额配置升级,则 GKE 会使用 Spot 虚拟机创建超额配置节点。但是,GKE 不会等待 Spot 虚拟机准备就绪之后再封锁和排空现有节点,因为 Spot 虚拟机无法保证可用性。如需了解详情,请参阅超额配置升级。
对 Kubernetes 行为的修改
在 GKE 上使用 Spot 虚拟机会修改 Kubernetes 提供的一些保证和限制条件,例如:
- Spot 虚拟机的弃用是非自愿的,不在
PodDisruptionBudgets
的保证范围内。相对于已配置的PodDisruptionBudget
,遇到不可用情况的几率可能较大。
Spot 虚拟机的最佳做法
在设计使用 Spot 虚拟机的系统时,您可以使用以下准则以避免重大中断:
- Spot 虚拟机无法保证可用性。在设计系统时,假设 GKE 可能会随时回收任何或所有 Spot 虚拟机,但无法保证新实例何时可用。
- 为了确保即使在没有 Spot 虚拟机可用的情况下系统也能处理您的工作负载和作业,请确保您的集群同时具有使用 Spot 虚拟机的节点池以及使用标准 Compute Engine 虚拟机的节点池。
- 在添加使用 Spot 虚拟机的 GPU 节点池之前,请确保您的集群至少包含一个使用标准虚拟机的非 GPU 节点池。
- 虽然节点名称在节点重新创建时通常不会发生变化,但 Spot 虚拟机使用的内部和外部 IP 地址可能会在重新创建后发生变化。
- 使用节点污点和容忍机制来确保关键 Pod 不会被调度到使用 Spot 虚拟机的节点池上。
- 如需在 Spot 虚拟机上运行有状态工作负载,请进行测试以确保您的工作负载可以在关停后的 25 秒内正常终止,从而最大限度地降低永久性卷数据损坏的风险。
- 遵循 Kubernetes Pod 终止最佳实践。
后续步骤
- 了解如何在节点池中使用 Spot 虚拟机。
- 了解如何自动扩缩集群。
- 了解如何扩缩已部署的应用。
- 利用 Compute Engine 文档中详细了解 Spot 虚拟机。
- 学习有关如何在 GKE 中使用 Spot 虚拟机部署批处理工作负载的教程。