Cloud-init サーバ側の設定 テンプレートに入れたいcloud-init

投稿者: | 10月 8, 2025

実は、なんとなくサポート的な仕事をしている期間が長い。それも1人社員でプリセールス、導入、サポートまでやっていた時がある。そうなると、サポート問い合わせが実は足枷で、いかに早急に楽に対応するべきかということになる。特に再現環境ができないと、どこでつまづいているのかが検討がつかないことが多々ある。そこで考えたのが、以下に仮想マシンイメージを展開するか?ということになる。たまに、再現環境をOSのセットアップからいちいちやっている人を見かけるが、これをしているとOSの設定自体がうまくいかなかったり、結果がばらついたりする。さらに、大量にマシンが必要なときはどうするのか?クローンしたら同じマシンIDのマシンが大量にできてしまう。

これを解消するのが、WindowsだとSysprepとなる。Sysprepも普通に作ってしまうと、OSのOOBEの初期セットアップが始まり入力箇所が多く実は大変。さらにRearm countがSysprepごとに1つ減ってしまう。評価版だとRearm countが3つくらいしかない。(長らく出ていないサービスパックを当てると1つ増えるが)なので、OSを作り直せる回数が少なくなってしまう。Sysprepのunattend.xmlを駆使すると、

  • Rearm Countの維持
  • OOBEセットアップの入力の簡略化(Administratorパスワードだけでいい)
  • 初回起動時のHDD領域拡張(OSのセットアップ時に回復パーティションを先頭に置く設定をする必要があるが。)
  • Bginfo(デスクトップ壁紙にIPアドレスなど表示)などのツールのセットアップ

などが自動化できる。こうすることで展開してすぐに使える、ADとしてセットアップできる。大量マシンの構築ができる。

一方、LinuxだとSysprepはないが、少なくともMachine IDとSSHのホストキーぐらいは作り直したい。また、ネットワークの設定も行いたい。簡単にできると思ったんだが、Machine IDはサイズゼロにすればよく、SSHのホストキーは消せば作り直してくれるが、Sysprepと違って

  • ホスト名をランダムにできない
  • 初回起動時のHDD領域拡張は、パーティションの拡張、ファイルシステムの拡張に加えて、LVMのケアなどが別途必要
  • ネットワークの初期化

などが必要になる。特に、Ubuntu Serverだと、DHCPで、MACアドレスをみてくれないので、DHCPのマシンをクローンすると、全て同じIPアドレスをつかんでしまう。固定IPでテンプレートを作っている人もいるかもしれない。一方、クラウド全盛、IPv6全盛の今だと、固定IPアドレスにしなくても、IPv4ならDHCP、IPv6ならステートレスな動的アドレス配信でも構わないような気がする。(IPv6の場合、DHCPのほうが面倒のような気がする。)

これを解決してくれるのが、Cloud-initだということがわかった。最近まで、初期化スクリプトを作ってこなしていたが、初期化スクリプトの維持管理が結構面倒。Cloud-initもデータを作るのが面倒だが、Cloud-initでデータをインジェクションすれば、元のOSイメージがなんであれ、自分の設定を入れ込んでくれる。さらにパッケージのアップデートとかも自動化できる。Cloud-initはいわば、借りてきた猫(最新のOSイメージを拾ってきた)ですら、自分の家の猫(自分専用の設定)にできる。

閑話休題

Cloud-initは、クラウドで使われているUser Data、そのものである。さらにLinuxだけではなく、Windowsも使える。今まではインジェクションしてcloud-initを使う方法を扱ってきたが腹持ち(OS内にいれて)使う方法。もちろん、インジェクションされたらインジェクションしたほうを優先できる。具体的には、

まず、cloud-initが見に行く先を指定する。以下以外にもあるのだが、余計な部分を見に行かれても困るので、オンプレで指定できるものを列記した。
tee /etc/cloud/cloud.cfg.d/90_datasource_list.cfg >/dev/null <<‘EOF’
datasource_list: [ NoCloud, VMware, OVF, LXD, None ]
EOF
次に各項目の設定 ISOイメージでインジェクションをする場合は、ISOのラベルをcidataとする。そうすると認識する、ISOイメージのラベルがcidataではない、そもそも存在しない場合は、/var/lib/cloud/seed/nocloud/にあるデータを見に行く。ここがみそ。/var/lib/cloud/seed/nocloud/の中にcloud-initのデータを仕込める!また、VMwareの設定も入れておく。
tee /etc/cloud/cloud.cfg.d/91_datasource_tuning.cfg >/dev/null <<‘EOF’
datasource:
Search:
max_wait: 15 # total wait ceiling across DS tries
timeout: 5 # per-attempt network timeout
NoCloud:
fs_label: cidata
seedfrom: /var/lib/cloud/seed/nocloud/
VMware:
vmware_guestinfo: true
dmi_system_uuid: true
EOF
/var/lib/cloud/seed/nocloud/の中身を作っていく。cloud-initのデータは割愛。(YAMLをこのブログに貼りたかったのだが、貼る方法がわからず。。。なので、Gistにサンプルを貼っておいた。)
install -d -m 0755 /var/lib/cloud/seed/nocloud
install -m 0644 /dev/null /var/lib/cloud/seed/nocloud/vendor-data
install -m 0644 /var/lib/cloud/seed/nocloud/meta-data
install -m 0644 /var/lib/cloud/seed/nocloud/user-data
install -m 0644 /var/lib/cloud/seed/nocloud/network-config
再起動時にcloud-initを作動させるには、以下を実行してから再起動をする。
systemctl stop cloud-init || true
systemctl stop cloud-init-local || true
systemctl stop cloud-config || true
systemctl stop cloud-final || true
cloud-init clean –logs –machine-id
truncate -s 0 /etc/machine-id
[ -f /var/lib/dbus/machine-id ] && truncate -s 0 /var/lib/dbus/machine-id || true
rm -f /etc/ssh/ssh_host_key /etc/ssh/ssh_host_key.pub || true
rm -f /etc/udev/rules.d/70-persistent-net.rules || true
systemctl enable cloud-init cloud-init-local cloud-config cloud-final
rm -rf /var/lib/cloud/instance /var/lib/cloud/instances/* 2>/dev/null || true
再起動完了後に、以下を実行して、doneと出れば完了
cloud-init status –long
UbuntuとRHEL系の2つを作ったが、テンプレートイメージの作成がだいぶ楽になった。少なくともUbuntu 22.04/24.04、RHEL系8/9はほぼ同じ記述で行ける。ちなみにRHELは、RHNにログインをしなければならないのでちょっと違う。UbuntuとRHEL系では、cloud-initに関わるパッケージが違うので、標準書式では吸収できなかった。
以下にサンプルを置いてみた。
SSHの証明書は自身のを貼り付ける。(今更RSAのキーを貼り付けることはしないと思うが)
初期パスワードのハッシュを以下のようにして作成して貼り付ける。
mkpasswd –method=SHA-512 –rounds=4096 ‘Password1234’
環境は、Ubuntu 24.04で検証済み
Rocky 9.6で動かす場合は、
  •  最初にcloud-initを入れる。再起動してはダメ
  •  少なくとも以下を変更
  cloud-guest-utilsをcloud-utils-growpartに変更
  adm, sudoをadm, wheelに変更
をする必要がある。
実は必要に迫られて突貫でつくったのだが、この突貫の作業が長く効果を出してくれる。

コメントを残す