💿

永続書き込み可能なUbuntu Server 23.10のインストーラーUSBメモリを標準ツールだけで作る

2024/02/18に公開

2024/04/26追記: Ubuntu Server 24.04ではこの手法は使用できませんでした。インストーラーの構造が変わった……?

背景

Ubuntuのインストーラーisoをddで焼けばUbuntuのインストーラーUSBメモリを簡単に作れる訳ですが、
それだとブートする度にデータは元に戻ってしまいます。

インストーラーに沿ってインストールするだけなら何ら困らない訳ですが、シェルに入ってトラブルシューティングをしたり特殊な構成(root on ZFSなど)でインストールする場合には、必要なパッケージやssh公開鍵を保持したくなるのではないでしょうか。

そこで、永続書き込み可能なインストーラーUSBメモリを作りたいわけですが、検索で出てくる内容はどれもGUIツールを使用する手法で個人的に都合が悪かったため、Ubuntuの標準ツールで済ませられる方法を書き記します。今回はUbuntu Server 23.10で行いますが、Ubuntuのバージョン等による差異も受けにくいベーシックな手法であるはずなので、ノウハウとして知っておくと便利だと思います。

必要なもの

  • 8GB以上のUSBメモリ
    • 今回は64GBのものを使用しました。ある程度の余裕があった方が良いと思います。
  • Linux PC (何でも良いし多分RasPiとかでもいい)
    • 今回使用したPC (一応)
      • ASRock Z790M-ITX
      • Intel Core i9-13900K
      • Crucial DDR5-5200 32GB × 2枚
      • Ubuntu Server 23.10

準備(省略可)

操作するディスクを間違えて他を破壊することをなるべく避けるため、個人的にはLXDで仮想マシンを作成しUSBメモリ(/dev/sda)を仮想マシンに接続しました。(LXDの初期設定等は済んでいる前提があります)
/dev/sdaは環境によって違うので十分にご注意ください。(fdisk等で要確認)

$ lxc launch ubuntu:mantic tmp --vm
$ lxc config device add tmp disk-usbmem disk source=/dev/sda
$ lxc shell tmp

fdiskで確認したところ、仮想マシン内でUSBメモリは/dev/sdbとして認識されていました。
以下、仮想マシン内での作業となっています。

蛇足であることは承知ながら、辻褄が合わなくなりそうなので一応説明に入れることにしました。
USBメモリをブロックデバイスとして触れれば何でも良いので、当然ベアメタルでもほぼ同様の手順で可能なはずです。

手順

Ubuntu Server 23.10のインストーラーisoをダウンロードし、ループバックマウントします。

# wget https://releases.ubuntu.com/23.10/ubuntu-23.10-live-server-amd64.iso
# mkdir /iso
# mount -o loop ubuntu-23.10-live-server-amd64.iso /iso

USBメモリ(/dev/sdb)のパーティションを消去しGPTで2つ切り、フォーマットしマウントします。先頭パーティションのサイズはisoのサイズを程よく超えるように作成してください。
また、2個目のパーティションは永続化用と認識させるためcasper-rwラベルを付けます。

# wipefs -a /dev/sdb
# sgdisk -n1::3G /dev/sdb
# sgdisk -n2:: /dev/sdb
# mkfs.vfat -F 32 /dev/sdb1
# mkfs.ext4 /dev/sdb2
# e2label /dev/sdb2 casper-rw
# mkdir /usbmem
# mount /dev/sdb1 /usbmem

isoファイルからUSBメモリにファイルコピーします。

# cp -a /iso/* /usbmem/

grub.cfgをお好きなエディタで編集します。インストール後のUbuntuでは御法度な行為ですが、インストーラー相手なら大丈夫かと。

# vim /usbmem/boot/grub/grub.cfg

Ubuntu Server 23.10の場合は以下の内容になっていました。

set timeout=30

loadfont unicode

set menu_color_normal=white/black
set menu_color_highlight=black/light-gray

menuentry "Try or Install Ubuntu Server" {
	set gfxpayload=keep
	linux	/casper/vmlinuz  ---
	initrd	/casper/initrd
}
grub_platform
if [ "$grub_platform" = "efi" ]; then
menuentry 'Boot from next volume' {
	exit 1
}
menuentry 'UEFI Firmware Settings' {
	fwsetup
}
else
menuentry 'Test memory' {
	linux16 /boot/memtest86+x64.bin
}
fi

menuentryをコピーし、Persistent用の項目を加えます。

(略)
menuentry "Try or Install Ubuntu Server (Persistent)" {
	set gfxpayload=keep
	linux	/casper/vmlinuz persistent
	initrd	/casper/initrd
}
menuentry "Try or Install Ubuntu Server" {
	set gfxpayload=keep
	linux	/casper/vmlinuz  ---
	initrd	/casper/initrd
}
(略)

元のmenuentryも残すことで、非永続化のインストーラーUSBとしても使用できます。
ちなみに、永続化側で書き込んだものは非永続化側では反映されていなかったので、使い分けできるかと思います。

お掃除をします。

(LXDを使用した場合)

# poweroff
$ lxc delete tmp

(その他の場合)

# umount /iso
# rmdir /iso
# umount /usbmem
# rmdir /usbmem
# rm ubuntu-23.10-live-server-amd64.iso

以上です。UEFI機ならこれで使えるはずです。BIOS機はもう持っていないので忘れました。

余談

作ったインストーラーUSBメモリの動作は仮想マシンでも簡単に確認できます。LXD便利すぎる!

lxc init test --empty --vm
lxc config device add test disk-usbmem disk boot.priority=10 source=/dev/sda
lxc start test

ここでLXD UIを開くか、GUI環境でlxc console test --type vgaする等してVGAコンソールを開くと、GRUBブートメニューが現れているはずです。

メニューエントリー選択後に起動後暫くするとlxc shell testも効くようになっていたので、環境のお膳立てに便利だと思います。

Discussion