本页面介绍如何在 Google Kubernetes Engine (GKE) 集群和节点池中使用 Spot 虚拟机,以更低的费用运行容错、无状态或批处理工作负载。
概览
Spot 虚拟机是一种价格低于默认标准虚拟机但不保证可用性的 Compute Engine 虚拟机。Spot 虚拟机提供与标准 Compute Engine 虚拟机相同的机器类型和选项。Compute Engine 可以根据系统事件(例如标准虚拟机需要资源时)随时回收 Spot 虚拟机。
如需详细了解 GKE 中的 Spot 虚拟机,请参阅 Spot 虚拟机。
Spot 虚拟机可以代替抢占式虚拟机来运行无状态、批量或容错工作负载。与抢占式虚拟机(在 24 小时后过期)相比,Spot 虚拟机没有到期时间。当 Compute Engine 需要资源运行标准虚拟机时,Spot 虚拟机会终止。
采用 Spot Pod 的 GKE Autopilot 集群也支持 Spot 虚拟机。使用 Spot Pod 时,Autopilot 会自动安排和管理 Spot 虚拟机上的工作负载。
限制
- kubelet 安全节点关停功能仅会在运行 GKE 1.20 版及更高版本的集群上启用。对于 1.20 之前的 GKE 版本,您可以使用 Kubernetes on GCP 节点终止事件处理程序在 Spot 虚拟机被抢占时安全终止 Pod。
- Spot 虚拟机不支持 Windows Server 节点池。
准备工作
在开始之前,请确保您已执行以下任务:
- 启用 Google Kubernetes Engine API。 启用 Google Kubernetes Engine API
- 如果您要使用 Google Cloud CLI 执行此任务,请安装并初始化 gcloud CLI。 如果您之前安装了 gcloud CLI,请运行
gcloud components update
以获取最新版本。
创建采用 Spot 虚拟机的集群
您可以通过 Google Cloud CLI 或 Google Cloud 控制台创建采用 Spot 虚拟机的新集群。
gcloud
创建一个在默认节点池中使用 Spot 虚拟机(而不是标准虚拟机)的新集群:
gcloud container clusters create CLUSTER_NAME \
--spot
将 CLUSTER_NAME
替换为新集群的名称。
控制台
如需创建在节点池中使用 Spot 虚拟机的新集群,请执行以下步骤:
转到 Google Cloud 控制台中的 Google Kubernetes Engine 页面。
点击 add_box 创建。
在创建集群对话框中,点击 GKE 标准旁边的配置。
在导航菜单的节点池部分中,点击要配置的节点池的名称,然后点击节点。
选中启用 Spot 虚拟机复选框。
根据需要配置集群,然后点击创建。
创建采用 Spot 虚拟机的节点池
您可以通过 gcloud CLI 或 Google Cloud 控制台创建采用 Spot 虚拟机的新节点池。您只能在新节点池上启用 Spot 虚拟机。您无法在现有节点池上启用或停用 Spot 虚拟机。
gcloud
创建采用 Spot 虚拟机的新节点池:
gcloud container node-pools create POOL_NAME \
--cluster=CLUSTER_NAME \
--spot
将 POOL_NAME
替换为新节点池的名称。
控制台
如需创建采用 Spot 虚拟机的新节点池,请执行以下步骤:
转到 Google Cloud 控制台中的 Google Kubernetes Engine 页面。
在集群列表中,点击您要修改的集群的名称。
点击
添加节点池。在导航菜单中,点击节点。
选中启用 Spot 虚拟机复选框。
根据需要配置节点池,然后点击创建。
安排 Spot 虚拟机上的工作负载
GKE 会将 cloud.google.com/gke-spot=true
和 cloud.google.com/gke-provisioning=spot
(适用于运行 GKE 1.25.5-gke.2500 或更高版本的节点)标签添加到使用 Spot 虚拟机的节点。您可以使用 Pod 规范中的 nodeSelector
字段或节点亲和性在 Pod 规范中过滤出此标签。
在以下示例中,您将创建一个包含两个节点池的集群,其中一个节点池使用 Spot 虚拟机。然后,您可以将无状态 nginx
应用部署到 Spot 虚拟机上,并使用 nodeSelector
控制 GKE 放置 Pod 的位置。
创建一个在默认节点池中使用标准虚拟机的新集群:
gcloud container clusters create CLUSTER_NAME
将
CLUSTER_NAME
替换为新集群的名称。获取集群的凭据:
gcloud container clusters get-credentials CLUSTER_NAME
创建采用 Spot 虚拟机的节点池:
gcloud container node-pools create POOL_NAME \ --num-nodes=1 \ --spot
将
POOL_NAME
替换为新节点池的名称。将以下清单保存为名为
pi-app.yaml
的文件:apiVersion: batch/v1 kind: Job metadata: name: pi spec: template: metadata: labels: app: pi spec: nodeSelector: cloud.google.com/gke-spot: "true" terminationGracePeriodSeconds: 25 containers: - name: pi image: perl:5.34.0 command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"] restartPolicy: Never backoffLimit: 4
在此清单中,
nodeSelector
字段指示 GKE 仅在使用 Spot 虚拟机的节点上调度 Pod。将清单应用到您的集群:
kubectl apply -f pi-app.yaml
描述 Pod:
kubectl describe pod pi
输出类似于以下内容:
Name: pi-kjbr9 Namespace: default Priority: 0 Node: gke-cluster-2-spot-pool-fb434072-44ct ... Labels: app=pi job-name=pi Status: Succeeded ... Controlled By: Job/pi Containers: ... Conditions: Type Status Initialized True Ready False ContainersReady False PodScheduled True Volumes: ... Node-Selectors: cloud.google.com/gke-spot=true Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s node.kubernetes.io/unreachable:NoExecute op=Exists for 300s Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 4m3s default-scheduler Successfully assigned default/pi-kjbr9 to gke-cluster-2-spot-pool-fb434072-44ct Normal Pulling 4m2s kubelet Pulling image "perl:5.34.0" Normal Pulled 3m43s kubelet Successfully pulled image "perl:5.34.0" in 18.481761978s Normal Created 3m43s kubelet Created container pi Normal Started 3m43s kubelet Started container pi
Node
字段显示 GKE 仅在使用 Spot 虚拟机的节点上调度 Pod。
对 Spot 虚拟机使用污点和容忍
最佳做法是让创建的集群中存在至少一个没有采用 Spot 虚拟机的节点池,这样您便可以在其中放置诸如 DNS 等系统工作负载。您可以使用节点污点和相应的容忍设置来指示 GKE 避免将某些工作负载放置在 Spot 虚拟机上。
如需让创建的节点池包含采用添加了节点污点的 Spot 虚拟机的节点,您可以在创建节点池时使用
--node-taints
标志:gcloud container node-pools create POOL_NAME \ --node-taints=cloud.google.com/gke-spot="true":NoSchedule --spot
如需向要调度到 Spot 虚拟机的 Pod 添加相应的容忍设置,您可以修改部署并将以下内容添加到 Pod 规范中:
tolerations: - key: cloud.google.com/gke-spot operator: Equal value: "true" effect: NoSchedule
GKE 仅将具有此容忍设置的 Pod 调度到添加了节点污点的 Spot 虚拟机上。
后续步骤
- 了解如何使用按需节点作为后备在 Spot 虚拟机上运行 GKE 应用。
- 详细了解 GKE 中的 Spot 虚拟机。
- 了解污点和容忍。
- 学习有关如何在 GKE 中使用 Spot 虚拟机部署批处理工作负载的教程。