使用 Google Distributed Cloud 1.13.0 以上版本時,您可以指定啟動常式,在 VM 啟動時自訂初始化作業。您可以設定 VM 建立 SSH 金鑰、新增使用者和密碼、安裝套件、寫入檔案,以及設定網路設定等。
這些啟動工作是透過 cloud-init API 或啟動指令碼 API 設定 (兩者擇一)。這些啟動指令會指定在 VirtualMachine
YAML 資訊清單檔案中,並在每次 VM 啟動時自動執行。
必要條件
如要使用啟動指令設定 VM,必須符合下列先決條件:
使用經過驗證的 Linux 客戶端 OS,並在 VM 資訊清單中將
osType
設為Linux
。Windows 客戶端 OS 不支援這項功能,因為這類 OS 不支援 cloud-init。確認客體 OS 已安裝 cloud-init。最新版 Linux 作業系統 都包含 cloud-init。
以下各節說明如何使用 cloud-init API 或啟動指令碼,在 VM 資訊清單中指定啟動常式。
使用 cloud-init API 初始化 VM
Cloud-init 通常用於雲端執行個體初始化,以及在啟動期間自訂 VM。VM 初始化通常會涉及套件安裝、存放區設定、SSH 金鑰建立、將資料寫入檔案,以及設定 VM 的其他層面等工作。您可以使用 spec.cloudInit
欄位,將 cloud-init 設定 YAML 併入自訂資源中。VirtualMachine
VM 執行個體啟動時,cloud-init 會讀取提供的資料,並據此初始化 VM。
請注意 cloud-init 實作的下列詳細資料:
建立或更新 VM 時,您可以在
VirtualMachine
YAML 資訊清單中指定 cloud-init 資料。如要瞭解如何套用資訊清單建立 VM,請參閱「教學課程:在 VM Runtime on GDC 中建立及管理 Linux VM」。我們在 VM 規格中使用
NoCloud
資料來源。spec.cloudInit.noCloud
您可以在
VirtualMachine
資訊清單的個別部分中,指定使用者資料和網路資料。章節命名和結構取決於您決定使用的資料格式。您可以透過下列資料格式指定 cloud-init 設定資訊:
- 清除文字
- Base64 編碼字串
- Kubernetes 密鑰
為協助您上手,我們提供了一些常見 VM 初始化工作的設定範例。
Cloud-init 使用者資料
GDC 上的 VM 執行階段支援雲端設定語法的 cloud-init 使用者資料,因此請以 #cloud-config
開頭。您可以將使用者資料格式設為明文、Base64 編碼字串或 Kubernetes Secret。
如要進一步瞭解使用者資料語法和模組參考資料,請參閱 cloud-init 說明文件。
以純文字形式提供的 Cloud-init 使用者資料
以下範例資訊清單說明如何以明文指定使用者資料。在本例中,cloud-init 會在 VM 啟動時執行指令:
apiVersion: vm.cluster.gke.io/v1
kind: VirtualMachine
metadata:
name: "my-vm"
spec:
...
cloudInit:
noCloud:
userData: |
#cloud-config
runcmd:
- echo hello
以 Base64 編碼字串形式提供的 Cloud-init 使用者資料
以下範例說明如何以 Base64 編碼格式指定使用者資料。
在本範例中,使用者資料包含與純文字範例相同的 echo hello
指令:
apiVersion: vm.cluster.gke.io/v1
kind: VirtualMachine
metadata:
name: "my-vm"
spec:
...
cloudInit:
noCloud:
userDataBase64: I2Nsb3VkLWNvbmZpZwpydW5jbWQ6CiAgLSBlY2hvIGhlbGxvCg==
以 Kubernetes Secret 形式提供的 Cloud-init 使用者資料
以下範例顯示 VirtualMachine
和 Secret
的 YAML 資訊清單。VirtualMachine
設定中的 spec.cloudInit.noCloud.secretRef
區段表示 cloud-init 使用者資料位於名為 my-sec
的 Kubernetes Secret 中。對應的 Secret
設定會將使用者資料指定為鍵/值組合。在本例中,Base64 編碼值是 cloud-config 語法中的 cloud-init 使用者資料。
在參照的 Secret 中,使用資料鍵 userData
(顯示) 或 userdata
指定 cloud-init 使用者資料。
在本範例中,使用者資料包含與純文字範例相同的 echo hello
指令:
apiVersion: vm.cluster.gke.io/v1
kind: VirtualMachine
metadata:
name: "my-vm"
spec:
...
cloudInit:
noCloud:
secretRef:
name: my-sec
---
apiVersion: v1
kind: Secret
type: Opaque
metadata:
name: my-sec
data:
userData: I2Nsb3VkLWNvbmZpZwpydW5jbWQ6CiAgLSBlY2hvIGhlbGxvCg==
如果找不到參照的 Secret,或 Secret 中沒有資料金鑰 userData
或 userdata
,請注意下列 VM 啟動行為:
建立 VM 時,VM 會進入
ErrorConfiguration
狀態,並顯示詳細原因和訊息。在其他情況下,VM 會繼續使用舊的 cloud-init 使用者資料,直到 VM 正確設定為止。因此,必須正確設定 VM,訪客代理程式啟用或停用更新才會生效。
如要擷取 VM 資訊 (包括使用的 cloud-init 使用者資料),請使用下列指令:
kubectl get vm VM_NAME -o yaml --kubeconfig KUBECONFIG_PATH
更改下列內容:
VM_NAME
:VM 名稱。KUBECONFIG_PATH
:包含 VM 的叢集 kubeconfig 檔案路徑。
如要擷取相關的 Kubernetes 警告事件,請使用 kubectl get event
或 kubectl describe gvm
。
Cloud-init 網路資料
與使用者資料類似,您可以將網路資料格式化為純文字、經過 Base64 編碼的字串或 Kubernetes Secret。與使用者資料不同,網路資料不會使用 cloud-config 語法。
使用明文或 Base64 編碼字串時,允許的最大大小為 2048 位元組。如果使用者資料大小接近或超過 2048 個位元組,請將其指定為 Kubernetes Secret。
如要進一步瞭解網路資料語法和相關詳細資料,請參閱 cloud-init 說明文件中的「Networking Config Version 2」。
以純文字形式提供 Cloud-init 網路資料
下列範例資訊清單說明如何以純文字指定網路資料。在本例中,cloud-init 會為名稱開頭為「e」的所有乙太網路裝置啟用 DHCP (e*
):
apiVersion: vm.cluster.gke.io/v1
kind: VirtualMachine
metadata:
name: "my-vm"
spec:
...
cloudInit:
noCloud:
userData: |
#cloud-config
runcmd:
- echo hello
networkData: |
version: 2
ethernets:
alleths:
match:
name: e*
dhcp4: true
採用 Base64 編碼字串的 Cloud-init 網路資料
以下範例說明如何以 Base64 編碼格式指定網路資料。在本例中,網路資料包含純文字範例中指定的相同 DHCP 設定:
apiVersion: vm.cluster.gke.io/v1
kind: VirtualMachine
metadata:
name: "my-vm"
spec:
...
cloudInit:
noCloud:
networkDataBase64: dmVyc2lvbjogMgpldGhlcm5ldHM6CiAgYWxsZXRoczoKICAgIG1hdGNoOgogICAgICBuYW1lOiBlKgogICAgZGhjcDQ6IHRydWUK
以 Kubernetes Secret 形式提供的 Cloud-init 網路資料
以下範例顯示 VirtualMachine
和 Secret
的 YAML 資訊清單。設定中的 spec.cloudInit.noCloud.networkDataSecretRef
區段表示 cloud-init 網路資料位於名為 my-sec
的 Kubernetes Secret 中。VirtualMachine
對應的 Secret
設定會將網路資料指定為鍵/值組合。在本例中,Base64 編碼值為 cloud-init 網路資料。
在參照的 Secret 中,使用資料鍵 networkData
(顯示) 或 networkdata
指定 cloud-init 網路資料。
在本例中,網路資料包含純文字範例中指定的相同 DHCP 設定:
apiVersion: vm.cluster.gke.io/v1
kind: VirtualMachine
metadata:
name: "my-vm"
spec:
...
cloudInit:
noCloud:
networkDataSecretRef:
name: my-sec
---
apiVersion: v1
kind: Secret
type: Opaque
metadata:
name: my-sec
data:
networkData: dmVyc2lvbjogMgpldGhlcm5ldHM6CiAgYWxsZXRoczoKICAgIG1hdGNoOgogICAgICBuYW1lOiBlKgogICAgZGhjcDQ6IHRydWUK
cloud-init 範例
以下各節提供一些常見用途的純文字範例,說明如何使用 cloud-init 初始化 VM:
設定授權的 SSH 金鑰
下列使用者資料範例會將授權的安全殼層金鑰 ssh-rsa AAAAB3NzaK8L93bWxnyp
指派給預設使用者。
apiVersion: vm.cluster.gke.io/v1
kind: VirtualMachine
metadata:
name: "my-vm"
spec:
...
cloudInit:
noCloud:
userData: |
#cloud-config
ssh_authorized_keys:
- ssh-rsa AAAAB3NzaK8L93bWxnyp
新增使用者
下列使用者資料範例會建立使用者 test
,並授予 test
完整 sudo 存取權。這個範例會為使用者指派永不過期的密碼 pwd
。
apiVersion: vm.cluster.gke.io/v1
kind: VirtualMachine
metadata:
name: "my-vm"
spec:
...
cloudInit:
noCloud:
userData: |
#cloud-config
users:
- default
- name: test
sudo: ALL=(ALL) NOPASSWD:ALL
chpasswd:
list: |
test:pwd
expire: False
在首次啟動時執行指令
下列使用者資料範例會執行 echo
指令和 ls
指令。您可以在 VM 啟動時使用指令安裝套件等項目。
apiVersion: vm.cluster.gke.io/v1
kind: VirtualMachine
metadata:
name: "my-vm"
spec:
...
cloudInit:
noCloud:
userData: |
#cloud-config
runcmd:
- [ echo, hello ]
- [ ls, -l, / ]
寫入檔案
以下使用者資料範例會將 bash 指令碼寫入 VM 的 /var/lib/google
目錄中的 test
檔案。cloud-init 指令會將檔案權限設為讀取、寫入及執行 (0744
) 檔案擁有者。
apiVersion: vm.cluster.gke.io/v1
kind: VirtualMachine
metadata:
name: "my-vm"
spec:
...
cloudInit:
noCloud:
userData: |
#cloud-config
write_files:
- path: /var/lib/google/test
permissions: 0744
content: |
#!/bin/bash
echo hello
排解 cloud-init 問題
如果 VM 初始化時發生問題,且您使用 cloud-init,請檢查 VM 中的下列 cloud-init 記錄:
/var/log/cloud-init.log
:根據預設,cloud-init 會將層級為DEBUG
以上的所有事件寫入這個記錄檔。/var/log/cloud-init-output.log
:根據預設,cloud-init 會將所有 cloud-init 階段的 stdout 和 stderr 導向這個記錄。
使用開機指令碼初始化 VM
開機指令碼會在虛擬機器 (VM) 執行個體的啟動程序中執行工作。您可以在 VirtualMachine
規格的 spec.startupScripts
區段中指定一或多個指令碼。開機指令碼可用於初始化 VM。VM 初始化通常會涉及套件安裝、存放區設定、SSH 金鑰建立、將資料寫入檔案,以及設定 VM 的其他層面等工作。
請注意開機指令碼的下列細節:
建立或更新 VM 時,您可以在
VirtualMachine
YAML 資訊清單中指定開機指令碼。如要瞭解如何套用資訊清單建立 VM,請參閱「教學課程:在 VM Runtime on GDC 中建立及管理 Linux VM」。每次啟動 VM 時,系統都會執行指定的指令碼。
在指令碼頂端加入
#!/bin/...
,指出指令碼解譯器。舉例來說,加入#!/bin/bash
即可使用 Bash 殼層執行指令碼。您無法在同一個
VirtualMachine
資訊清單中,同時指定 cloud-init API 指令 (spec.cloudInit
) 和啟動指令碼 (spec.startupScripts
)。
指令碼格式
您可以透過下列資料格式指定開機指令碼:
- 清除文字
- Base64 編碼字串
- Kubernetes 密鑰
請注意下列規則,瞭解如何使用不同格式的指令碼:
使用明文或 base64 編碼字串時,指令碼內容的大小上限為 2048 位元組。如果指令碼內容大小接近或超過 2048 個位元組,請將指令碼指定為 Kubernetes 密鑰。
使用 Kubernetes Secret 時,請在參照的 Secret 中使用資料金鑰
script
指定指令碼內容。如果找不到參照的 Secret,或參照的 Secret 中沒有資料金鑰
script
,VM 會繼續執行指令碼。但 VM 不會撰寫或更新指令碼內容。在這種情況下,您可以使用kubectl get event
或kubectl describe gvm
找出 Kubernetes 警告事件。
下列 VirtualMachine
YAML 資訊清單範例包含三個指令碼,每個指令碼都採用其中一種支援的格式。在本例中,每個指令碼都會執行 myscript1
中顯示的 echo
hello
指令,也就是純文字範例。
apiVersion: vm.cluster.gke.io/v1
kind: VirtualMachine
metadata:
name: "my-vm"
spec:
...
startupScripts:
- name: myscript1
script: |
#!/bin/bash
echo hello
- name: myscript2
scriptBase64: IyEvYmluL2Jhc2gKICAgICAgZWNobyBoZWxsbwo=
- name: myscript3
scriptSecretRef:
name: my-sec
---
apiVersion: v1
kind: Secret
type: Opaque
metadata:
name: my-sec
data:
script: IyEvYmluL2Jhc2gKICAgICAgZWNobyBoZWxsbwo=
指令碼疑難排解
如要查看指令碼結果或記錄,請執行下列指令:
journalctl -u cloud-final
開機指令碼記錄項目會以以下文字開頭:
started to run the command /var/lib/google/startup-scripts/SCRIPT_NAME ...
記錄項目包含 SCRIPT_NAME
,也就是開機指令碼的名稱。