建立和啟動先佔 VM 執行個體

本頁面說明如何建立及使用先佔虛擬機器 (VM) 執行個體。先佔執行個體是您可利用遠低於一般執行個體的價格建立及執行的執行個體。不過如果 Compute Engine 需要存取其他工作的資源,可能會終止 (先佔) 這些執行個體。先佔執行個體一律會在 24 小時之後終止。 如要進一步瞭解先佔執行個體,請參閱先佔執行個體說明文件。

建議僅針對能承受執行個體先佔影響的容錯應用程式使用先佔執行個體。在您決定建立先佔執行個體之前,請務必確保您的應用程式可以處理先佔。 如要瞭解先佔執行個體的風險與價值,請參閱先佔執行個體說明文件。

事前準備

建立先佔執行個體

透過 Google Cloud Platform 主控台gcloud 工具API 建立先佔執行個體。

主控台

建立先佔執行個體與建立一般執行個體的程序相同,但您要啟用 preemptible 屬性。

gcloud

透過 gcloud compute,使用與您用來建立一般執行個體相同的 instances create 指令,但要新增 --preemptible 標記。

gcloud compute instances create [INSTANCE_NAME] --preemptible

其中的 [INSTANCE_NAME] 是執行個體的名稱。

API

在 API 中,建構一般要求來建立執行個體,但要在 scheduling 下納入 preemptible 屬性並將這個屬性設定為 true。例如:

POST https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/[ZONE]/instances

{
  'machineType': 'zones/[ZONE]/machineTypes/[MACHINE_TYPE]',
  'name': '[INSTANCE_NAME]',
  'scheduling':
  {
    'preemptible': true
  },
  ...
}

先佔 CPU 配額

先佔執行個體像一般執行個體一樣,需要可用的 CPU 配額。為避免先佔執行個體使用到一般執行個體的 CPU 配額,您可以要求特別的「先佔 CPU」配額。當 Compute Engine 在該地區授予您先佔 CPU 配額後,所有先佔執行個體都將計入這個配額。所有一般執行個體都將持續使用一般 CPU 配額。

在您沒有先佔 CPU 配額的地區,可以使用一般 CPU 配額來啟動先佔執行個體。您也照常需要足夠的 IP 與磁碟配額。除非 Compute Engine 已授予配額,否則先佔 CPU 配額不會出現在 gcloud 工具或 GCP 主控台配額頁面中。

如要進一步瞭解配額的相關資訊,請造訪資源配額頁面

使用關閉指令碼處理先佔

當您的執行個體遭到先佔時,您可以使用關閉指令碼,在執行個體停止之前執行清除動作。例如,您可以順利終止運作中的程序,並將檢查點檔案複製到 Google Cloud Storage

下面是您可以新增至執行中先佔執行個體或在建立新先佔執行個體時新增的關閉指令碼。這個指令碼會在執行個體開始關閉時,作業系統的一般 kill 指令終止所有剩餘程序之前執行。在順利終止需要的程式之後,指令碼會將檢查點檔案平行上傳至 Google Cloud Storage 值區。

#!/bin/bash

MY_PROGRAM="[PROGRAM_NAME]" # For example, "apache2" or "nginx"
MY_USER="[LOCAL_USERNAME]"
CHECKPOINT="/home/$MY_USER/checkpoint.out"
GSUTIL_OPTS="-m -o GSUtil:parallel_composite_upload_threshold=32M"
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 "gsutil $GSUTIL_OPTS cp $CHECKPOINT gs://${BUCKET_NAME}/"

echo "Done uploading, shutting down."

如要將這個指令碼新增至執行個體,請設定指令碼以與執行個體上的應用程式搭配使用,並將它新增至您的執行個體中繼資料。

  1. 關閉指令碼複製或下載到您的本機工作站。
  2. 開啟檔案以編輯並變更下列變數:
    • [PROGRAM_NAME] 是您要關閉之程序或程式的名稱。例如,apache2nginx
    • [LOCAL_USER] 是您以其身分登入虛擬機器的使用者名稱。
    • [BUCKET_NAME] 是您想儲存程式檢查點檔案之 Google Cloud Storage 值區的名稱。請注意,本例中的值區名稱開頭不是 gs://
  3. 儲存變更。
  4. 將關閉指令碼新增至新的執行個體現有執行個體

這個指令碼假設:

  • 已建立至少具備 Google Cloud Storage 讀取/寫入權限的執行個體。如需如何建立適當範圍執行個體的操作說明,請參閱驗證說明文件

  • 您具備現有 Google Cloud Storage 值區及其寫入權限。

檢查執行個體是否為先佔

您可以使用 GCP 主控台gcloud 工具API,檢查是否已將執行個體設定為先佔。

主控台


請查看執行個體屬性,藉此檢查執行個體是否為先佔。

  1. 前往 VM 執行個體頁面。

    前往 VM 執行個體頁面

  2. 選取您的專案並點選 [繼續]
  3. 按一下您要檢查的執行個體名稱。這個動作會開啟執行個體詳細資料頁面。
  4. 先佔狀態是在執行個體詳細資料的「Availability policies」(可用性政策) 部分進行指定。

gcloud


gcloud compute 中,使用 instances describe 取得執行個體的相關資訊,其中包括執行個體是否為先佔。

gcloud compute instances describe [INSTANCE_NAME]

其中的 [INSTANCE_NAME] 是執行個體的名稱。

回應資訊會在排程部分中包含先佔狀態。

...
scheduling:
  automaticRestart: false
  onHostMaintenance: TERMINATE
  preemptible: true
...

API


如要檢查執行個體是否為先佔,請使用 API 將 GET 要求傳送至執行個體的 URI。

GET https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/[ZONE]/instances/[INSTANCE_NAME]

回應資訊會在 scheduling 下包含先佔狀態。

{
    "kind": "compute#instance",
    "id": "4468501694759003918",
    "creationTimestamp": "2015-04-15T15:40:59.004-07:00",
    "zone": "https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/us-central1-f",
    "status": "RUNNING",
    "name": "example-instance",
    "scheduling":
    {
       "preemptible": true
    },
    ...
 }

或者,您也可以從執行個體本身判斷執行個體是否為先佔。只要在執行個體的預設執行個體中繼資料中,檢查中繼資料伺服器是否有 scheduling/preemptible 值即可判斷。

例如,從執行個體內使用 curl 來取得 scheduling/preemptible 的值:

curl "http://metadata.google.internal/computeMetadata/v1/instance/scheduling/preemptible" -H "Metadata-Flavor: Google"
TRUE

若這個值為 TRUE,則執行個體為先佔。

偵測執行個體是否遭到先佔

使用 Google Cloud Platform 主控台gcloud 工具API,偵測執行個體是否遭到先佔。

主控台


您可以透過檢查系統活動記錄,來檢查執行個體是否遭到先佔。

  1. 前往「Logs」(記錄檔) 頁面。

    前往記錄頁面

  2. 選取您的專案並按一下 [Continue] (繼續)
  3. compute.instances.preempted 新增至 [filter by label or text search] (按標籤或搜尋字詞篩選) 欄位。
  4. 或者,如果您想查看特定執行個體的先佔運算,也可以輸入執行個體名稱。
  5. 按下 Enter 鍵,套用指定篩選器。GCP 主控台會將記錄清單更新為僅顯示執行個體遭到先佔的運算。
  6. 選取清單中的運算,查看遭到先佔之執行個體的相關詳細資料。

gcloud


使用 gcloud compute operations list 指令搭配 filter 參數來取得專案內的先佔事件清單。

gcloud compute operations list \
    --filter="operationType=compute.instances.preempted"

您可以使用 filter 參數進一步指定結果範圍。舉例來說,如果只想查看代管執行個體群組中的執行個體先佔事件,即可運用這個參數來篩選:

gcloud compute operations list \
    --filter="operationType=compute.instances.preempted AND targetLink:instances/[BASE_INSTANCE_NAME]"

gcloud 會傳回類似以下的回應:

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 運算類型代表執行個體遭到先佔。您可以使用 operations describe 指令取得特定先佔運算的相關詳細資訊。

gcloud compute operations describe \
    systemevent-xxxxxxxx

gcloud 會傳回類似以下的回應:

...
operationType: compute.instances.preempted
progress: 100
selfLink: https://www.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.
...

API


如要取得最近的系統作業清單,請傳送 GET 要求至區域作業 URI。

GET https://www.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-instance",
  "targetId": "12820389800990687210",
  "status": "DONE",
  "statusMessage": "Instance was preempted.",
  ...
}

如要將回應範圍限制為僅顯示先佔運作,您可以在 API 要求中新增篩選條件:operationType="compute.instances.preempted"。如要查看特定執行個體的先佔運作,請將 targetLink 參數新增到篩選條件:operationType="compute.instances.preempted" AND targetLink="https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/[ZONE]/instances/[INSTANCE_NAME]"

或者,您也可以從執行個體本身判斷執行個體是否遭到先佔。如果您想在關閉指令碼中,以與一般關閉不同的方式處理因 Compute Engine 先佔導致的關閉情形,這會很實用。只要在執行個體的預設執行個體中繼資料中,檢查中繼資料伺服器是否有 preempted 值即可判斷。

例如,從執行個體內使用 curl 來取得 preempted 的值:

curl "http://metadata.google.internal/computeMetadata/v1/instance/preempted" -H "Metadata-Flavor: Google"
TRUE

若這個值為 TRUE,則執行個體遭到 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 執行個體的資源來自於額外與備份的 Google Cloud Platform 容量。相較於較大的機器類型,取得較小機器類型的大量先佔容量通常會比較簡單。擁有 32 個以下核心之較小機器類型的先佔率,一直以來也都低於較大機器類型的先佔率。

您也可以透過使用介於預先定義類型之間的自訂機器類型,來獲得更多的備用容量。例如,擁有 48 個 vCPU 的自訂機器類型可能比 n1-standard-64s 擁有更多容量。

在離峰時段執行大型先佔 VM 叢集

Google Cloud Platform 資料中心的負載會因位置與時段而有所不同,但通常夜晚與週末的負載最低。因此,夜晚與週末最適合執行大型先佔 VM 叢集。

將應用程式設計為容錯與容忍先佔

由於先佔模式在不同時間點會發生變更,因此針對這一情況做好準備非常重要。例如,如果區域發生部分中斷,大量先佔執行個體可能會遭到先佔,來為必須做為復原一部分移動的一般執行個體騰出空間。在這短暫的時間內,先佔率看起來與其他任何日期的先佔率非常不同。如果您的應用程式假設先佔一律會在小規模群組中執行,您可能無法針對這類事件做好準備。您可以停止 VM 執行個體來測試應用程式在先佔事件下的行為。

重試建立已遭到先佔的執行個體

如果您已遭到先佔,建議先重試一或兩次先佔執行個體,再恢復至一般執行個體。根據您的需求,建議將叢集中的一般與先佔執行個體結合起來,確保工作能夠按照適當的步調繼續執行。

使用關閉指令碼

使用關閉指令碼管理關閉與先佔通知,能夠儲存工作進度以接續上次進度,而不用從頭開始。

後續步驟

本頁內容對您是否有任何幫助?請提供意見:

傳送您對下列選項的寶貴意見...

這個網頁
Compute Engine 說明文件