Ubuntu24 LTSをroot on ZFSでインストールする
Ubuntu 24.04 LTSが2024/4/25にリリースされました。
拙宅ではUbuntu 20.04.6 LTSでroot on ZFSしてNASとして稼働中ですが、ブート用のSSDがエラーを出し始めたので時期的にも24.04のリリースを待ち望んでいました。
実はbetaのときにも試したんですが、debootstrapがバグのためうまくいかず、ドキドキしましたが無事修正されていました。
作業メモを残しながらインストールしたのでせっかくだから公開しようと思いましたが、自分よりも高度なことをやってる方がおられるのでそちらを見てもらってもよいかもというのと、基本はOpenZFSが公開しているUbuntu22.04LTS公式の手順そのままです。そのため、自分用の作業メモ以上の内容ではないのでご了承ください。
構成
母艦は流行りの中華製ミニPCです。これにUSB経由で2ベイの外付けのHDDを接続しています。チャチではありますが、アイドル時の消費電力が14W程度とそれなりに省電力です。
- メモリ: 16GB
- 起動ドライブ: 512GB NVMe
- 外付けHDD: WD Blue 8TBx2
システムはNVMeに入れます。ミラーにもしません。ミニPCなので拡張が面倒なのと、大事なデータはHDDをミラーするのでそれで保護します。
手順
Ubuntuダウンロード
ここからISOイメージをダウンロード。ServerでOKです。
USBメモリに書き込む
お好きなアプリを使ってください。私はRufusを使いました。
SSHでつなぐ
先ほど書き込んだUSBからブートし、「Try or Install Ubuntu」を選ぶと、インストーラが立ち上がりますが、インストーラは使わないので、こちらの手順を参考に、外部からSSHでつなぎます。SSHせずに作業もできますが、コピペできないので辛いと思います。
最小限のシステムを入れるまで
内蔵NVMeにシステムを入れていきます。
リポジトリをアップデートして必要なパッケージを準備。
sudo apt update
apt purge needrestart
apt install --yes debootstrap gdisk zfsutils-linux
systemctl stop zed
インストール対象のドライブを環境変数に設定しておく。EFI用のパーティション、スワップ、ブートパーティション、rootパーティションを確保。
DISK=/dev/disk/by-id/nvme-BIWIN_NA80V1M10-512G_2349089101262
swapoff --all
wipefs -a $DISK
blkdiscard -f $DISK
sgdisk -n1:1M:+512M -t1:EF00 $DISK
sgdisk -n2:0:+32G -t2:8200 $DISK
sgdisk -n3:0:+2G -t3:BE00 $DISK
sgdisk -n4:0:0 -t4:BF00 $DISK
ブート用のpoolとroot用のpoolを作成。
zpool create \
-o ashift=12 \
-o autotrim=on \
-o cachefile=/etc/zfs/zpool.cache \
-o compatibility=grub2 \
-o feature@livelist=enabled \
-o feature@zpool_checkpoint=enabled \
-O devices=off \
-O acltype=posixacl -O xattr=sa \
-O compression=lz4 \
-O normalization=formD \
-O relatime=on \
-O canmount=off -O mountpoint=/boot -R /mnt \
bpool ${DISK}-part3
zpool create \
-o ashift=12 \
-o autotrim=on \
-O acltype=posixacl -O xattr=sa -O dnodesize=auto \
-O compression=lz4 \
-O normalization=formD \
-O relatime=on \
-O canmount=off -O mountpoint=/ -R /mnt \
rpool ${DISK}-part4
各poolにベースになるデータセットを作る。
zfs create -o canmount=off -o mountpoint=none rpool/ROOT
zfs create -o canmount=off -o mountpoint=none bpool/BOOT
システム用の各種データセットを作成。公式の手順にあるUUIDは使わない。
zfs create -o mountpoint=/ \
-o com.ubuntu.zsys:bootfs=yes \
-o com.ubuntu.zsys:last-used=$(date +%s) rpool/ROOT/ubuntu
zfs create -o mountpoint=/boot bpool/BOOT/ubuntu
zfs create -o com.ubuntu.zsys:bootfs=no -o canmount=off rpool/ROOT/ubuntu/usr
zfs create -o com.ubuntu.zsys:bootfs=no -o canmount=off rpool/ROOT/ubuntu/var
zfs create rpool/ROOT/ubuntu/var/lib
zfs create rpool/ROOT/ubuntu/var/log
zfs create rpool/ROOT/ubuntu/var/spool
zfs create -o canmount=off -o mountpoint=/ rpool/USERDATA
zfs create -o com.ubuntu.zsys:bootfs-datasets=rpool/ROOT/ubuntu -o canmount=on -o mountpoint=/root rpool/USERDATA/root
chmod 700 /mnt/root
zfs create rpool/ROOT/ubuntu/var/lib/apt
zfs create rpool/ROOT/ubuntu/var/lib/dpkg
zfs create -o com.ubuntu.zsys:bootfs=no rpool/ROOT/ubuntu/srv
zfs create rpool/ROOT/ubuntu/var/lib/docker
zfs create rpool/ROOT/ubuntu/var/www
tmpfsを作る。
mkdir /mnt/run
mount -t tmpfs tmpfs /mnt/run
mkdir /mnt/run/lock
最低限のパッケージをインストール。今日は本家が混んでて少しダウンロードが遅かった。
debootstrap noble /mnt
しばし待つ。
grubをインストールする前の設定
キャッシュをコピー。
mkdir /mnt/etc/zfs
cp /etc/zfs/zpool.cache /mnt/etc/zfs/
ホスト名の設定。HOSTNAMEは好きな名前で。
hostname HOSTNAME
hostname > /mnt/etc/hostname
hostsファイルの編集。
vi /mnt/etc/hosts
127.0.0.1はすでにあると思うので、次の行に書き加える。
127.0.1.1 HOSTNAME
IPアドレスの設定。/etc/netplan/99_config.yaml
というファイルにしたほうがよいらしい。
cat > /mnt/etc/netplan/99_config.yaml <<___
network:
version: 2
renderer: networkd
ethernets:
enp4s0:
dhcp4: no
addresses: [192.168.x.x/24]
gateway4: 192.168.x.x
nameservers:
addresses: [192.168.x.x]
___
Ubuntu24.04から/etc/apt/sources.listではなく、/etc/apt/sources.list.d/ubuntu.sourcesというファイルに変わったらしいので注意が必要。コピーして持ってくる。/etc/apt/sources.list
にも残ってるのでとりあえずコメントアウト推奨。ミラーサイトを参考に近くて太いサイトを設定すると良いと思う。ISCCoEが良さそう。
cp /etc/apt/sources.list.d/ubuntu.sources /mnt/etc/apt/sources.list.d/
chrootする。環境変数DISKは引き続き使うので持って行く。
mount --make-private --rbind /dev /mnt/dev
mount --make-private --rbind /proc /mnt/proc
mount --make-private --rbind /sys /mnt/sys
chroot /mnt /usr/bin/env DISK=$DISK bash --login
localeを作ってvimをインストールし、タイムゾーンも設定する。
apt update
locale-gen --purge en_US.UTF-8 ja_JP.UTF-8
apt install --yes vim
ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
dpkg-reconfigure -f noninteractive tzdata
grubをインストールする
EFI/boot/efi
を作成
apt install --yes dosfstools
mkdosfs -F 32 -s 1 -n EFI ${DISK}-part1
mkdir /boot/efi
echo /dev/disk/by-uuid/$(blkid -s UUID -o value ${DISK}-part1) \
/boot/efi vfat defaults 0 0 >> /etc/fstab
mount /boot/efi
grub用ディレクトリ作成
mkdir /boot/efi/grub /boot/grub
echo /boot/efi/grub /boot/grub none defaults,bind 0 0 >> /etc/fstab
mount /boot/grub
grubのパッケージをインストール。エラーが出ても無視。
apt install --yes \
grub-efi-amd64 grub-efi-amd64-signed linux-image-generic \
shim-signed zfs-initramfs zsys
apt purge --yes os-prober
下記のエラーが出た(無視した)
Failed to open connection to "system" message bus: Failed to connect to socket /run/dbus/system_bus_socket: No such file or directory
invoke-rc.d: initscript dbus, action "reload" failed.
start-stop-daemon: unable to stat /usr/libexec/polkitd (No such file or directory)
あとでrootログインするのでrootのパスワードを設定しておく。
passwd
swapを作成
mkswap -f ${DISK}-part2
echo /dev/disk/by-uuid/$(blkid -s UUID -o value ${DISK}-part2) \
none swap discard 0 0 >> /etc/fstab
swapon -a
/tmp ディレクトリのファイルを実行できないようにする
cp /usr/share/systemd/tmp.mount /etc/systemd/system/
systemctl enable tmp.mount
グループ追加。
addgroup --system lpadmin
addgroup --system lxd
addgroup --system sambashare
リブート後の設定のためにSSHサーバをインストールしrootログインも有効にする(危険を承知で)
apt install --yes openssh-server
vi /etc/ssh/sshd_config
PermitRootLogin yes
とする
grubをインストールしていく。
grub-probe /boot
update-initramfs -c -k all
/etc/default/grub
を編集する。
vi /etc/default/grub
-
GRUB_TIMEOUT_STYLE=hidden
をコメントアウト -
GRUB_TIMEOUT
を5秒に -
GRUB_TIMEOUT
の次の行にGRUB_RECORDFAIL_TIMEOUT=5
を追加 -
GRUB_CMDLINE_LINUX_DEFAULT
をinit_on_alloc=0
だけにして、quiet splash
は削除。メモリのゼロクリアを実施しない設定。 -
GRUB_TERMINAL=console
をコメントアウト
その状態でgrubをupdate
update-grub
grubをインストールして、grub-initrd-fallback.service
を無効化
grub-install --target=x86_64-efi --efi-directory=/boot/efi \
--bootloader-id=ubuntu --recheck --no-floppy
systemctl mask grub-initrd-fallback.service
ZFS関連のファイルを作ります。
mkdir /etc/zfs/zfs-list.cache
touch /etc/zfs/zfs-list.cache/bpool
touch /etc/zfs/zfs-list.cache/rpool
zed -F &
次のコマンドで、ファイルの内容があればよいらしい。
cat /etc/zfs/zfs-list.cache/bpool
cat /etc/zfs/zfs-list.cache/rpool
zed
を終了する。
fg
Press Ctrl-C.
cacheのマウントポイントを修正。
sed -Ei "s|/mnt/?|/|" /etc/zfs/zfs-list.cache/*
chroot環境から抜けて、マウント解除
exit
mount | grep -v zfs | tac | awk '/\/mnt/ {print $3}' | \
xargs -i{} umount -lf {}
poolを切り離す。/mntがbusyだと言われ、rpoolが切り離されなかったがどうしようもないと思うので無視。
zpool export -a
reboot
コマンドでリブートすると、初回は(initramfs)
というプロンプトのまま止まると思うので、
(initramfs) zpool import -f rpool
(initramfs) exit
とすれば無事起動すると思う。次回からは不要。
一般ユーザを作成する
username=xxxxx
HDDでアクセスが遅いのもあれなのでNVMe上につくる。これは好みで。
zfs create -o com.ubuntu.zsys:bootfs-datasets=rpool/ROOT/ubuntu -o canmount=on -o mountpoint=/home/$username rpool/USERDATA/$username
adduser $username
cp -a /etc/skel/. /home/$username
chown -R $username:$username /home/$username
usermod -a -G adm,cdrom,dip,lpadmin,lxd,plugdev,sambashare,sudo $username
HDDをミラーにする
ついでに外付けのHDDにパーティションを作り、ミラープールを作る。パーティションを作ってプールを作る方が良いと何処かに書いていた。
apt install gdisk
sgdisk -Z -o -a 8 -n 1:40 -t 1:bf01 /dev/disk/by-id/ata-WDC_WD80EAAZ-00BXBB0_WD-RD09811E
sgdisk -Z -o -a 8 -n 1:40 -t 1:bf01 /dev/disk/by-id/ata-WDC_WD80EAAZ-00BXBB0_WD-RD09BUME
zpool create -o ashift=12 -O compression=lz4 -O atime=off -O snapdir=visible -O canmount=off -O acltype=posixacl -O xattr=sa -O mountpoint=none zpool mirror /dev/disk/by-id/ata-WDC_WD80EAAZ-00BXBB0_WD-RD09811E-part1 /dev/disk/by-id/ata-WDC_WD80EAAZ-00BXBB0_WD-RD09BUME-part1
ここまでで最低限のシステムインストールまで終了したと思います。ここからdockerを入れたり、sambaを入れたり、旧NASからコピーしてきたりとありますが、それはまた別の機会に。
PermitRootLogin
のコメントアウトくらいはしておいたほうがいいかもしれない。自分は自宅なのでそれほど気にしない。
以上です。
Discussion