本頁面說明如何建立及管理Spot VM,包括:
- 如何建立、啟動及識別 Spot VM
- 如何偵測、處理及測試 Spot VM 先占
- Spot VM 最佳做法
Spot VM 是採用Spot 佈建模式的虛擬機器 (VM) 執行個體。與標準 VM 價格相比,Spot VM 提供 60% 至 91% 的折扣優惠。不過,Compute Engine 隨時可能會搶占 Spot VM,回收資源。 建議只用於能因應 VM 搶佔的容錯應用程式。決定建立 Spot VM 前,請務必確保應用程式可以處理先占。
事前準備
- 請參閱 Spot VM 的概念說明文件:
-
如果尚未設定驗證,請先完成設定。
「驗證」是指驗證身分的程序,確認您有權存取 Google Cloud 服務和 API。如要從本機開發環境執行程式碼或範例,請選取下列其中一個選項,向 Compute Engine 進行驗證:
Select the tab for how you plan to use the samples on this page:
Console
When you use the Google Cloud console to access Google Cloud services and APIs, you don't need to set up authentication.
gcloud
-
After installing the Google Cloud CLI, initialize it by running the following command:
gcloud init
If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.
- Set a default region and zone.
-
Install the Google Cloud CLI.
-
If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.
-
To initialize the gcloud CLI, run the following command:
gcloud init
-
If you're using a local shell, then create local authentication credentials for your user account:
gcloud auth application-default login
You don't need to do this if you're using Cloud Shell.
If an authentication error is returned, and you are using an external identity provider (IdP), confirm that you have signed in to the gcloud CLI with your federated identity.
- 在 Google Cloud 控制台中,將「VM 佈建模式」設為「Spot」
- gcloud CLI 中的
--provisioning-model=SPOT
- Compute Engine API 中的
"provisioningModel": "SPOT"
前往 Google Cloud 控制台的「Create an instance」(建立執行個體) 頁面。
在導覽選單中,按一下「進階」。在隨即顯示的「進階」窗格中,完成下列步驟:
- 在「佈建模型」部分,從「VM 佈建模型」清單中選取「Spot」。
選用:如要選取 Compute Engine 預先終止 VM 時執行的終止動作,請完成下列步驟:
- 展開「VM 佈建模式進階設定」部分。
- 在「On VM termination」(VM 終止時) 清單中,選取下列其中一個選項:
- 如要在先佔期間停止 VM,請選取「停止」 (預設)。
- 如要在搶占期間刪除 VM,請選取「刪除」。
視需要指定其他設定選項。詳情請參閱「建立執行個體時的設定選項」。
如要建立並啟動 VM,請按一下 [Create] (建立)。
VM_NAME
:新 VM 的名稱。TERMINATION_ACTION
:選用:指定 Compute Engine 先占 VM 時要採取的動作,可以是STOP
(預設行為) 或DELETE
。VM_NAME
:新 VM 的名稱。IMAGE
:指定下列其中一項:IMAGE
:公開映像檔或映像檔系列的特定版本。例如,特定圖片是--image=debian-10-buster-v20200309
。- 映像檔系列。
系統會使用未淘汰的最新 OS 映像檔建立 VM。舉例來說,如果您指定
--image-family=debian-10
,Compute Engine 會從 Debian 10 映像檔系列中,使用最新版本的 OS 映像檔建立 VM。
IMAGE_PROJECT
:包含映像檔的專案。舉例來說,如果您指定debian-10
做為映像檔系列,請指定debian-cloud
做為映像檔專案。MACHINE_TYPE
:新 VM 的預先定義或自訂機器類型。TERMINATION_ACTION
:選用:指定 Compute Engine 先占 VM 時要採取的動作,可以是STOP
(預設行為) 或DELETE
。如要取得區域可用的機器類型清單,請使用
gcloud compute machine-types list
指令和--zones
旗標。PROJECT_ID
:要在其中建立 VM 的專案專案 ID。ZONE
:要在其中建立 VM 的區域。此外,該區域也必須支援新 VM 使用的機器類型。MACHINE_TYPE
:新 VM 的預先定義或自訂機器類型。VM_NAME
:新 VM 的名稱。IMAGE_PROJECT
:包含映像檔的專案。舉例來說,如果您指定family/debian-10
做為映像檔系列,請指定debian-cloud
做為映像檔專案。IMAGE
:指定下列其中一項:- 公開映像檔的特定版本。舉例來說,特定圖片為
"sourceImage": "projects/debian-cloud/global/images/debian-10-buster-v20200309"
,其中debian-cloud
是IMAGE_PROJECT
。 - 映像檔系列。
系統會使用未淘汰的最新 OS 映像檔建立 VM。舉例來說,如果您指定
"sourceImage": "projects/debian-cloud/global/images/family/debian-10"
,其中debian-cloud
是IMAGE_PROJECT
,Compute Engine 會從 Debian 10 映像檔系列中最新版本的 OS 映像檔建立 VM。
- 公開映像檔的特定版本。舉例來說,特定圖片為
TERMINATION_ACTION
:選用:指定 Compute Engine 先占 VM 時要採取的動作,可以是STOP
(預設行為) 或DELETE
。前往「VM instances」(VM 執行個體) 頁面。
按一下要識別的 VM「名稱」。「VM instance details」(VM 執行個體詳細資料) 頁面隨即開啟。
前往頁面底部的「管理」部分。在「可用性政策」子部分中,檢查下列選項:
- 如果「VM 佈建模式」設為「Spot」,則 VM 為 Spot VM。
- 「VM 終止時」:指出 Compute Engine 預先終止 VM 時要採取的動作,即「停止」或「刪除」VM。
- 否則,如果 VM 佈建模式設為「標準」或「—」:
- 如果「Preemptibility」(先占) 選項設為「On」(啟用),則 VM 為先占 VM。
- 否則,VM 就是標準 VM。
- 如果「VM 佈建模式」設為「Spot」,則 VM 為 Spot VM。
如果輸出內容包含設為
SPOT
的provisioningModel
欄位 (如下所示),表示 VM 是 Spot VM。... scheduling: ... provisioningModel: SPOT instanceTerminationAction: TERMINATION_ACTION ...
其中
TERMINATION_ACTION
表示 Compute Engine 先占 VM 時要採取的動作,即停止 (STOP
) 或刪除 (DELETE
) VM。如果缺少instanceTerminationAction
欄位,預設值為STOP
。否則,如果輸出內容包含設為
standard
的provisioningModel
欄位,或輸出內容省略provisioningModel
欄位:- 如果輸出內容包含設為
true
的preemptible
欄位,表示 VM 是先占 VM。 - 否則,VM 就是標準 VM。
- 如果輸出內容包含設為
如果輸出內容包含設為
SPOT
的provisioningModel
欄位 (如下所示),表示 VM 是 Spot VM。{ ... "scheduling": { ... "provisioningModel": "SPOT", "instanceTerminationAction": "TERMINATION_ACTION" ... }, ... }
其中
TERMINATION_ACTION
表示 Compute Engine 先占 VM 時要採取的動作,即停止 (STOP
) 或刪除 (DELETE
) VM。如果缺少instanceTerminationAction
欄位,預設值為STOP
。否則,如果輸出內容包含設為
standard
的provisioningModel
欄位,或輸出內容省略provisioningModel
欄位:- 如果輸出內容包含設為
true
的preemptible
欄位,表示 VM 是先占 VM。 - 否則,VM 就是標準 VM。
- 如果輸出內容包含設為
建立 VM 時,至少具備 Cloud Storage 的讀取/寫入權限。如需建立具有適當範圍之 VM 的操作說明,請參閱驗證說明文件。
您有現有的 Cloud Storage 值區並有權限對其進行寫入。
複製或下載關機指令碼:
複製上述關機指令碼,並替換下列項目:
PROGRAM_NAME
是您要關閉的程序或程式名稱。例如apache2
或nginx
。LOCAL_USER
是您以其身分登入虛擬機器的使用者名稱。BUCKET_NAME
是您想儲存程式檢查點檔案的 Cloud Storage 值區名稱。請注意,本例中的 bucket 名稱開頭不是gs://
。
將關閉指令碼下載到本機工作站,然後在檔案中取代下列變數:
[PROGRAM_NAME]
是您要關閉之程序或程式的名稱。例如apache2
或nginx
。[LOCAL_USER]
是您以其身分登入虛擬機器的使用者名稱。[BUCKET_NAME]
是您想儲存程式查核點檔案之 Cloud Storage 值區的名稱。請注意,本例中的值區名稱開頭不是gs://
。
前往 Google Cloud 控制台的「記錄」頁面。
選取您的專案並點選 [繼續]。
將
compute.instances.preempted
新增至 [filter by label or text search] (按標籤或搜尋字詞篩選) 欄位。或者,如果您想查看特定 VM 的先占作業,也可以輸入 VM 名稱。
按下 Enter 鍵,套用指定篩選器。 Google Cloud 控制台會更新記錄清單,僅顯示 VM 遭到先占的作業。
選取清單中的作業,即可查看遭到先占之 VM 的相關詳細資料。
SYSTEM_EVENT
:gcloud compute operations list
指令輸出內容中的系統事件,例如systemevent-xxxxxxxx
。ZONE
:系統事件的區域,例如us-central1-f
。使用執行個體範本。您可以使用執行個體範本,一次建立多個屬性相同的 Spot VM,不必逐一建立。使用 MIG 時必須有執行個體範本。或者,您也可以使用大量執行個體 API 建立多個 Spot VM。
使用 MIG 在區域中發布 Spot VM,並自動重新建立這些 VM。使用受管理執行個體群組,讓 Spot VM 上的工作負載更具彈性和復原能力。舉例來說,使用區域性 MIG 將 VM 分散至多個可用區,有助於減輕資源可用性錯誤。此外,您也可以使用自動修復功能,在 Spot VM 遭到先占後自動重建。
挑選較小的機器類型。Spot VM 的資源來自多餘與備份 Google Cloud 容量。較小的機器類型通常較容易取得 Spot VM 容量,也就是具備較少 vCPU 和記憶體等資源的機器類型。選取較小的自訂機型,或許能取得更多 Spot VM 容量,但預先定義的較小機型更可能提供容量。舉例來說,與
n2-standard-32
預先定義的機器類型容量相比,n2-custom-24-96
自訂機器類型的容量較有可能,但n2-standard-16
預先定義的機器類型容量更有可能。在離峰時段執行大型 Spot VM 叢集。 Google Cloud 資料中心的負載量會因地點和時間而異,但通常在夜間和週末最低。因此,夜間和週末是執行大型 Spot VM 叢集的最佳時機。
將應用程式設計為容錯且能承受先占。 請務必做好準備,瞭解不同時間點的搶占模式會有所變化。舉例來說,如果某個可用區發生部分中斷,系統可能會先占大量 Spot VM,以便為需要遷移的標準 VM 騰出空間,做為復原程序的一部分。在該短時間內,預先搶占率會與其他任何一天大不相同。如果應用程式假設先占作業一律以小群組進行,您可能無法為這類事件做好準備。
再次嘗試建立已遭先占的 Spot VM。 如果 Spot VM 已遭到先占,請先嘗試建立新的 Spot VM 一兩次,再退而求其次使用標準 VM。視您的需求為何,可以考慮混合使用叢集中的標準 VM 和 Spot VM,以確保工作能夠按照適當的速度進行。
使用關閉指令碼。 請使用關閉指令碼管理關閉與先占通知,該指令碼要能夠儲存工作進度以接續上次進度,而不用從頭開始。
- 連線至 VM 執行個體。
- 瞭解關機指令碼。
- 瞭解如何限制 VM 的執行時間。
- 瞭解執行個體範本。
- 瞭解 MIG。
Terraform
如要在本機開發環境中使用本頁的 Terraform 範例,請安裝並初始化 gcloud CLI,然後使用使用者憑證設定應用程式預設憑證。
詳情請參閱 Set up authentication for a local development environment。
REST
如要在本機開發環境中使用本頁的 REST API 範例,請使用您提供給 gcloud CLI 的憑證。
After installing the Google Cloud CLI, initialize it by running the following command:
gcloud init
If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.
詳情請參閱 Google Cloud 驗證說明文件中的「Authenticate for using REST」。
建立 Spot VM
使用 Google Cloud 控制台、gcloud CLI 或 Compute Engine API 建立 Spot VM。Spot VM 是指設定為使用 Spot 佈建模式的任何 VM:
主控台
gcloud
如要透過 gcloud CLI 建立 VM,請使用
gcloud compute instances create
指令。如要建立 Spot VM,請務必加入--provisioning-model=SPOT
旗標。如有需要,您也可以一併加入--instance-termination-action
旗標,為 Spot VM 指定終止動作。gcloud compute instances create VM_NAME \ --provisioning-model=SPOT \ --instance-termination-action=TERMINATION_ACTION
更改下列內容:
如要進一步瞭解建立 VM 時可指定的選項,請參閱「執行個體建立期間的設定選項」。舉例來說,如要建立具有指定機型和映像檔的 Spot VM,請使用下列指令:
gcloud compute instances create VM_NAME \ --provisioning-model=SPOT \ [--image=IMAGE | --image-family=IMAGE_FAMILY] \ --image-project=IMAGE_PROJECT \ --machine-type=MACHINE_TYPE \ --instance-termination-action=TERMINATION_ACTION
更改下列內容:
Terraform
您可以使用 Terraform 資源,透過排程區塊建立 Spot 執行個體
REST
如要透過 Compute Engine API 建立 VM,請使用
instances.insert
方法。您必須指定 VM 的機器類型和名稱。您也可以選擇為開機磁碟指定映像檔。如要建立 Spot VM,請務必加入
"provisioningModel": spot
欄位。 如有需要,您也可以一併加入"instanceTerminationAction"
欄位,為 Spot VM 指定終止動作。POST https://compute.googleapis.com/compute/v1/projects/
PROJECT_ID
/zones/ZONE
/instances { "machineType": "zones/ZONE/machineTypes/MACHINE_TYPE", "name": "VM_NAME
", "disks": [ { "initializeParams": { "sourceImage": "projects/IMAGE_PROJECT/global/images/IMAGE" }, "boot": true } ] "scheduling": { "provisioningModel": "SPOT", "instanceTerminationAction": "TERMINATION_ACTION" }, ... }更改下列內容:
如要進一步瞭解建立 VM 時可指定的選項,請參閱「執行個體建立期間的設定選項」。
Go
Java
Python
如要建立多個具有相同屬性的 Spot VM,可以建立執行個體範本,並使用該範本建立代管執行個體群組 (MIG)。詳情請參閱「最佳做法」。
啟動 Spot VM
與其他 VM 相同,Spot VM 會在建立時啟動。同樣地,如果 Spot VM 停止運作,您可以重新啟動 VM,繼續執行
RUNNING
狀態。只要有容量,您就能視需要多次停止及重新啟動遭先占的 Spot VM。詳情請參閱「VM 執行個體生命週期」。如果 Compute Engine 停止自動調度資源代管執行個體群組 (MIG) 或 Google Kubernetes Engine (GKE) 叢集中的一或多個 Spot VM,當資源再次可用時,群組會重新啟動 VM。
找出 VM 的佈建模型和終止動作
找出 VM 的佈建模式,確認是標準 VM、Spot VM 還是先占 VM。如果是 Spot VM,您也可以識別終止動作。您可以使用Google Cloud 主控台、gcloud CLI 或 Compute Engine API,識別 VM 的佈建模型和終止動作。
主控台
gcloud
如要透過 gcloud CLI 說明 VM,請使用
gcloud compute instances describe
指令:gcloud compute instances describe VM_NAME
其中
VM_NAME
是要檢查的 VM 名稱。在輸出內容中,檢查
scheduling
欄位,找出 VM:REST
如要透過 Compute Engine API 說明 VM,請使用
instances.get
方法:GET https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/VM_NAME
更改下列內容:
在輸出內容中,檢查
scheduling
欄位,找出 VM:Go
Java
Python
管理 Spot VM 的搶占作業
如要瞭解如何管理 Spot VM 的搶占作業,請參閱下列章節:
使用關機指令碼處理先占
當 Compute Engine 預先終止 Spot VM 時,您可以使用關機指令碼,在 VM 預先終止前嘗試執行清除動作。舉例來說,您可以完善地停止運作中的程序,並將查核點檔案複製到 Cloud Storage。請注意,與使用者啟動的關機程序相比,搶占通知的關機期限較短。如要進一步瞭解先占通知的關機期限,請參閱 Spot VM 概念說明文件中的「先占程序」。
以下是關閉指令碼範例,您可以新增至執行中的 Spot VM,或在建立新的 Spot VM 時新增。這個指令碼的執行時機是 VM 開始關閉時,且作業系統的一般
kill
指令停止所有剩餘程序之前。在完善地停止所要的程式之後,指令碼會將查核點檔案平行上傳至 Cloud Storage 值區。#!/bin/bash MY_PROGRAM="PROGRAM_NAME" # For example, "apache2" or "nginx" MY_USER="LOCAL_USER" CHECKPOINT="/home/$MY_USER/checkpoint.out" BUCKET_NAME="BUCKET_NAME" # For example, "my-checkpoint-files" (without gs://) echo "Shutting down! Seeing if ${MY_PROGRAM} is running." # Find the newest copy of $MY_PROGRAM PID="$(pgrep -n "$MY_PROGRAM")" if [[ "$?" -ne 0 ]]; then echo "${MY_PROGRAM} not running, shutting down immediately." exit 0 fi echo "Sending SIGINT to $PID" kill -2 "$PID" # Portable waitpid equivalent while kill -0 "$PID"; do sleep 1 done echo "$PID is done, copying ${CHECKPOINT} to gs://${BUCKET_NAME} as ${MY_USER}" su "${MY_USER}" -c "gcloud storage cp $CHECKPOINT gs://${BUCKET_NAME}/" echo "Done uploading, shutting down."
這個指令碼假設:
如要將這個指令碼新增至 VM,請設定指令碼,使其能與 VM 上的應用程式搭配使用,並將它新增至 VM 的中繼資料。
偵測 Spot VM 先占
使用 Google Cloud console、gcloud CLI 或 Compute Engine API,判斷 Compute Engine 是否先占了 Spot VM。
主控台
您可以查看系統活動記錄,確認 VM 是否遭到先占。
gcloud
使用
gcloud compute operations list
指令搭配 filter 參數,取得專案的先占事件清單。gcloud compute operations list \ --filter="operationType=compute.instances.preempted"
或者,您也可以使用其他篩選參數進一步指定結果範圍。舉例來說,如果只想查看代管執行個體群組中的執行個體先占事件,請使用下列指令:
gcloud compute operations list \ --filter="operationType=compute.instances.preempted AND targetLink:instances/BASE_INSTANCE_NAME"
其中
BASE_INSTANCE_NAME
是指定為這個代管執行個體群組中所有 VM 名稱前置字串的基準名稱。輸出結果會與下列內容相似:
NAME TYPE TARGET HTTP_STATUS STATUS TIMESTAMP systemevent-xxxxxxxx compute.instances.preempted us-central1-f/instances/example-instance-xxx 200 DONE 2015-04-02T12:12:10.881-07:00
compute.instances.preempted
作業類型代表 VM 執行個體遭到先占。您可以使用gcloud compute operations describe
指令取得特定先占作業的相關詳細資訊。gcloud compute operations describe SYSTEM_EVENT \ --zone=ZONE
更改下列內容:
輸出結果會與下列內容相似:
... operationType: compute.instances.preempted progress: 100 selfLink: https://compute.googleapis.com/compute/v1/projects/my-project/zones/us-central1-f/operations/systemevent-xxxxxxxx startTime: '2015-04-02T12:12:10.881-07:00' status: DONE statusMessage: Instance was preempted. ...
REST
如要取得特定專案和區域的近期系統作業清單,請使用
zoneOperations.get
方法。GET https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/operations
更改下列內容:
如要將回應範圍限制為僅顯示先佔運作,您可以在 API 要求中新增篩選條件:
operationType="compute.instances.preempted"
或者,如要查看特定 VM 的先佔作業,請將
targetLink
參數新增到篩選條件:operationType="compute.instances.preempted" AND targetLink="https://www.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/VM_NAME
請替換下列項目: +
PROJECT_ID
:專案 ID。 +ZONE
:區域。 +VM_NAME
:這個可用區和專案中的特定 VM 名稱。回應會包含近期運算的清單。舉例來說,先占看起來類似下列內容:
{ "kind": "compute#operation", "id": "15041793718812375371", "name": "systemevent-xxxxxxxx", "zone": "https://www.googleapis.com/compute/v1/projects/my-project/zones/us-central1-f", "operationType": "compute.instances.preempted", "targetLink": "https://www.googleapis.com/compute/v1/projects/my-project/zones/us-central1-f/instances/example-instance", "targetId": "12820389800990687210", "status": "DONE", "statusMessage": "Instance was preempted.", ... }
或者,您也可以從 VM 內部判斷 VM 是否遭到先占。如果您想在關機指令碼中,以與一般關機不同的方式處理因 Compute Engine 先占導致的關機情形,此方法很實用。只要在 VM 的預設中繼資料中,查看中繼資料伺服器是否有
preempted
值即可判斷。例如,從 VM 內使用
curl
來取得preempted
的值:curl "http://metadata.google.internal/computeMetadata/v1/instance/preempted" -H "Metadata-Flavor: Google" TRUE
若這個值為
TRUE
,則 VM 遭到 Compute Engine 先占,否則此值會是FALSE
。如果您想在關閉指令碼以外的地方使用它,請將
?wait_for_change=true
附加至網址。這會執行等待 HTTP GET 要求,而該要求只會在 VM 的中繼資料變更,且 VM 遭到先占時傳回。curl "http://metadata.google.internal/computeMetadata/v1/instance/preempted?wait_for_change=true" -H "Metadata-Flavor: Google" TRUE
測試先占設定
您可在 VM 上執行模擬維護作業,以強制先占這些 VM。使用這項功能可測試應用程式處理 Spot VM 的方式。請參閱「模擬主機維護事件」一節,瞭解如何在執行個體上測試維護作業。
您也可以停止 VM 執行個體,藉以模擬 VM 先占行為,這個模擬操作可用來取代模擬維護作業,並避免超過配額限制。
最佳做法
以下列舉幾項最佳做法,協助您充分發揮 Spot VM 的效用。
後續步驟
除非另有註明,否則本頁面中的內容是採用創用 CC 姓名標示 4.0 授權,程式碼範例則為阿帕契 2.0 授權。詳情請參閱《Google Developers 網站政策》。Java 是 Oracle 和/或其關聯企業的註冊商標。
上次更新時間:2025-07-14 (世界標準時間)。
-