Ubuntu 20.04LTS Desktopで「ZFS on root」で構築してみた(その2)

Table of Content

広告

はじめに

前回記事で、私がデスクトップでZFSを使い始めた経緯を説明しました。今回は、実際に「ZFS on root」でUbuntu 20.04LTS Desktopをインストールしていきたいと思います。

前提条件

パーティション構成は、SSDを2台でミラー構成とし、以下を前提としています。

ZFSパーティション構成

今回のインストールでは標準のインストーラを使いません。インストーラを起動して「Ubuntuを試す」からインストールを行ってきます。
また、操作は実機ではなくopenssh-serverを起動して、リモートでSSHに接続して行うことを推奨致します。

インストール準備

SSH環境の準備

インストーラで起動し「Ubuntuを試す」をクリックしUbuntuのデスクトップを開きます。
Ctrl+Alt+Tを押してターミナルを開き、以下のコマンドを実行します。

sudo apt-add-repository universe
sudo apt update

ubuntuユーザのパスワードを設定します。

passwd

openssh-serverをインストールします。

sudo apt install --yes openssh-server

以下のコマンドを入力してIPアドレスを確認しておきます。

ip a

別のマシンから対象マシンにsshでログインしてインストール作業を続行する

ここからは別のマシンからsshで対象マシンで接続し、コピペで作業を続行します。

ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no \
ubuntu@<対象マシンのIPアドレス>

mDNSな環境であれば、IPアドレスではなくubuntu.localで名前解決できますので、以下のコマンドで…

ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no \
ubuntu@ubuntu.local

以下のコマンドでrootユーザになります。

sudo -i

以下のコマンドを入力してdebootstrap、ZFS環境をインストールします。

apt install --yes debootstrap gdisk zfs-initramfs

ディスクのフォーマット

インストール先ディスクの確認

ZFSは/dev/sda/dev/sdbのデバイス名を使うことは推奨されていません。/dev/disk/by-idからインストール先のディスクエイリアスを確認します。

ls -l /dev/disk/by-id/

作業のため環境変数に設定しておきます。今回はミラーなので2台分設定しておきます。

DISK_L=/dev/disk/by-id/<1台目のインストール先のディスクエイリアス>
DISL_R=/dev/disk/by-id/<2台目のインストール先のディスクエイリアス>

パーティションテーブルの作成

新品のディスクを想定してますが、新品でない場合はパーティションテーブルを削除します。

sgdisk --zap-all $DISK_L
sgdisk --zap-all $DISK_R

パーティションテーブルを作成していきます。

parted $DISK_L mklabel gpt
sgdisk -n1:1M:+512M -t1:EF00 $DISK_L # /boot/efi
sgdisk -n2:0:+64G   -t2:8200 $DISK_L # swap
sgdisk -n3:0:+2G    -t3:BE00 $DISK_L # bpool
sgdisk -n4:0:0      -t4:BF00 $DISK_L # rpool

2台目のディスクは1台目のパーティションテーブルをコピーし、uuidを生成します。

parted $DISK_R mklabel gpt
sgdisk $DISK_L -R $DISK_R
sgdisk -G $DISK_R

ZFSプールの作成

ブート(/boot)パーティション用のZFSプールbpoolを作成します。

zpool create \
     -o ashift=12 -d \
     -o feature@async_destroy=enabled \
     -o feature@bookmarks=enabled \
     -o feature@embedded_data=enabled \
     -o feature@empty_bpobj=enabled \
     -o feature@enabled_txg=enabled \
     -o feature@extensible_dataset=enabled \
     -o feature@filesystem_limits=enabled \
     -o feature@hole_birth=enabled \
     -o feature@large_blocks=enabled \
     -o feature@lz4_compress=enabled \
     -o feature@spacemap_histogram=enabled \
     -o feature@zpool_checkpoint=enabled \
     -O acltype=posixacl -O canmount=off \
     -O devices=off -O normalization=formD -O relatime=on -O xattr=sa \
     -O mountpoint=/boot -R /mnt \
     bpool mirror ${DISK_L}-part3 ${DISK_R}-part3

圧縮が必要であれば-O ompression=lz4を入れてもいいと思います。

ルート(/)パーティション用のZFSプールrpoolを作成します。

zpool create \
     -o ashift=12 \
     -O acltype=posixacl -O canmount=off \
     -O dnodesize=auto -O normalization=formD -O relatime=on \
     -O xattr=sa -O mountpoint=/ -R /mnt \
     rpool mirror ${DISK_L}-part4 ${DISK_R}-part4

ここでも圧縮が必要であれば-O ompression=lz4を入れてもいいと思います。

ここまでの結果を確認します。

zpool list

システムのインストール

ZFSファイルシステムの作成

roool/ROOTbpool/BOOTを作成します。

zfs create -o canmount=off -o mountpoint=none rpool/ROOT
zfs create -o canmount=off -o mountpoint=none bpool/BOOT

ファイルシステムを作成します。ここは各自の利用方法に応じて調整してください。私は以下の様にしました。

zfs create -o canmount=noauto -o mountpoint=/           rpool/ROOT/ubuntu
zfs mount rpool/ROOT/ubuntu
zfs create -o canmount=noauto -o mountpoint=/boot       bpool/BOOT/ubuntu
zfs mount bpool/BOOT/ubuntu
zfs create                                              rpool/home
zfs create -o mountpoint=/root                          rpool/home/root
zfs create                                              rpool/opt
zfs create                                              rpool/srv
zfs create -o canmount=off                              rpool/usr
zfs create                                              rpool/usr/local
zfs create -o canmount=off                              rpool/var
zfs create                                              rpool/var/lib
zfs create                                              rpool/var/log
zfs create                                              rpool/var/spool
zfs create -o com.sun:auto-snapshot=false               rpool/var/cache
zfs create -o com.sun:auto-snapshot=false               rpool/var/tmp
chmod 1777 /mnt/var/tmp
zfs create                                              bpool/BOOT/ubuntu/grub

Ubuntuのインストール

まずはdebootstrapで最小限のシステムをインストールします。

debootstrap focal /mnt

システム設定

ネットワーク関係のインストールを行います。ネットワーク関係のインストールを行います。

HOSTNAME=pc01
echo ${HOSTNAME} >/mnt/etc/hostname
sed -i -e "/^127.0.0.1/a\
127.0.1.1       ${HOSTNAME}
" /mnt/etc/hosts
cat <<EOF >/mnt/etc/netplan/01-netcfg.yaml
network:
   version: 2
   ethernets:
     enp6s0:
       dhcp4: true
EOF

リポジトリの設定をします。

cat <<EOF >/mnt/etc/apt/sources.list
deb http://jp.archive.ubuntu.com/ubuntu focal main universe

deb-src http://jp.archive.ubuntu.com/ubuntu focal main universe
deb http://security.ubuntu.com/ubuntu focal-security main universe
deb-src http://security.ubuntu.com/ubuntu focal-security main universe

deb http://jp.archive.ubuntu.com/ubuntu focal-updates main universe
deb-src http://jp.archive.ubuntu.com/ubuntu focal-updates main universe
EOF

chroot用にシステムファイルをマウントします。

mount --rbind /dev  /mnt/dev
mount --rbind /proc /mnt/proc
mount --rbind /sys  /mnt/sys

chrootします

chroot /mnt /usr/bin/env DISK_L=$DISK_L DISK_R=$DISK_R bash --login

言語とタイムゾーンを設定します。

apt update
locale-gen --purge en_US.UTF-8 ja_JP.UTF-8
update-locale LANG=en_US.UTF-8 LANGUAGE=en_US
dpkg-reconfigure --frontend noninteractive locales

ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
dpkg-reconfigure -f noninteractive tzdata

ファイル編集用にvimをインストールします。nanoでも構いません。

apt install --yes vim

パーティションの設定

EFIパーティションの設定を行います。

apt install --yes dosfstools
mkdosfs -F 32 -s 1 -n EFI ${DISK_L}-part1
mkdosfs -F 32 -s 1 -n EFI ${DISK_R}-part1
mkdir /boot/efi
mkdir /boot/efi2
cat <<EOF >>/etc/fstab
UUID=$(blkid -s UUID -o value ${DISK_L}-part1) /boot/efi  vfat umask=0022,fmask=0022,dmask=0022 0 1
UUID=$(blkid -s UUID -o value ${DISK_R}-part1) /boot/efi2 vfat umask=0022,fmask=0022,dmask=0022 0 1
EOF
mount /boot/efi
mount /boot/efi2

スワップパーティションの設定を行います。

mkswap -f ${DISK_L}-part2
mkswap -f ${DISK_R}-part2
cat <<EOF >>/etc/fstab
UUID=$(blkid -s UUID -o value ${DISK_L}-part2) none swap discard 0 0
UUID=$(blkid -s UUID -o value ${DISK_R}-part2) none swap discard 0 0
EOF
swapon -a

/tmpはRAMを使うようにします。

cp /usr/share/systemd/tmp.mount /etc/systemd/system/
systemctl enable tmp.mount

boot環境の設定

grub,カーネル,zfs用initram等をインストールします。

apt install --yes \
     grub-efi-amd64 grub-efi-amd64-signed linux-image-generic \
     shim-signed zfs-initramfs zsys
dpkg --purge os-prober
grub-probe /boot

initramfsを生成します。

update-initramfs -c -k all

/etc/default/grubを編集します。

vi /etc/default/grub
# Comment out: GRUB_TIMEOUT_STYLE=hidden
# Set: GRUB_TIMEOUT=5
# Below GRUB_TIMEOUT, add: GRUB_RECORDFAIL_TIMEOUT=5
# Remove quiet and splash from: GRUB_CMDLINE_LINUX_DEFAULT
# Uncomment: GRUB_TERMINAL=console
# Save and quit.
update-grub

grubをインストールします。ミラー構成なので2台分です。

grub-install --target=x86_64-efi \
    --efi-directory=/boot/efi \
    --bootloader-id=ubuntu \
    --recheck --no-floppy
cp -a /boot/efi/EFI /boot/efi2
grub-install \
    --target=x86_64-efi \
    --efi-directory=/boot/efi2 \
    --bootloader-id=ubuntu-2  \
    --recheck --no-floppy

zfsファイルシステムのマウント順序を固定します。

mkdir /etc/zfs/zfs-list.cache
touch /etc/zfs/zfs-list.cache/bpool
touch /etc/zfs/zfs-list.cache/rpool
ln -s /usr/lib/zfs-linux/zed.d/history_event-zfs-list-cacher.sh /etc/zfs/zed.d
zed -F &

/etc/zfs/zfs-list.cache/*が出来上がっているか確認します。

cat /etc/zfs/zfs-list.cache/bpool
cat /etc/zfs/zfs-list.cache/rpool

rpoolとbpoolをcanmount=noautoに変更します。

zfs set canmount=noauto bpool/BOOT/ubuntu
zfs set canmount=noauto rpool/ROOT/ubuntu

zedをフォアグランドに移行してCtrl+cで停止します。

fg

/etc/zfs/zfs-list.cache/*のマウントポイントを/mntから/に変更します。

sed -Ei "s|/mnt/?|/|" /etc/zfs/zfs-list.cache/*

初回リブート

Ubuntu Desktopは一旦リブートしてインストールを行います。openssh-serverをインストールします。また、mDNSも使用できるようにavahi-daemonもインストールします。

apt install --yes openssh-server avahi-daemon

rootのパスワードを設定します。

passwd

rootユーザでsshがログインできるよう/etc/ssh/sshd_configを修正します。

vi /etc/ssh/sshd_config
# Set: PermitRootLogin yes

chrootを抜けてアンマウント・プールのエクスポートを行いrebootします。

exit
mount | grep -v zfs | tac | awk '/\mnt/ { print $3}' | xargs -i{} umount -lf {}
zpool export -a
systemctl reboot

Ubuntu Desktopのインストール

ここからも別のマシンからsshで対象マシンで接続し、コピペで作業を続行します。

ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no \
ubuntu@<対象マシンのIPアドレス>

mDNSな環境であれば、IPアドレスではなくubuntu.localで名前解決できますので、以下のコマンドで…

ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no \
ubuntu@ubuntu.local

Ubuntu Desktopインストール

まずはユーザを作成します。

useradd -m -s /bin/bash -G adm,cdrom,dip,plugdev,sudo ubuntu
passwd ubuntu

Ubuntu Desktopをインストールします。私はLibreOfficeもThunderbirdは不要なので最小限のインストールをしています。Ubuntu Desktopを普通に入れたい場合はapt install --yes ubuntu-desktopとします。インストールが終えたらリブートします。

sudo -i
apt update
apt dist-upgrade --yes
apt install --yes ubuntu-desktop-minimal
localectl set-locale LANG=ja_JP.UTF-8 LANGUAGE="ja_JP:ja"
source /etc/default/locale
dpkg-reconfigure keyboard-configuration
reboot

最終調整

rootのパスワードを無効にします。

sudo usermod -p '*' root

rootユーザがsshでログイン出来ないようにします。

sudo vi /etc/ssh/sshd_config
# Remove: PermitRootLogin no
sudo systemctl restart sshd

/etc/default/grubの設定をもとに戻します。

sudo vi /etc/default/grub
# Uncomment: GRUB_TIMEOUT_STYLE=hidden
# Add quiet and splash to: GRUB_CMDLINE_LINUX_DEFAULT
# Comment out: GRUB_TERMINAL=console
# Save and quit.

sudo update-grub

以上で終了です。

参考したサイト