本頁面說明如何建立及管理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 之前,請務必確保您的應用程式可以處理先占。
事前準備
- 請參閱 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.
Terraform
To use the Terraform samples on this page in a local development environment, install and initialize the gcloud CLI, and then set up Application Default Credentials with your user credentials.
- 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.
For more information, see Set up authentication for a local development environment.
REST
To use the REST API samples on this page in a local development environment, you use the credentials you provide to the 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.
For more information, see Authenticate for using REST in the Google Cloud authentication documentation.
-
建立 Spot VM
使用 Google Cloud 控制台、gcloud CLI 或 Compute Engine API 建立 Spot VM。Spot VM 是指任何已設定為使用 Spot 佈建模式的 VM:
- 在 Google Cloud 控制台中將「VM 佈建模式」設為「Spot」
- gcloud CLI 中的
--provisioning-model=SPOT
- Compute Engine API 中的
"provisioningModel": "SPOT"
主控台
前往 Google Cloud 控制台的「Create an instance」(建立執行個體) 頁面。
在導覽選單中,按一下「進階」。在隨即顯示的「Advanced」窗格中,完成下列步驟:
- 在「Provisioning model」(佈建模型) 部分,從「VM provisioning model」(VM 佈建模型) 清單中選取「Spot」。
選用:如要選取 Compute Engine 搶先取得 VM 時發生的終止動作,請完成下列步驟:
- 展開「VM 佈建模式進階設定」部分。
- 在「On VM termination」清單中,選取下列其中一個選項:
- 如要在先佔期間停止 VM,請選取「停止」 (預設)。
- 如要在優先取得期間刪除 VM,請選取「刪除」。
選用:指定其他設定選項。詳情請參閱「建立執行個體時的設定選項」。
如要建立並啟動 VM,請按一下 [Create] (建立)。
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_NAME
:新 VM 的名稱。TERMINATION_ACTION
:選用:指定 Compute Engine 在先占 VM 時採取的動作,可選為STOP
(預設行為) 或DELETE
。
如要進一步瞭解建立 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
更改下列內容:
VM_NAME
:新 VM 的名稱。IMAGE
:指定下列任一值:IMAGE
:公開圖片或圖片系列的特定版本。例如特定圖片為--image=debian-10-buster-v20200309
。- 映像檔系列。這會從最新的未淘汰作業系統映像檔建立 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
。如要取得區域中可用的機器類型清單,請搭配
--zones
標記使用gcloud compute machine-types list
指令。
Terraform
您可以使用 Terraform 資源,透過排程區塊建立短期執行個體
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" }, ... }
更改下列內容:
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
。 - 映像檔系列。這會從最新的未淘汰作業系統映像檔建立 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 時可指定的選項,請參閱「執行個體建立期間的設定選項」。
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 是標準 VM、Spot VM 還是先占 VM。對於 Spot VM,您也可以指定終止動作。您可以使用 Google Cloud 控制台、gcloud CLI 或 Compute Engine API 來判斷 VM 的佈建模型和終止動作。
主控台
前往「VM instances」(VM 執行個體) 頁面。
按一下要識別的 VM 的「名稱」,「VM instance details」(VM 執行個體詳細資料) 頁面隨即開啟。
前往頁面底部的「管理」部分。在「可用性政策」子區段中,勾選下列選項:
- 如果 VM 佈建模式設為 Spot,則該 VM 為 Spot VM。
- 「On VM termination」會指出 Compute Engine 在先占 VM 時採取的動作,可選擇「Stop」或「Delete」 VM。
- 否則,如果 VM 佈建模式設為「標準」或「-」:
- 如果「Preemptibility」選項設為「On」,則 VM 為先占 VM。
- 否則,VM 就是標準 VM。
- 如果 VM 佈建模式設為 Spot,則該 VM 為 Spot VM。
gcloud
如要透過 gcloud CLI 描述 VM,請使用 gcloud compute instances describe
指令:
gcloud compute instances describe VM_NAME
其中 VM_NAME
是您要檢查的 VM 名稱。
在輸出內容中,檢查 scheduling
欄位來識別 VM:
如果輸出內容包含
provisioningModel
欄位,且已設為SPOT
(類似於以下範例),表示 VM 為 Spot VM。... scheduling: ... provisioningModel: SPOT instanceTerminationAction: TERMINATION_ACTION ...
其中
TERMINATION_ACTION
表示 Compute Engine 先占 VM 時要採取的動作,可停止 (STOP
) 或刪除 (DELETE
) VM。如果缺少instanceTerminationAction
欄位,則預設值為STOP
。否則,如果輸出內容包含設為
standard
的provisioningModel
欄位,或是輸出內容省略provisioningModel
欄位:- 如果輸出內容包含
preemptible
欄位,且已設為true
,表示 VM 為可先占的 VM。 - 否則,VM 就是標準 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:
如果輸出內容包含
provisioningModel
欄位,且已設為SPOT
(類似於以下範例),表示 VM 為 Spot VM。{ ... "scheduling": { ... "provisioningModel": "SPOT", "instanceTerminationAction": "TERMINATION_ACTION" ... }, ... }
其中
TERMINATION_ACTION
表示 Compute Engine 先占 VM 時要採取的動作,可停止 (STOP
) 或刪除 (DELETE
) VM。如果缺少instanceTerminationAction
欄位,則預設值為STOP
。否則,如果輸出內容包含設為
standard
的provisioningModel
欄位,或是輸出內容省略provisioningModel
欄位:- 如果輸出內容包含
preemptible
欄位,且已設為true
,表示 VM 為可先占的 VM。 - 否則,VM 就是標準 VM。
- 如果輸出內容包含
Go
Java
Python
管理 Spot VM 的先占
如要瞭解如何管理 Spot VM 的預取權,請參閱下列章節:
使用關閉指令碼處理先占
當 Compute Engine 先占 Spot VM 時,您可以使用關機指令碼,在 VM 先占前嘗試執行清理動作。例如,您可以完善地停止運作中的程序,並將查核點檔案複製到 Cloud Storage。值得注意的是,預先中斷通知的關機期間最長時間,比使用者啟動的關機時間短。如要進一步瞭解先占通知的關機期間,請參閱 Spot VM 概念說明文件中的先占程序。
以下是關閉指令碼範例,您可以將其新增至執行中的 Spot VM,或在建立新 Spot 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."
這個指令碼假設:
已建立至少具備 Cloud Storage 讀取/寫入權限的 VM。如需建立具有適當範圍的 VM 操作說明,請參閱驗證說明文件。
您有現有的 Cloud Storage 值區並有權限對其進行寫入。
如要將這個指令碼新增至 VM,請設定指令碼,使其能與 VM 上的應用程式搭配使用,並將它新增至 VM 的中繼資料。
複製或下載關機指令碼:
複製上述關機指令碼,並替換下列項目:
PROGRAM_NAME
是您要關閉的程序或程式名稱。例如apache2
或nginx
。LOCAL_USER
是您以其身分登入虛擬機器的使用者名稱。BUCKET_NAME
是您想儲存程式檢查點檔案之 Cloud Storage 值區的名稱。請注意,本例中的值區名稱開頭不是gs://
。
下載關閉指令碼到本機工作站,然後在檔案中取代下列變數:
[PROGRAM_NAME]
是您要關閉之程序或程式的名稱。例如apache2
或nginx
。[LOCAL_USER]
是您以其身分登入虛擬機器的使用者名稱。[BUCKET_NAME]
是您想儲存程式查核點檔案之 Cloud Storage 值區的名稱。請注意,本例中的值區名稱開頭不是gs://
。
偵測 Spot VM 先占
使用 Google Cloud 控制台、gcloud CLI 或 Compute Engine API,判斷 Compute Engine 是否已先占 Spot VM。
主控台
您可以查看系統活動記錄,檢查 VM 是否遭到先占。
前往 Google Cloud 控制台的「Logs」頁面。
選取您的專案並點選 [繼續]。
將
compute.instances.preempted
新增至 [filter by label or text search] (按標籤或搜尋字詞篩選) 欄位。或者,如果您想查看特定 VM 的先占作業,也可以輸入 VM 名稱。
按下 Enter 鍵,套用指定篩選器。Google Cloud 控制台會將記錄清單更新為僅顯示 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
更改下列內容:
SYSTEM_EVENT
:來自gcloud compute operations list
指令輸出的系統事件,例如systemevent-xxxxxxxx
。ZONE
:系統事件的區域,例如us-central1-f
。
輸出結果會與下列內容相似:
... 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 要求,而該要求只會在中繼資料變更,且執行個體遭到先占時傳回。
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 的效用。
使用執行個體範本。您可以使用執行個體範本建立多個具有相同屬性的 Spot VM,而非一次建立一個。使用 MIG 時,必須選取執行個體範本。或者,您也可以使用大量執行個體 API 建立多個 Spot VM。
使用 MIG 在地區層級發布及自動重新建立 Spot VM。使用 MIG,讓 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。