本頁面說明如何建立及使用先占虛擬機器 (VM) 執行個體。與標準 VM 價格相比,先占 VM 提供 60% 至 91% 的折扣優惠。不過,如果 Compute Engine 需要回收這些資源來執行其他工作,可能會停止 (先占) 這些 VM。先占 VM 一律會在 24 小時後停止。建議僅針對能承受 VM 搶佔影響的容錯應用程式使用先占 VM。決定建立可先占 VM 之前,請務必確保您的應用程式可以處理先占。如要瞭解使用先占 VM 的風險與好處,請參閱先占 VM 執行個體說明文件。
事前準備
- 閱讀先占 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.
Go
To use the Go 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.
Java
To use the Java 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.
Node.js
To use the Node.js 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.
Python
To use the Python 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.
-
建立先占 VM
使用 gcloud CLI 或 Compute Engine API 建立可搶佔的 VM。如要使用 Google Cloud 控制台,請改為建立 Spot VM。
gcloud
透過 gcloud compute
,使用與您用來建立一般 VM 相同的 instances create
指令,但要加上 --preemptible
旗標。
gcloud compute instances create [VM_NAME] --preemptible
其中 [VM_NAME]
是 VM 的名稱。
Go
Java
Node.js
Python
REST
請在 API 中建構一個建立 VM的一般要求,但要在 scheduling
下方加上 preemptible
屬性,並把該屬性設為 true
。例如:
POST https://compute.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/[ZONE]/instances
{
'machineType': 'zones/[ZONE]/machineTypes/[MACHINE_TYPE]',
'name': '[INSTANCE_NAME]',
'scheduling':
{
'preemptible': true
},
...
}
先占 CPU 配額
先占 VM 像標準 VM 一樣,需有可用的 CPU 配額。為避免先占 VM 耗用標準 VM 的 CPU 配額,您可以要求特別的「先占 CPU」配額。當 Compute Engine 授予您該地區的先占 CPU 配額後,所有先占 VM 都會計入該配額,而所有標準 VM 則會繼續計入標準 CPU 配額。
在未提供先占 CPU 配額的地區,您可以使用標準 CPU 配額啟用先占 VM。跟平常一樣,您也需有足夠的 IP 與磁碟配額。除非 Compute Engine 已授予配額,否則先占 CPU 配額不會出現在 gcloud CLI 或 Google Cloud 控制台配額頁面中。
如要進一步瞭解配額的相關資訊,請造訪資源配額頁面。
啟動先佔 VM
與其他 VM 一樣,如果先占 VM 已停止或先占,您可以再次啟動 VM,並將其恢復為 RUNNING
狀態。啟動先占 VM 會重設 24 小時計數器,但由於仍是先占 VM,Compute Engine 可以在 24 小時前先佔。在先占型 VM 執行期間,無法將其轉換為標準 VM。
如果 Compute Engine 在自動調度資源的代管執行個體群組 (MIG) 或 Google Kubernetes Engine (GKE) 叢集中,停止先占 VM,則群組會在資源再次可用時重新啟動 VM。
使用關閉指令碼處理先占
當 Compute Engine 先占 VM 時,您可以使用關機指令碼,在 VM 先占前嘗試執行清理動作。例如,您可以完善地停止運作中的程序,並將查核點檔案複製到 Cloud Storage。值得注意的是,預先中斷通知的關機期間最長時間,比使用者啟動的關機時間短。如要進一步瞭解優先處理通知的關閉期間,請參閱概念說明文件中的「優先處理程序」。
以下是您可以新增至執行中先占 VM 或在建立新先占 VM 時新增的關閉指令碼。這個指令碼的執行時機是執行個體開始關閉時,且作業系統的一般 kill
指令終止所有剩餘程序之前。在完善地停止所需程式之後,指令碼會將查核點檔案平行上傳至 Cloud Storage 值區。
#!/bin/bash
MY_PROGRAM="[PROGRAM_NAME]" # For example, "apache2" or "nginx"
MY_USER="[LOCAL_USERNAME]"
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 的中繼資料。
- 將關閉指令碼複製或下載到您的本機工作站。
- 開啟檔案以編輯並變更下列變數:
[PROGRAM_NAME]
是您要關閉之程序或程式的名稱。例如apache2
或nginx
。[LOCAL_USER]
是您以其身分登入虛擬機器的使用者名稱。[BUCKET_NAME]
是您想儲存程式查核點檔案之 Cloud Storage 值區的名稱。請注意,本例中的值區名稱開頭不是gs://
。
- 儲存變更。
- 將關閉指令碼新增至新的 VM或現有的 VM。
這個指令碼假設:
已建立至少具備 Cloud Storage 讀取/寫入權限的 VM。如需建立具有適當範圍的 VM 操作說明,請參閱驗證說明文件。
您有現有的 Cloud Storage 值區並有權限對其進行寫入。
找出先占 VM
如要檢查 VM 是否為先占 VM,請按照這篇文章的步驟操作,找出 VM 的佈建模型和終止動作。
判斷是否先佔了 VM
請使用 Google Cloud 控制台、gcloud CLI 或 API 來判斷 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"
您可以使用 filter 參數進一步指定結果範圍。舉例來說,如果只想查看代管執行個體群組中的 VM 先占事件,即可按照以下方設定參數:
gcloud compute operations list \
--filter="operationType=compute.instances.preempted AND targetLink:instances/[BASE_VM_NAME]"
gcloud
會傳回類似以下內容的回應:
NAME TYPE TARGET HTTP_STATUS STATUS TIMESTAMP systemevent-xxxxxxxx compute.instances.preempted us-central1-f/instances/example-vm-xxx 200 DONE 2015-04-02T12:12:10.881-07:00
compute.instances.preempted
作業類型代表 VM 遭到先占。您可以使用 operations describe
指令取得特定先占作業的相關詳細資訊。
gcloud compute operations describe \
systemevent-xxxxxxxx
gcloud
會傳回類似以下內容的回應:
... operationType: compute.instances.preempted progress: 100 selfLink: https://compute.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/us-central1-f/operations/systemevent-xxxxxxxx startTime: '2015-04-02T12:12:10.881-07:00' status: DONE statusMessage: Instance was preempted. ...
REST
如要取得最近的系統作業清單,請傳送 GET
要求至區域作業 URI。
GET https://compute.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/[ZONE]/operations
回應會包含近期作業的清單。
{ "kind": "compute#operation", "id": "15041793718812375371", "name": "systemevent-xxxxxxxx", "zone": "https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/us-central1-f", "operationType": "compute.instances.preempted", "targetLink": "https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/us-central1-f/instances/example-vm", "targetId": "12820389800990687210", "status": "DONE", "statusMessage": "Instance was preempted.", ... }
如要將回應範圍限制為僅顯示先占作業,您可以在 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]"
。
或者,您也可以從 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。使用這項功能可測試應用程式處理先占 VM 的方式。請參閱測試可用性政策一節,瞭解如何在 VM 上測試維護作業。
您也可以停止 VM,藉以模擬 VM 先占行為,這個模擬操作可用來取代模擬維護作業,並避免超過配額限制。
最佳做法
以下是可協助您善用先佔 VM 執行個體的幾個最佳做法。
使用大量執行個體 API
您可以使用大量執行個體 API,而非建立單一 VM。
挑選較小的機器類型
先占 VM 的資源來自多餘和備份 Google Cloud容量。較小的機器類型通常較容易取得容量,也就是說,較小的機器類型指的是具備較少 vCPU 和記憶體等資源的機器類型。您可以選取較小的自訂機器類型,為先占 VM 提供更多容量,但較小的預先定義機器類型更有可能提供容量。舉例來說,與 n2-standard-32
預先定義機器類型的容量相比,n2-custom-24-96
自訂機器類型的容量更有可能達到,但 n2-standard-16
預先定義機器類型的容量更有可能達到。
在離峰時段執行大型先占 VM 叢集
Google Cloud 資料中心的負載量會因地點和時段而異,但通常在夜間和週末時最低。因此,夜晚與週末最適合執行大型先佔 VM 叢集。
將應用程式設計為容錯且能承受先占
請務必做好準備,以因應不同時間點的優先順序模式變更。舉例來說,如果某個區域發生部分停機情形,大量可先占的 VM 就會遭到先占,以便為需要遷移的標準 VM 騰出空間,以便進行復原作業。在這短暫的時間內,先佔率看起來與其他任何日期的先佔率非常不同。如果應用程式假設預取作業一律以小群組執行,您可能無法為這類事件做好準備。您可以停止 VM 執行個體來測試應用程式在先佔事件下的行為。
再次嘗試建立已遭先占的 VM
如果您的 VM 執行個體已遭到先占,請先嘗試建立新的先占 VM 一兩次,再退而求其次使用標準 VM。視您的需求為何,可以考慮混合使用叢集中的標準與可先占 VM,以確保工作能夠按照適當的速度進行。
使用關閉指令碼
使用關閉指令碼管理關閉與先佔通知,能夠儲存工作進度以接續上次進度,而不用從頭開始。
後續步驟
- 參閱先佔 VM 執行個體說明文件。
- 瞭解關閉指令碼。
- 連線至 VM。