Portal:MicroOS/Combustion

移動先: 案内, 検索

Combustion - 初回起動時の MicroOS 設定

Combustion は dracut 向けの最小モジュールで、システムの初回起動時に指定のスクリプトを動作させるための仕組みです。

このスクリプト内ではファイルの作成やパッケージのインストール、デバイスの設定だけでなく、必要であればハードディスクのパーティション編集さえも行うことができます。このスクリプトはシェルスクリプトの形式で記述するもので、外付けのストレージメディアから読み込み、初回のシステムスナップショット採取の際に実行します。スクリプトの実行が成功すると、システムはそのまま新しいスナップショット内で動作しますので、再起動は不要になります。

Ignition および Combustion スクリプトは、 Ignition & Combustion Config Generator を利用して作成することができます。

ビデオでの説明は下記をご覧ください: https://youtu.be/BHaPdJc8_zQ?t=190


準備

パーティションに対して "combustion" という名前のラベルを設定した USB メモリを用意します (MicroOS のインストールメディアとは別に用意する必要があります) 。

このパーティション内には "combustion" という名前のディレクトリを作成します。

あとはそのディレクトリ内に "script" というファイル名の bash スクリプトを作成するだけです。ファイル名には ".sh" という拡張子を付ける必要はありません。

設定ファイルは "combustion" というラベルの設定されたファイルシステムからコピーすることになります。

注意: Ignition との互換性確保および共存の観点から、 "ignition" というラベルでも認識します。

MicroOS は、ファイルシステム内のルートディレクトリに "combustion" というサブディレクトリが存在し、そのディレクトリ内に "script" というファイルが存在していることを期待します。このスクリプトはトランザクション型更新のシェル内で実行されます。

<ルートディレクトリ>
├── combustion
│   ├── script
│   └── ... その他のファイル
└── ignition (任意)
    └── config.ign

このスクリプト内では初回のシステム設定に関わる任意の処理を実施することができます。たとえば ssh 鍵の設定やパッケージのインストール、ユーザの管理やパーティション設定の編集などがあります。

USB メモリによる簡単な構築例

下記は USB メモリをフォーマットして Combustion 用の簡単なスクリプトを構築する場合の例となります。 このスクリプトでは、 "vim-small" というパッケージをインストールし、 sshd サービスを有効化しています:

mkfs.ext4 /dev/sdX
e2label /dev/sdX ignition
mount /dev/sdX /mnt
mkdir -p /mnt/combustion/
cat >/mnt/combustion/script <<EOF


これでパーティションとディレクトリの設定ができますので、あとは "script" ファイルの内容を記述するだけです。

#!/bin/sh
# combustion: network
systemctl enable sshd.service
zypper --non-interactive install vim-small
EOF
echo "Hello User!" >/mnt/combustion/welcome
umount /mnt

なお、上記の "# combustion: network" はスクリプトの実行前要件を記した箇所で、具体的にはネットワークの準備が終わった後に実行すべきであることを示しています。このような記述はカーネルのコマンドラインに対して "rd.neednet=1" を指定した場合と同じで、スクリプトを実行するまでの間にネットワーク関連の設定パラメータ (man dracut.cmdline) が構成されます。なお、カーネルのコマンドラインにそれ以外のネットワーク関連パラメータを指定していない場合は、 "ip=dhcp" が各インターフェイスに対して指定されたものとみなされます。

より複雑な設定例

下記のスクリプトは起動時の処理が画面表示されるようにしています。処理としてはパスワードの設定と ssh 公開鍵の設定を行っています (ssh 公開鍵は "combustion" ディレクトリ内に保存しておきます) 。

#!/bin/bash
# combustion: network
# コンソールへの出力リダイレクト
exec > >(exec tee -a /dev/tty0) 2>&1
# root に対するパスワード設定 (ハッシュ値は "openssl passwd -6" コマンドで生成できます)
echo 'root:$5$.wn2BZHlEJ5R3B1C$TAHEchlU.h2tvfOpOki54NaHpGYKwdNhjaBuSpDotD7' | chpasswd -e
# ssh 公開鍵の設定と sshd サービスの有効化
mkdir -pm700 /root/.ssh/
cat id_rsa_new.pub >> /root/.ssh/authorized_keys
systemctl enable sshd.service
# vim-small パッケージのインストール
zypper --non-interactive install vim-small
# 実行完了のマーキング
echo "Configured with combustion" > /etc/issue.d/combustion

QEMU での注意事項

"opt/org.opensuse.combustion/script" という名前の QEMU fw_cfg blob が存在した場合、こちらで指定されたスクリプトが優先されることに注意してください。 QEMU でのパラメータ指定例:

-fw_cfg name=opt/org.opensuse.combustion/script,file=/var/combustion-script

libvirt での fw_cfg qemu 機能の使用について

仮想マシンの実行に qemu/kvm とともに libvirt を使用している場合、作成した VM 内の libvirt XML 内で combustion ファイルを指定することができます。 XML の編集にあたっては virt-manager UI または virsh edit をお使いください。

具体的には、 <domain> セクション内に下記のような XML セクションを挿入します:

 <sysinfo type="fwcfg">
   <entry name="opt/org.opensuse.combustion/script" file="/location/for/your/file/script"/>
 </sysinfo>

virt-install で VM を作成する場合は、 --sysinfo オプションでスクリプトを指定することもできます:

 --sysinfo type=fwcfg,entry0.name="opt/org.opensuse.combustion/script",entry0.file="/location/for/your/file/script" \

動作

初回の起動時、 ignition-dracut-grub2 パッケージが下記のフラグファイルを作成します:

   /boot/writable/firstboot_happened 

これにより、初回起動処理が実行済みであることを示します。 このフラグファイルが存在しない場合、 GRUB はカーネルのコマンドライン内に "ignition.firstboot" を追加します。

カーネルのコマンドラインに上記のオプションが指定されると、 combustion.service の ConditionKernelCommandLine が設定され、 initrd.target からの要件として設定されます。 この要件設定は combustion-prepare.service を動作させ、 USB メモリや QEMU fw_cfg blob の存在をチェックするようになります (詳しくは combustion.rules を参照) 。スクリプトの存在が検出されるとそれを読み込み、 "network" フラグコメントが設定されていればネットワークの起動完了後にスクリプトを実行するように手配します。 あとは /sysroot のマウントと (必要であれば) ネットワークの起動を待機し、 combustion.service を実行したあとシステム内の /etc/fstab に従って全てのマウントポイントを有効化し、 chroot 内でトランザクション型更新を呼び出します。

このトランザクション型更新のセッション内でスクリプトが実際に実行され、終了コードが記録されます。スクリプトの実行が失敗するとトランザクション型更新の巻き戻し (ロールバック) 処理が呼び出され、 combustion.service の実行が失敗したものとされ、システムの起動が失敗します。なお、 USB メモリやスクリプトが見つからなかった場合は、致命的なエラーとしては扱われず、単に警告メッセージを記録します。

あとは /sysroot のマウントをやり直して既定のサブボリュームを再検出し、通常の起動処理が行われます。

通常の起動処理内では ignition-firstboot-complete サービスが開始され、ここではフラグファイルの書き込みが行われます。これにより combustion が複数回起動されたりしないようにしています。

既知の問題

[# combustion: network] が動作しない問題 (Dracut 内のバグで、イメージ内で回避)

リンク

https://build.opensuse.org/package/show/devel:kubic:ignition/combustion

combustion スクリプトの例: https://code.opensuse.org/adathor/combustion-dotconf