UbuntuサーバーのインストールISOイメージは、デスクトップ版と同じようにLive環境が備わっています。たとえば何かトラブルがあった時、デスクトップを起動するほどのスペックがないマシンに対してLive環境でリカバリーを試みる際に有効です。起動後は普通のUbuntuであるため、メモリの容量が許せば、aptコマンドなどで追加のインストールも可能になります。ただ、ネットワークの都合で、起動の時点でインストールされていたほうが良い場合も多々あります。そこで今回はこのLive環境をカスタマイズしたISOイメージの作成方法を紹介しましょう。
UbuntuサーバーのISOイメージ
Ubuntuは18.
また、Subiquityはsnapパッケージとして提供されていますが、その副産物として
直接的な利便性という点では、Subiquityの利点はcloud-initベースの自動インストール機能とLive環境でしょう。自動インストール機能については第615回の
Live環境は、デスクトップ版のUbuntuを利用している人にはおなじみの
Live環境は管理者exit
するとインストーラーの画面に戻れます。一般ユーザーとしてubuntu-server
」installer
」
ルートファイルシステムそのものは、squashfsで構築されています。ただし、lowerディレクトリは複数のsquashfsの組み合わせをoverlayfsで重ね合わせることによって実現しているようです[1]。よって、ISOイメージを分解してカスタマイズするにしても、このあたりの状態を把握しておかなくてはいけません。
ただし、リカバリーにも使うならよく使うツールを入れておきたいところです。また、たとえば小さなUSBメモリーにして常に接続しておくことで、ストレージ故障によりうまく起動できなくなった時に、自動的にUSBメモリー側にフォールバックして、そこから状況の確認を行う、といった用途にも使えるようになります。
今回は、そんなUbuntuサーバーのLiveインストールイメージをカスタマイズできる
Liveイメージのカスタマイズに特化した、livefs-editor
「livefs-editor」
- PPA等のリポジトリの追加
- 自動インストール用のYAMLファイルの同梱
- カーネルの起動パラメーターの変更
- インストール用のリポジトリに任意のdebファイルやパッケージを追加
- インストール用リポジトリのリポジトリ鍵の変更
- Live環境に指定のパッケージやdebファイルをインストール
- Live環境に指定のsnapパッケージをインストール
- ISOイメージやLive環境に対する任意のファイルのコピーや削除
- 指定したsquashfsのカスタマイズ
- 指定したPython文字列の実行
- 起動・
インストール時のカーネルフレーバーの変更 - initramsのカスタマイズ
- カスタマイズ用のインタラクティブシェルの立ち上げ
また、上記の設定はすべてコマンドラインオプションから指定するのですが、YAMLでまとめて指定してしまうことも可能です。各オプションの指定方法や使い方が少し特殊であるため、習熟するのには少し手間かもしれませんが、うまくやればイメージの作成を自動化できます。
とりあえず使ってみるのが良いでしょう。そこでまずはlivefs-editorをインストールします。
$ sudo apt install xorriso liblz4-tool pipx $ pipx install git+https://github.com/mwhudson/livefs-editor.git installed package livefs-edit 0.0.4, installed using Python 3.10.6 These apps are now globally available - livefs-edit done! ✨ 🌟 ✨
ちなみにUbuntu 23.
また、pipxは~/.local/
」~/.local/
ディレクトリが存在すれば自動的に環境変数$PATH
に追加してくれますので、インストールしたコマンドもすぐに使えるようになります。ただし、ログインの時点でディレクトリがなく、その後作られた場合は$PATH
には設定されませんので、パスを指定するか一度ログインし直してください。
試しにヘルプを表示してみましょう。注意しなくてはいけない点として、live-editorのリポジトリ名は
$ livefs-edit -h # livefs-edit source.{iso,img} dest.{iso,img} [actions] livefs-edit makes modifications to Ubuntu live ISOs and images. Actions include: * --add-apt-repository * --add-autoinstall-config * --add-cmdline-arg * --add-debs-to-pool * --add-packages-to-pool * --add-snap-from-store * --cp * --edit-squashfs * --inject-snap * --install-debs * --install-packages * --python * --replace-kernel * --resign-pool * --rm * --setup-rootfs * --shell * --unpack-initrd
これらの
livefs-editコマンドの使い方
ヘルプメッセージにもあるように、livefs-editは次のように複数のアクションを繋げて使うことになります。
$ sudo ~/.local/bin/livefs-edit src.iso dst.iso --add-apt-repository REPO --install-packages PKG
まず最初に、chrootコマンド等を使うために、管理者権限で実行する必要があります。さらにsudo
を使おうとすると$PATH
が初期化されてしまい、pipxでインストールした場所にパスが通っていないため、上記のようにフルパスで指定しなくてはいけないのです。
src.
が元になるISOイメージで、dst.
が生成ファイルです。そのあとにカスタマイズしたい内容を順番に指定していきます。上記の例だとadd-apt-repository
コマンドで追加し、その上で
もうひとつの方法として、上記コマンド列をYAMLファイルに記述して指定する方法があります。たとえば上記のアクション列は次のように変換できるのです。
- name: add-apt-repository repo: REPO - name: install-packages packages: - PKG
「name: アクション名
」引数名: 引数
」README.
に記載があるので、そちらを参照しましょう。引数
」install-packages
を含むパッケージ関連だけは、リスト形式で指定します。
作成したYAMLファイルの指定方法は次のとおりです。
$ sudo ~/.local/bin/livefs-edit src.iso dst.iso --action-yaml install.yaml
アクション列が複雑になってきたら、YAMLファイルに移行することも検討しましょう。
install-packagesとadd-packages-to-poolの違い
livefs-editには次の4種類のパッケージ関連のアクションが存在します。
install-packages
add-packages-to-pool
install-debs
add-debs-to-pool
「install-packages
」
それに対してadd-packages-to-pool
」
「deb
」
強力なshellアクション
livefs-editにはよくある使い方に対するアクションが一通り揃っています。ただ、それですべて賄えるかというと難しいところです。そこで便利なのが
実際に試してみましょう。
$ sudo ~/.local/bin/livefs-edit ubuntu-22.04.2-live-server-amd64.iso test.iso --shell set up loop device /dev/loop31 backing ubuntu-22.04.2-live-server-amd64.iso found live iso9660 filesystem on /dev/loop31p1 running shell with arguments {} root@meet:/tmp/tmpv922azo1#
上記はサーバー版のUbuntu 22./tmp
以下に展開されていることがわかります。まずはディレクトリを見てみましょう。
root@meet:/tmp/tmpv922azo1# ls
new old
root@meet:/tmp/tmpv922azo1# ls new/iso/
EFI boot boot.catalog casper dists install md5sum.txt pool ubuntu
大本のISOイメージはold/
」new/
」dists
」pool
」casper
」
実際にcasper
以下を見てみると、カーネル
# ls new/iso/casper/
filesystem.manifest ubuntu-server-minimal.squashfs.gpg ubuntu-server-minimal.ubuntu-server.installer.manifest
filesystem.size ubuntu-server-minimal.ubuntu-server.installer.generic-hwe.manifest ubuntu-server-minimal.ubuntu-server.installer.size
hwe-initrd ubuntu-server-minimal.ubuntu-server.installer.generic-hwe.size ubuntu-server-minimal.ubuntu-server.installer.squashfs
hwe-vmlinuz ubuntu-server-minimal.ubuntu-server.installer.generic-hwe.squashfs ubuntu-server-minimal.ubuntu-server.installer.squashfs.gpg
initrd ubuntu-server-minimal.ubuntu-server.installer.generic-hwe.squashfs.gpg ubuntu-server-minimal.ubuntu-server.manifest
install-sources.yaml ubuntu-server-minimal.ubuntu-server.installer.generic.manifest ubuntu-server-minimal.ubuntu-server.size
ubuntu-server-minimal.manifest ubuntu-server-minimal.ubuntu-server.installer.generic.size ubuntu-server-minimal.ubuntu-server.squashfs
ubuntu-server-minimal.size ubuntu-server-minimal.ubuntu-server.installer.generic.squashfs ubuntu-server-minimal.ubuntu-server.squashfs.gpg
ubuntu-server-minimal.squashfs ubuntu-server-minimal.ubuntu-server.installer.generic.squashfs.gpg vmlinuz
squashfsが複数存在するのは、環境に応じて重ね合わせるレイヤーを変更するためのようです。ubuntu-server-minimal.
」
shellアクションの終了はexit
コマンドの実行です。このとき戻り値が0なら次のアクションを実行し、1ならその時点で終了してクリーンナップ処理が走ります。
root@meet:/tmp/tmpv922azo1# exit exit running repack hooks no changes!
上記の例だと、old/
」new/
」
edit-squashfsアクションでsquashfsをカスタマイズ
「edit-squash
」ubuntu-server-minimal
」ubuntu-server-minimal.
」
$ sudo ~/.local/bin/livefs-edit ubuntu-22.04.2-live-server-amd64.iso test.iso \ --edit-squashfs ubuntu-server-minimal \ --edit-squashfs ubuntu-server-minimal.ubuntu-server.installer \ --shell set up loop device /dev/loop31 backing ubuntu-22.04.2-live-server-amd64.iso found live iso9660 filesystem on /dev/loop31p1 running edit-squashfs with arguments {'squash_name': 'ubuntu-server-minimal'} squashfs 'ubuntu-server-minimal' now mounted at '/tmp/tmp6av769vs/new/ubuntu-server-minimal' running edit-squashfs with arguments {'squash_name': 'ubuntu-server-minimal.ubuntu-server.installer'} squashfs 'ubuntu-server-minimal.ubuntu-server.installer' now mounted at '/tmp/tmp6av769vs/new/ubuntu-server-minimal.ubuntu-server.installer' running shell with arguments {} root@meet:/tmp/tmp6av769vs#
「edit-squash
」--shell
」new/
」
root@meet:/tmp/tmp6av769vs# ls new/ubuntu-server-minimal bin boot dev etc home lib lib32 lib64 libx32 media mnt opt proc root run sbin snap srv sys tmp usr var root@meet:/tmp/tmp6av769vs# ls new/ubuntu-server-minimal.ubuntu-server.installer dev etc proc root run snap sys tmp usr var
このように内容がだいぶ異なるようです。実際に中身を比較してみると、new/
」/etc/
」
このsquashfsディレクトリに変更を加えると、shellを抜けて、ISOイメージを構築する際に自動的に再アーカイブしてくれます。つまりLive環境のルートファイルシステムを柔軟にカスタマイズしたいのであれば、edit-squash
の利用は必須となります。
標準入力のリダイレクトを活用して設定を自動化
shellとedit-squashfsを組み合わせれば大抵のことは自動化できます。まずは次のような、YAMLファイルを作ってみましょう。
- name: edit-squashfs squash_name: ubuntu-server-minimal - name : shell - name: install-packages packages: - docker-ce
「ubuntu-server-minimal
」
- YAMLをshellで指定した場合はどうなるのか
- Ubuntuリポジトリにはdocker-ceパッケージは存在しないがどうなるのか
実際に実行してみた結果は次のとおりです。
$ sudo ~/.local/bin/livefs-edit ubuntu-22.04.2-live-server-amd64.iso test.iso --action-yaml docker.yaml (中略) running edit-squashfs with arguments {'squash_name': 'ubuntu-server-minimal'} squashfs 'ubuntu-server-minimal' now mounted at '/tmp/tmpr8b131tq/new/ubuntu-server-minimal' running shell with arguments {} root@meet:/tmp/tmpr8b131tq# exit exit running install-packages with arguments {'packages': ['docker-ce']} running unpack-initrd with arguments {} Hit:1 http://archive.ubuntu.com/ubuntu jammy InRelease (中略) E: Package 'docker-ce' has no installation candidate (後略)
まず最初の疑問の
次の疑問である
そこでさらに次のようなファイルを作ってみることにしましょう。
cd new/ubuntu-server-minimal/ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o etc/apt/keyrings/docker.gpg chmod a+r etc/apt/keyrings/docker.gpg echo \ "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \ sudo tee etc/apt/sources.list.d/docker.list > /dev/null chroot . addgroup --system docker exit
これはnew/
」
さらに最後から2行目ではchrootコマンドを使っています。これにより、指定したsquashfsをルートファイルシステムと仮定して、コマンドを実行できます。
これをsample.
」
$ sudo ~/.local/bin/livefs-edit ubuntu-22.04.2-live-server-amd64.iso test.iso --action-yaml docker.yaml < sample.txt (中略) Adding group `docker' (GID 112) ... (中略) Get:1 https://download.docker.com/linux/ubuntu jammy InRelease [48.9 kB] (中略) Setting up docker-ce (5:24.0.1-1~ubuntu.22.04~jammy) ... (中略) Writing to 'stdio:test.iso' completed successfully.
今度は処理が止まらずに動いているようです。さらにdocker-ceパッケージも無事にインストールできました。このように標準入力のリダイレクトと組み合わせれば、かなり柔軟にLive環境をカスタマイズできます。
ちなみに、この方法で作ったLiveイメージでは、dockerサービスは起動していません。どうもaddgroupはubuntu-server-minimalとは別のレイヤーのものが使われているようです。もちろんLive環境を起動したあとにaddgroup --system docker
」systemctl start docker
」
ぜひ、各自でUbuntuサーバーのインストールISOをカスタマイズしてみてください。