執行開機指令碼

請在虛擬機器上建立並執行自己的開機指令碼,以便在每次執行個體啟動時執行自動化工作。開機指令碼可以執行許多動作,例如安裝軟體、執行更新、開啟服務及在指令碼中定義的其他任何工作。您可以使用開機指令碼輕鬆地以程式方式自訂虛擬機器執行個體,包括在建立時的新執行個體上。

例如,安裝及啟動 Apache 伺服器的一個簡單開機指令碼看起來可能像這樣:

#! /bin/bash
apt-get update
apt-get install -y apache2
cat <<EOF > /var/www/html/index.html
<html><body><h1>Hello World</h1>
<p>This page was created from a simple startup script!</p>
</body></html>
EOF

開機指令碼使用開機指令碼中繼資料鍵值透過中繼資料伺服器指定。您可以使用 gcloud 指令列工具、API 或 Google Cloud Platform 主控台提供開機指令碼。

事前準備

這項工作需要的權限

如要執行這項工作,您必須具備以下權限

開機指令碼執行

執行個體一律會在網路可用之後,以根權限執行開機指令碼。

開機指令碼可以是任何檔案類型。如果有開機指令碼,Compute Engine 將執行以下操作:

  1. 將開機指令碼複製到執行個體的本機檔案。
  2. 設定檔案的權限並將它設為可執行。
  3. 執行檔案。

例如,您可以提供 Python 指令碼而不是 Bash 指令碼。請注意,Compute Engine 會確實地執行指令碼,無論其類型為何。

如要執行非 Bash 指令碼,請在檔案頂端新增一個工作行,讓作業系統知道要使用哪個解譯器。舉例來說,您可以針對 Python 指令碼新增如下的工作行:

#! /usr/bin/python

使用本機開機指令碼

本機開機指令碼是本機電腦上的指令碼。如要使用本機開機指令碼,請傳入本機開機指令碼檔案或將開機指令碼的內容直接提供給中繼資料伺服器。以下幾小節中的範例會示範如何以本機檔案或是直接輸入的方式新增開機指令碼中繼資料。

本機開機指令碼受限於中繼資料值的 256 KB 長度限制。如果您的開機指令碼超過此限制,您將無法在本機載入它。請改為將檔案儲存至 Google Cloud Storage 並於建立執行個體時指定指令碼網址。詳情請參閱使用儲存在 Cloud Storage 的開機指令碼一文。

提供開機指令碼檔案

您只能透過 gcloud 指令列工具傳入本機開機指令碼檔案。

如要傳入本機開機指令碼檔案,請使用 gcloud 指令列工具並提供 --metadata-from-file 標記,後面加上中繼資料鍵值組合 startup-script=PATH/TO/FILE,其中 PATH/TO/FILE 是開機指令碼的相對路徑:

gcloud compute instances create example-instance \
    --metadata-from-file startup-script=examples/scripts/install.sh

直接提供開機指令碼內容

或者您也可以使用主控台、gcloud 指令列工具或是 API 直接輸入或貼上您的開機指令碼內容。

主控台

在 GCP 主控台,直接在「開機指令碼」部分指定開機指令碼:

  1. 在 GCP 主控台中,前往「VM Instances」(VM 執行個體) 頁面。

    前往 VM 執行個體頁面

  2. 按一下 [建立執行個體]
  3. 在「Create a new instance」 (建立新執行個體) 頁面上,填入您要為執行個體 設定的屬性。 如需進階設定選項,請展開「管理、安全性、磁碟、網路、單獨租用」區段。
  4. 在「自動」專區的「開機指令碼」下方提供您的開機指令碼內容。

    在 GCP 主控台中設定開機指令碼的螢幕擷取畫面

  5. 按一下 [Create] (建立) 來建立執行個體。

gcloud

透過 gcloud 指令列工具,使用 startup-script=[CONTENTS] 金鑰組指定 --metadata 標記以提供開機指令碼內容,其中 [CONTENTS] 是您的開機指令碼內容。

舉例來說,下列指令會執行個體,在開機時執行某些系統更新、安裝 Apache 及啟動單一網頁。您可以執行此指令,然後造訪執行個體的外部 IP,查看 index.html 頁面的內容。

在 Linux 桌面上,執行類似以下這樣的指令:

gcloud compute instances create example-instance --tags http-server \
--metadata startup-script='#! /bin/bash
# Installs apache and a custom homepage
sudo su -
apt-get update
apt-get install -y apache2
cat <<EOF > /var/www/html/index.html
<html><body><h1>Hello World</h1>
<p>This page was created from a simple start up script!</p>
</body></html>
EOF'

如果您使用 Windows 桌面,可在 cmd 終端機上執行此指令:

gcloud compute instances create example-instance --tags http-server --metadata startup-script="
apt-get update;
apt-get install -y apache2;
echo \"This page was created from a simple start up script!\" ^> /var/www/html/index.html"

同樣的,如果您正在使用 Powershell,可以使用 --% 標記執行此指令,將確切指令傳入 gcloud 工具:

gcloud --% compute instances create example-instance --tags http-server --metadata startup-script="
apt-get update;
apt-get install -y apache2;
echo \"This page was created from a simple start up script!\" ^> /var/www/html/index.html"

API

在 API 中,使用 startup-script 做為中繼資料鍵值,在要求中提供開機指令碼做為中繼資料屬性的一部分。

POST https://www.googleapis.com/compute/v1/projects/myproject/zones/us-central1-a/instances

{
  ...
  "metadata": {
    "items": [
      {
       "key": "startup-script",
       "value": "#! /bin/bash\n\n# Installs apache and a custom homepage\napt-get update\napt-get install -y apache2\ncat <<EOF > /var/www/html/index.html\n<html><body><h1>Hello World</h1>\n<p>This page was created from a simple start up script!</p>\n</body></html>"
      }
    ]
  }
  ...
}

為 Windows 執行個體提供開機指令碼

您可使用唯一 Windows 專用中繼資料鍵值,在 Windows 執行個體上執行開機指令碼。從下面列出的所有特殊鍵值中加以選擇。每組鍵值都應與您要執行的指令碼類型相符。您也可以將不同的鍵值傳入執行個體來指定多個指令碼。每個鍵值都只能為每個執行個體指定一次。

以下鍵值可與本機開機指令碼一起使用,請參閱上述的相同操作說明

指令碼類型 於 sysprep 期間,在開機之前執行 在 sysprep 完成之後及每次後續開機時執行
url 開機指令碼 sysprep-specialize-script-url windows-startup-script-url
cmd 開機指令碼 sysprep-specialize-script-cmd windows-startup-script-cmd
bat 開機指令碼 sysprep-specialize-script-bat windows-startup-script-bat
ps11 開機指令碼 sysprep-specialize-script-ps1 windows-startup-script-ps1

提供儲存在 Google Cloud Storage 上的開機指令碼

您可將指令碼儲存在 Google Cloud Storage 上,並於建立執行個體時提供指令碼的網址。這可讓您從任意位置存取您的開機指令碼,也可略過中繼資料伺服器限制。

設定指令碼的存取權限

為了從 Google Cloud Storage 使用開機指令碼,您必須具有存取指令碼的權限。請檢查值區與檔案上的存取權控管設定以確保您具有權限。

根據預設,如果您是專案擁有者或編輯者,除非有明確存取權控管禁止,否則您應能夠從相同專案存取檔案。

提供開機指令碼

  1. 建立值區。 您可以建立新值區或使用現有值區。如需建立新值區的操作說明,請參閱在 Google Cloud Platform 主控台中建立值區gsutil 中建立值區
  2. 上傳檔案至值區。 按照操作說明使用 gsutilGCP 主控台上傳物件。
  3. 在您建立新執行個體時,提供開機指令碼檔案的網址

    主控台

    1. 在 GCP 主控台中,前往「VM Instances」(VM 執行個體) 頁面。

      前往 VM 執行個體頁面

    2. 按一下 [建立執行個體]
    3. 在「Create a new instance」 (建立新執行個體) 頁面上,填入您要為執行個體 設定的屬性。 如需進階設定選項,請展開「管理、安全性、磁碟、網路、單獨租用」區段。
    4. 在「Metadata」(中繼資料) 部分,提供 startup-script-url 做為中繼資料鍵值。
    5. 在「Value」(值) 方塊中,以 gs://[BUCKET]/[FILE]https://storage.googleapis.com/[BUCKET]/[FILE] 格式提供開機指令碼檔案的網址。
    6. 在「Identity and API access」(身分及 API 存取權) 部分,選取在 Cloud Storage 中具有存取權而可讀取開機指令碼檔案的服務帳戶。舉例來說,服務帳戶需具有 Storage 物件檢視者角色的權限。
    7. 按一下 [Create] (建立) 來建立執行個體。

    gcloud

    透過 gcloud 指令列工具,使用 --scopes--metadata 標記建立執行個體,並指定 startup-script-url 鍵值。--scopes 標記可讓虛擬機器存取 Google Cloud Storage 來下載開機指令碼。您可以 gs://bucket/filehttps://storage.googleapis.com/bucket/file 格式將 Google Cloud Storage 網址提供給指令碼。

    gcloud compute instances create example-instance --scopes storage-ro \
        --metadata startup-script-url=gs://bucket/startupscript.sh
    

    API

    在 API 中,使用 startup-script-url 做為中繼資料鍵值,在要求中提供開機指令碼做為中繼資料屬性的一部分。此外,使用 Google Cloud Storage 範圍提供 scopes 的清單,讓虛擬機器能夠存取開機指令碼檔案:

    POST https://www.googleapis.com/compute/v1/projects/myproject/zones/us-central1-a/instances
    
    {
      ...
      "serviceAccounts": [
        {
          "email": "default",
          "scopes": [
            "https://www.googleapis.com/auth/devstorage.read_only"
          ]
        }
      ],
      "metadata": {
        "items": [
          {
           "key": "startup-script-url",
           "value": "gs://bucket/myfile"
          }
        ]
      },
      "tags": {
        "items": []
      },
      "machineType": "zones/us-central1-a/machineTypes/n1-standard-1",
      "name": "example-instance"
    }
    

    Windows

    透過 gcloud 指令列工具,使用 --scopes--metadata 標記建立執行個體,並指定 windows-startup-script-url 鍵值。--scopes 標記可讓虛擬機器存取 Google Cloud Storage 來下載開機指令碼。您可以 gs://bucket/filehttps://storage.googleapis.com/bucket/file 格式將 Google Cloud Storage 網址提供給指令碼。

    gcloud compute instances create example-windows-instance --scopes storage-ro \
       --metadata windows-startup-script-url=gs://bucket/startupscript.ps1
    

將開機指令碼套用至執行中執行個體

如果您有執行中的執行個體,請將開機指令碼新增至執行個體,下次執行個體重新啟動時,開機指令碼就會執行。開機指令碼也會在所有後續重新開機時執行。

請按照下列操作說明在執行中執行個體上設定開機指令碼。

主控台

  1. 前往 VM 執行個體頁面
  2. 按一下您要新增開機指令碼的執行個體。執行個體詳細資料頁面隨即會顯示。
  3. 在執行個體詳細資料頁面上,完成以下步驟:

    1. 按一下頁面頂端的 [Edit] (編輯) 按鈕。
    2. 在「自訂中繼資料」下,點選 [新增項目]
    3. 使用下列其中一個鍵值新增您的開機指令碼:

      • startup-script:直接使用此鍵值提供開機指令碼內容。
      • startup-script-url:使用此鍵值提供開機指令碼檔案的 Google Cloud Storage 網址。

gcloud

透過 gcloud 指令列工具,使用 instances add-metadata 將中繼資料新增至執行個體。使用任何可用的開機指令碼鍵值:

  • --metadata startup-script=CONTENTS:直接使用此鍵值提供開機指令碼內容。
  • --metadata startup-script-url=URL:使用此鍵值提供開機指令碼檔案的 Google Cloud Storage 網址。
  • --metadata-from-file startup-script=FILE:提供本機儲存的開機指令碼檔案。

例如:

gcloud compute instances add-metadata example-instance \
    --metadata-from-file startup-script=path/to/file
gcloud compute instances add-metadata example-instance \
    --metadata startup-script-url=gs://bucket/file

API

在 API 中,對 instances().setMetadata 方法提出要求,提供新中繼資料與 fingerprint 值。

指紋是由 Compute Engine 產生的隨機字元字串,可用來執行樂觀鎖定。請提供相符的指紋值,以執行您的要求。在每次要求之後,指紋都會變更,如果您提供不符的指紋,您的要求便會遭到拒絕。如此一來,一次就只能進行一項更新,而能夠防止發生衝突。

如要取得執行個體的目前指紋,請執行 instances().get 要求並複製指紋值:

GET https://www.googleapis.com/compute/v1/projects/myproject/zones/us-central1-a/instances/example-instance
{

 ...
 "name": "example-instance",
 "metadata": {
  "kind": "compute#metadata",
  "fingerprint": "zhma6O1w2l8="
 },
 "...
}

接下來,使用下列其中一個中繼資料鍵值及指紋值對 instances().setMetadata 方法提出要求:

  • startup-script:直接使用此鍵值提供開機指令碼內容。
  • startup-script-url:使用此鍵值提供開機指令碼檔案的 Google Cloud Storage 網址。

例如:

POST https://www.googleapis.com/compute/v1/projects/myproject/zones/us-central1-a/instances/example-instance/setMetadata

{
 "fingerprint": "zhma6O1w2l8=",
 "items": [
  {
   "key": "startup-script-url",
   "value": "gs://bucket/file"
  }
 ]
}

執行開機指令碼

您可以連線至執行個體並執行下列其中一個指令,強制開機指令碼在 VM 執行個體上重新執行:

在 Debian、CentOS、RHEL、SLES、Container-Optimized OS 與 Ubuntu 映像檔上:

$ sudo google_metadata_script_runner --script-type startup --debug

startup-script: INFO Starting startup scripts.
startup-script: INFO startup-script: Return code 0.
startup-script: INFO Finished running startup scripts.

在容器最佳化的 OS 上,您也可以使用 journalctl 檢視開機指令碼的輸出。

$ sudo journalctl -u google-startup-scripts.service

開機指令碼輸出會寫入至下列記錄檔:

  • CentOS 與 RHEL:/var/log/messages
  • Debian:/var/log/daemon.log
  • Ubuntu 14.04、16.04 與 16.10:/var/log/syslog
  • SLES 11 與 12:/var/log/messages

在開機指令碼中設定自訂值

當您跨執行個體執行開機指令碼時,可能在某些情況下,您會想要在開機指令碼中使用自訂值。例如,您可能會想要在不同的執行個體上執行開機指令碼,並讓每個執行個體輸出自訂訊息。

您可在建立執行個體時將這些自訂值指定為自訂中繼資料鍵/值組合,並在您的開機指令碼中參照它們。如要深入瞭解如何建立自訂中繼資料鍵值,請參閱設定自訂中繼資料一文。

當您設定了自訂中繼資料鍵值組合時,可以修改開機指令碼以查詢新中繼資料。例如,以上的相同指令碼可以修改成這樣:

#! /bin/bash
VALUE_OF_FOO=$(curl http://metadata.google.internal/computeMetadata/v1/instance/attributes/foo -H "Metadata-Flavor: Google")
apt-get update
apt-get install -y apache2
cat <<EOF > /var/www/html/index.html
<html><body><h1>Hello World</h1>
<p>The value of foo: $VALUE_OF_FOO</p>
</body></html>
EOF

疑難排解

對於中繼資料伺服器的網路連線

專就 Linux 虛擬機器而言,Compute Engine 會先等待連線至中繼資料伺服器,然後才嘗試從中繼資料伺服器取得例如自訂開機或關閉指令碼的資訊。如果中繼資料伺服器無回應,或尚未設定網路,虛擬機器將不會完成開機。

專就映像檔早於 v20160606 的 Linux 虛擬機器而言,序列埠輸出將會顯示 "Waiting for metadata server, attempt N",其中 N 是已做出的嘗試次數。

由於暫時網路問題,這個問題可能會持續最長七分鐘,然後問題會自行解決。如果在七分鐘之後,問題沒有自行解決,請重建您的虛擬機器執行個體。

後續步驟

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

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

這個網頁
Compute Engine 說明文件