GKE on Bare Metal バージョン 1.13.0 以降を使用する場合、起動ルーティンを指定して、起動時に VM の初期化をカスタマイズできます。VM を構成することで、SSH 認証鍵の作成、ユーザーとパスワードの追加、パッケージのインストール、ファイルの書き込み、ネットワーク設定の構成などを行うことができます。
これらの起動タスクは、cloud-init API または起動スクリプト API のいずれかを使用して構成されます(両方は使用できません)。これらの起動ディレクティブは VirtualMachine
YAML マニフェスト ファイルで指定され、VM が起動するたびに自動的に実行されます。
前提条件
起動ディレクティブを設定して VM を構成するには、次の前提条件を満たす必要があります。
検証済みの Linux ゲスト OS を使用し、VM マニフェストで
osType
をLinux
に設定する。Windows ゲスト OS は、cloud-init をサポートしていないため、この機能ではサポートされていません。ゲスト OS に cloud-init がインストールされていることを確認する。最新の Linux OS には 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 を作成または更新するときに、cloud-init データを
VirtualMachine
YAML マニフェストに指定します。マニフェストを適用して VM を作成する手順については、チュートリアル: GDC 上の VM ランタイムで Linux VM を作成、管理するをご覧ください。VM 仕様にある
NoCloud
データソースのspec.cloudInit.noCloud
を使用します。VirtualMachine
マニフェストの各セクションで、ユーザーデータとネットワーク データを指定します。セクションの名前と構造は、使用するデータ形式によって異なります。cloud-init 構成情報は、次のデータ形式で指定できます。
- テキストを消去
- Base64 でエンコードされた文字列
- Kubernetes シークレット
作業を開始するにあたり、一般的な VM 初期化タスクの構成例を一部紹介しました。
cloud-init ユーザーデータ
GDC 上の VM ランタイムは、cloud-config 構文の 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
構成では、ユーザーデータを Key-Value ペアとして指定します。この場合、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 が見つからないか、データキー userData
または userdata
が Secret に存在しない場合は、次の VM の起動動作に注意してください。
VM を作成する際、VM は詳細な理由とメッセージとともに
ErrorConfiguration
状態になります。それ以外の場合、VM が適切に構成されるまで、以前の cloud-init ユーザーデータを引き続き使用します。このため、ゲスト エージェントの有効化または無効化の更新は、VM が正しく構成されるまで有効になりません。
使用された cloud-init ユーザーデータなどの VM 情報を取得するには、次のコマンドを使用します。
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 でエンコードされた文字列を使用する場合、最大サイズは 2,048 バイトです。ユーザーデータのサイズが 2,048 バイトに近いか、超えている場合は、Kubernetes Secret として指定します。
ネットワーク データ構文と関連する詳細情報について詳しくは、cloud-init ドキュメントに記載されたネットワーク構成のバージョン 2 をご覧ください。
クリアテキストとしての cloud-init ネットワーク データ
次のマニフェストの例は、ネットワーク データをクリアテキストとして指定する方法を示しています。この場合、cloud-init によって名前が「e」(e*
)で始まるすべてのイーサネット デバイスで DHCP が有効になります。
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 マニフェストを示しています。VirtualMachine
構成の spec.cloudInit.noCloud.networkDataSecretRef
セクションは、cloud-init ネットワーク データが my-sec
という名前の Kubernetes Secret にあることを示しています。対応する Secret
構成では、ネットワーク データを Key-Value ペアとして指定します。この場合の 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 認証鍵 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, / ]
ファイルを書き込む
次のユーザーデータの例では、VM の /var/lib/google
ディレクトリ内のファイル test
に bash スクリプトを書き込みます。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 のトラブルシューティング
cloud-init を使用していて VM の初期化で問題が発生した場合、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
セクションで、1 つ以上のスクリプトを指定できます。また、起動スクリプトを使用して VM を初期化できます。VM の初期化では通常、パッケージのインストール、リポジトリの設定、SSH 認証鍵の作成、ファイルへのデータの書き込み、VM の他の側面の設定などが行われます。
起動スクリプトについては、次の詳細事項に留意してください。
VM を作成または更新するときに、起動スクリプトを
VirtualMachine
YAML マニフェストに指定します。マニフェストを適用して VM を作成する手順については、チュートリアル: GDC 上の VM ランタイムで Linux VM を作成、管理するをご覧ください。指定されたスクリプトは VM が起動されるたびに実行されます。
スクリプトの先頭に
#!/bin/...
を追加して、スクリプト インタープリタを指定します。たとえば、Bash シェルでスクリプトを実行するには、#!/bin/bash
を含めます。cloud-init API ディレクティブ(
spec.cloudInit
)および起動スクリプト(spec.startupScripts
)の両方を同じVirtualMachine
マニフェストで指定することはできません。
スクリプトの形式
起動スクリプトは、次のデータ形式で指定できます。
- テキストを消去
- Base64 でエンコードされた文字列
- Kubernetes シークレット
個別のスクリプト形式を使用する場合は、次のルールに注意してください。
クリアテキストまたは Base64 でエンコードされた文字列を使用する場合、スクリプトのコンテンツに許容される最大サイズは 2,048 バイトです。スクリプト コンテンツのサイズが 2,048 バイトに近いか、超えている場合は、Kubernetes Secret としてスクリプトを指定します。
Kubernetes Secret を使用する場合は、参照される Secret のデータキー
script
を使用してスクリプト コンテンツを指定します。参照される Secret が見つからないか、参照される Secret にデータキー
script
が存在しない場合、VM は引き続きスクリプトを実行します。ただし、VM はスクリプトのコンテンツの作成や更新は行いません。この場合、kubectl get event
またはkubectl describe gvm
を使用して Kubernetes 警告イベントを見つけることができます。
次の VirtualMachine
YAML マニフェストのサンプルには、サポートされている各形式で 1 つずつで 3 つのスクリプトが含まれています。この場合、各スクリプトがクリアテキストの例にある 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
が含まれています。