💤

Ubuntu24 LTSをroot on ZFSでインストールする

2024/04/26に公開

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_DEFAULTinit_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