在 Linux VM 中使用開機指令碼

本文說明如何使用開機指令碼,在 Google Distributed Cloud (GDC) 實體隔離方案中啟動虛擬機器 (VM) 執行個體和相關聯的程式。

開機指令碼是一種自動化工具,可在 VM 啟動程序中執行工作。使用開機指令碼,在新執行個體或現有執行個體上自動執行 VM 設定和部署工作,節省時間並減少手動設定作業。

本文適用對象為平台管理員或應用程式操作員群組中的開發人員,他們想在 Distributed Cloud 環境中,為 VM 使用開機指令碼。詳情請參閱「GDC 實體隔離方案說明文件的目標對象」。

事前準備

如要使用 gdcloud 指令列介面 (CLI) 指令,請務必下載、安裝及設定 gdcloud CLI。Distributed Cloud 的所有指令都使用 gdcloud 或 kubectl CLI,且需要作業系統 (OS) 環境。

取得 kubeconfig 檔案路徑

如要對 Management API 伺服器執行指令,請確認您具備下列資源:

  1. 如果您沒有 Management API 伺服器的 kubeconfig 檔案,請登入並產生該檔案。

  2. 請使用 Management API 伺服器的 kubeconfig 檔案路徑,取代這些操作說明中的 MANAGEMENT_API_SERVER。

要求 IAM 角色

如要為 VM 使用開機指令碼,請與 IAM 專案管理員聯絡,要求在專案中取得下列角色:

  • 虛擬機器專案管理員 (project-vm-admin):建立、修改、列出及刪除專案命名空間中的 VM。

  • Secret 管理員 (secret-admin):取得、列出、建立、更新、刪除、修補及監控專案命名空間中的 Kubernetes Secret。使用這個角色指定開機指令碼 Secret。您不需要這個角色,也能指定純文字開機指令碼。

所有 VM 角色都必須繫結至 VM 所在專案的命名空間。按照步驟驗證存取權。

傳遞開機指令碼

您可以使用 bash 或非 bash 指令碼做為開機指令碼。方法是在指令碼開頭加入 #!/bin/…,指出指令碼解譯器。舉例來說,如要使用 Python 3 開機指令碼,請在指令碼開頭加上 #! /usr/bin/python3。

Google Distributed Cloud (GDC) 實體隔離方案會按照 startupScripts 陣列中的順序,執行開機指令碼。

下表列出不同腳本大小適用的腳本格式:

指令碼大小 腳本格式
指令碼最多 2048 個位元組 清除文字
指令碼大於 2048 位元組 Kubernetes 密鑰

定義開機指令碼

如要使用開機指令碼,您必須在 VM spec 欄位中新增 startupScripts 欄位。您可以在這個欄位中,以明文或 Kubernetes 密鑰的形式指定多個開機指令碼。

以下範例將開機指令碼指定為明文和 Kubernetes 密鑰:

apiVersion: virtualmachine.gdc.goog/v1
kind: VirtualMachine
metadata:
  name: "my-vm"
spec:
  # …
  startupScripts:
  - name: hello-world
    script: |
      #!/bin/bash
      echo hello
  - name: add-user
    scriptSecretRef:
      name: add-user
---

apiVersion: v1
kind: Secret
type: Opaque
metadata:
  name: add-user
data:
  script:
    IyEvYmluL2Jhc2gKYWRkdXNlciB1c2VyCg==

請考量下列事項:

  • 開機指令碼會在每次開機時執行。
  • 開機指令碼預設具備根權限。
  • 在 Kubernetes 密鑰中,VM spec 中的 scriptSecretRef 名稱必須與 metadata.name 欄位一致。
  • 在 Kubernetes 密鑰中,將 script 鍵新增至 data 欄位,指定開機指令碼內容。

使用開機指令碼建立新的 VM

無論您使用何種映像檔建立 VM,這些操作說明都適用。完成下列步驟:

  1. 如要將開機指令碼建立為 Kubernetes Secret,請執行下列指令:

    cat <<EOF >>FILE_NAME
    STARTUP_SCRIPT_CONTENT
    EOF
    
    kubectl --kubeconfig MANAGEMENT_API_SERVER \
      -n PROJECT \
      create secret generic SECRET_NAME \
      --from-file=script=FILE_NAME
    
    rm FILE_NAME
    
  2. 請參閱「建立 VM」頁面,瞭解建立 VM 的步驟。在步驟一中,先將一或多個開機指令碼新增至 spec 欄位,再執行指令建立 VM。

    以下範例定義了包含明文和 Kubernetes 密鑰的開機指令碼:

    apiVersion: virtualmachine.gdc.goog/v1
    kind: VirtualMachine
    metadata:
      name: VM_NAME
      namespace: PROJECT
    spec:
      # …
      startupScripts:
      - name: CLEAR_TEXT_SCRIPT_NAME
        script: |
          #!/bin/bash
          CLEAR_TEXT_SCRIPT
      - name: SECRET_SCRIPT_NAME
        scriptSecretRef:
          name: SECRET_NAME
    

    這些變數的定義如下:

    變數定義
    MANAGEMENT_API_SERVER Management API 伺服器 kubeconfig 檔案。
    PROJECT 要在其中建立 VM 的 Distributed Cloud 雲端專案。
    VM_NAME VM 的名稱。
    FILE_NAME 用於儲存開機指令碼的檔案名稱。
    STARTUP_SCRIPT_CONTENT 開機指令碼中要執行的指令
    CLEAR_TEXT_SCRIPT_NAME 明文開機指令碼的名稱。
    CLEAR_TEXT_SCRIPT 您定義的明文指令碼。
    SECRET_NAME Kubernetes 密鑰的名稱。
    SECRET_SCRIPT_NAME 開機指令碼的名稱,以 Kubernetes Secret 的形式呈現。
  3. 請按照下列步驟建立 VM。

    以下範例說明如何建立含有開機指令碼的 VM,並使用 Kubernetes Secret 和明文新增使用者。

    kubectl --kubeconfig MANAGEMENT_API_SERVER \
      -n PROJECT \
      apply -f - <<EOF
    apiVersion: virtualmachine.gdc.goog/v1
    kind: VirtualMachineDisk
    metadata:
      name: VM_BOOT_DISK_NAME
    spec:
      source:
        image:
          name: BOOT_DISK_IMAGE_NAME
          namespace: vm-system
      size: BOOT_DISK_SIZE
    ---
    apiVersion: v1
    kind: Secret
    type: Opaque
    metadata:
      name: add-user
    data:
      script:
        IyEvYmluL2Jhc2gKYWRkdXNlciB1c2VyCg==
    ---
    apiVersion: virtualmachine.gdc.goog/v1
    kind: VirtualMachine
    metadata:
      name: VM_NAME
    spec:
      compute:
        virtualMachineType: MACHINE_TYPE
      disks:
      - virtualMachineDiskRef:
          name: VM_BOOT_DISK_NAME
        boot: true
        autoDelete: BOOT_DISK_AUTO_DELETE
      startupScripts:
      - name: add-user
        scriptSecretRef:
          name: add-user
      - name: add-to-sudoers
        script: |
          #!/bin/bash
          usermod -aG sudo user
    EOF
    

    在本例中,變數定義如下。

    變數定義
    MANAGEMENT_API_SERVER Management API 伺服器 kubeconfig 檔案。
    PROJECT 要在其中建立 VM 的 Distributed Cloud 雲端專案。
    VM_NAME 新 VM 的名稱。
    VM_BOOT_DISK_NAME 新 VM 開機磁碟的名稱。
    BOOT_DISK_IMAGE_NAME 新 VM 開機磁碟要使用的映像檔名稱。
    BOOT_DISK_SIZE 開機磁碟的大小,例如 20G。
    這個值一律必須大於或等於開機磁碟映像檔的 minimumDiskSize。
    BOOT_DISK_AUTO_DELETE true 或 false,表示 VM 執行個體刪除時,是否會自動刪除開機磁碟。
    MACHINE_TYPE 新 VM 的預先定義機型。如要選取可用的機型,請執行下列指令:
    kubectl --kubeconfig MANAGEMENT_API_SERVER get virtualmachinetype.virtualmachine.gdc.goog --namespace vm-system

使用開機指令碼更新現有 VM

您也可以使用開機指令碼更新現有 VM。執行更新前,必須先關閉 VM。

按照更新 VM 屬性的步驟操作,並使用要執行的開機指令碼更新 spec 欄位。

查看開機指令碼的輸出內容

  1. 按照步驟連線至 VM。
  2. 在訪客 VM 中執行下列指令,取得您執行的開機指令碼記錄:

    sudo journalctl -u cloud-final
    

    開機指令碼記錄的開頭如下:

    Started to run the command: /var/lib/google/startup-scripts/<script-name> ...