3年ほど前に、CentOS 6 の root ファイルシステムに ZFS を使う方法について書きました。
CentOS 6 の root ファイルシステムに ZFS を使う
当時設定したサーバは、最新の v0.8.1 にアップデートして、今も動かしています。3年間の運用中、カーネルアップデートや ZFS のアップデートの際、何回か起動できなくなり snapshot から rollback したことがありましたが、ZFS の高い信頼性(格納データに対するチェックサム、mirror構成による自己修復)を活用できたと思っています。
しかし、CentOS 7 については Btrfs raid1 が使えたので、そちらを使って構築していました。カーネルアップデートが ZFS よりは容易であるという利点があります。
信頼性はおそらく ZFS のほうが上かも。
さて、Red Hat が Btrfs を見限った(フルサポート開始をあきらめて RHEL8 から削除)ということもあり、最近になって CentOS 7 の root ファイルシステムに ZFS を使うようになりました。ところが、、、最新の zfs-dracut には問題があるようです。v0.7.13 で動作していた環境を v0.8.1 にアップデートしたら起動できなくなってしまいました。
https://github.com/zfsonlinux/zfs/issues/8913
たぶんこれが、対応していると思われます。まもなく直るでしょう。
zfs-dracut っていうのは、要するに dracut のフレームワークに乗っかって、ZFS root をマウントしてくれるだけだし、最新のスクリプトでなくてもよいと思えるので、snapshot 中の古い /usr/lib/dracut/modules.d/90zfs/ をコピーして、initramfs を再作成したら起動できました。rd.break=pre-mount で、起動を中断させてシェルに落し、次のような手順で initramfs を再作成しました。応急処置です。
# zpool import rpool
# mkdir /mnt_temp
# mount -t zfs rpool/ROOT /mnt_temp
# mkdir /mnt_temp2
# mount -t zfs -o ro rpool/ROOT@2019-04-23-0312 /mnt_temp2
# cp -rp /mnt_temp2/usr/lib/dracut/modules.d/90zfs/ /mnt_temp/usr/lib/dracut/modules.d/
# mount -t proc proc /mnt_temp/proc
# mount -t devtmpfs devtmpfs /mnt_temp/dev
# mount -t devpts devpts /mnt_temp/dev/pts
# mount -t sysfs sysfs /mnt_temp/sys
# chroot /mnt_temp
# dracut -f /boot/initramfs-3.10.0-957.21.3.el7.x86_64.img 3.10.0-957.21.3.el7.x86_64
次は、現在の稼動状態です。ThinkPad 25 の NVMe から UEFI ブートしています。
[root@hoge ~]# df -hT /
ファイルシス タイプ サイズ 使用 残り 使用% マウント位置
rpool/ROOT zfs 26G 7.7G 18G 31% /
[root@hoge ~]# cat /proc/cmdline
BOOT_IMAGE=/ROOT@/boot/vmlinuz-3.10.0-957.21.3.el7.x86_64 root=ZFS=rpool/ROOT ro crashkernel=auto elevator=deadline vconsole.keymap=jp106 int_pln_enable=1 efi=old_map
[root@hoge ~]# grep linuxefi /boot/efi/EFI/centos/grub.cfg
linuxefi /ROOT@/boot/vmlinuz-3.10.0-957.21.3.el7.x86_64 root=ZFS=rpool/ROOT ro crashkernel=auto elevator=deadline vconsole.keymap=jp106 int_pln_enable=1 efi=old_map
linuxefi /ROOT@/boot/vmlinuz-0-rescue-27a0bb3862794c69a2c05249c5e54c36 root=ZFS=rpool/ROOT ro crashkernel=auto elevator=deadline vconsole.keymap=jp106 int_pln_enable=1 efi=old_map
[root@hoge ~]# grep ^GRUB_CMD /etc/default/grub
GRUB_CMDLINE_LINUX="crashkernel=auto elevator=deadline vconsole.keymap=jp106 int_pln_enable=1 efi=old_map"
[root@hoge ~]# zpool status
pool: rpool
state: ONLINE
status: Some supported features are not enabled on the pool. The pool can
still be used, but some features are unavailable.
action: Enable all features using 'zpool upgrade'. Once this is done,
the pool may no longer be accessible by software that does not support
the features. See zpool-features(5) for details.
scan: scrub repaired 0B in 0 days 00:00:20 with 0 errors on Sat Jul 20 00:58:48 2019
config:
NAME STATE READ WRITE CKSUM
rpool ONLINE 0 0 0
nvme0n1p5 ONLINE 0 0 0
errors: No known data errors
[root@hoge ~]# zfs get all -s local
NAME PROPERTY VALUE SOURCE
rpool compression lz4 local
rpool relatime on local
rpool/ROOT mountpoint legacy local
rpool/ROOT compression lz4 local
rpool/ROOT acltype posixacl local
これは、実験的な環境ですが、この他にサーバを1台 ZFS mirror で動かしています。
CentOS 7 で ZFS root 環境を作る手順については、
こちら にまとめられています。thanks
2019-11-27追記
書き忘れていましたが、カーネルをアップデートした場合に、grub.cfg の自動更新が失敗するので、手動で grub2-mkconfig を行う必要があります。
インストール中 : kernel-3.10.0-1062.4.3.el7.x86_64
grubby fatal error: unable to find a suitable template
更新します : sudo-1.8.23-4.el7_7.1.x86_64
というメッセージが出て、grub.cfg に新しいエントリーが追加されません。
[root@hoge ~]# grep 3.10.0 /boot/efi/EFI/centos/grub.cfg
menuentry 'CentOS Linux (3.10.0-1062.4.1.el7.x86_64) 7 (Core)' --class centos --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-3.10.0-1062.4.1.el7.x86_64-advanced-8c823f06e4556631' {
linuxefi /ROOT@/boot/vmlinuz-3.10.0-1062.4.1.el7.x86_64 root=ZFS=rpool/ROOT ro crashkernel=auto elevator=deadline vconsole.keymap=jp106 int_pln_enable=1 psmouse.synaptics_intertouch=1
initrdefi /ROOT@/boot/initramfs-3.10.0-1062.4.1.el7.x86_64.img
[root@hoge ~]# grub2-mkconfig -o /boot/efi/EFI/centos/grub.cfg
Generating grub configuration file ...
Linux イメージを見つけました: /boot/vmlinuz-3.10.0-1062.4.3.el7.x86_64
Found initrd image: /boot/initramfs-3.10.0-1062.4.3.el7.x86_64.img
Linux イメージを見つけました: /boot/vmlinuz-3.10.0-1062.4.1.el7.x86_64
Found initrd image: /boot/initramfs-3.10.0-1062.4.1.el7.x86_64.img
Linux イメージを見つけました: /boot/vmlinuz-0-rescue-27a0bb3862794c69a2c05249c5e54c36
Found initrd image: /boot/initramfs-0-rescue-27a0bb3862794c69a2c05249c5e54c36.img
完了
[root@hoge ~]# grep 3.10.0 /boot/efi/EFI/centos/grub.cfg
menuentry 'CentOS Linux (3.10.0-1062.4.3.el7.x86_64) 7 (Core)' --class centos --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-3.10.0-1062.4.3.el7.x86_64-advanced-8c823f06e4556631' {
linuxefi /ROOT@/boot/vmlinuz-3.10.0-1062.4.3.el7.x86_64 root=ZFS=rpool/ROOT ro crashkernel=auto elevator=deadline vconsole.keymap=jp106 int_pln_enable=1 psmouse.synaptics_intertouch=1
initrdefi /ROOT@/boot/initramfs-3.10.0-1062.4.3.el7.x86_64.img
menuentry 'CentOS Linux (3.10.0-1062.4.1.el7.x86_64) 7 (Core)' --class centos --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-3.10.0-1062.4.1.el7.x86_64-advanced-8c823f06e4556631' {
linuxefi /ROOT@/boot/vmlinuz-3.10.0-1062.4.1.el7.x86_64 root=ZFS=rpool/ROOT ro crashkernel=auto elevator=deadline vconsole.keymap=jp106 int_pln_enable=1 psmouse.synaptics_intertouch=1
initrdefi /ROOT@/boot/initramfs-3.10.0-1062.4.1.el7.x86_64.img
if [ "x$default" = 'CentOS Linux (3.10.0-1062.4.1.el7.x86_64) 7 (Core)' ]; then default='Advanced options for CentOS Linux>CentOS Linux (3.10.0-1062.4.1.el7.x86_64) 7 (Core)'; fi;
[root@hoge ~]#
2019-12-25追記
前述の grubby のエラーについて探究していませんでしたが、調べてみると単純な話しでした。まず、/var/log/grubby というログファイルが存在することがわかったので見てみたら、次のような出力になっていました。
[root@hoge ~]# cat /var/log/grubby
...
DBG: 1894: Wed Dec 25 04:39:43 2019: command line: --grub2 -c /boot/efi/EFI/centos/grub.cfg --efi --add-kernel=/boot/vmlinuz-3.10.0-1062.9.1.el7.x86_64 --copy-default --title CentOS Linux (3.10.0-1062.9.1.el7.x86_64) 7 (Core) --args=root=ZFS=rpool/ROOT --remove-kernel=TITLE=CentOS Linux (3.10.0-1062.9.1.el7.x86_64) 7 (Core) --make-default
DBG: Image entry failed: access to /ROOT@/boot/vmlinuz-3.10.0-1062.4.3.el7.x86_64 failed
DBG: menuentry 'CentOS Linux (3.10.0-1062.4.3.el7.x86_64) 7 (Core)' --class centos --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-3.10.0-1062.4.3.el7.x86_64-advanced-8c823f06e4556631' {
DBG: load_video
DBG: set gfxpayload=keep
DBG: insmod gzio
DBG: insmod part_gpt
DBG: insmod zfs
DBG: if [ x$feature_platform_search_hint = xy ]; then
DBG: search --no-floppy --fs-uuid --set=root 8c823f06e4556631
DBG: else
DBG: search --no-floppy --fs-uuid --set=root 8c823f06e4556631
DBG: fi
DBG: linuxefi /ROOT@/boot/vmlinuz-3.10.0-1062.4.3.el7.x86_64 root=ZFS=rpool/ROOT ro crashkernel=auto elevator=deadline vconsole.keymap=jp106 int_pln_enable=1 psmouse.synaptics_intertouch=1
DBG: initrdefi /ROOT@/boot/initramfs-3.10.0-1062.4.3.el7.x86_64.img
DBG: }
DBG: Image entry failed: access to /ROOT@/boot/vmlinuz-0-rescue-27a0bb3862794c69a2c05249c5e54c36 failed
DBG: menuentry 'CentOS Linux (0-rescue-27a0bb3862794c69a2c05249c5e54c36) 7 (Core)' --class centos --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-0-rescue-27a0bb3862794c69a2c05249c5e54c36-advanced-8c823f06e4556631' {
DBG: load_video
...
ZFS 特有の /ROOT@/boot という記法を解釈できないために、vmlinuz のパスを正しく認識できず、エラーになるようです。つまり、安直にはシンボリックリンクでも張ればよいと思われます。
[root@hoge ~]# ln -s / /ROOT\@
[root@hoge ~]# ls -l / | grep ROOT
lrwxrwxrwx 1 root root 1 12月 25 06:00 ROOT@ -> /
[root@hoge ~]# ls -l /ROOT@/boot/vmlinuz-3.10.0-1062.9.1.el7.x86_64
-rwxr-xr-x 1 root root 6734016 12月 7 00:53 /ROOT@/boot/vmlinuz-3.10.0-1062.9.1.el7.x86_64
[root@hoge ~]#
これでうまくいくかどうかは、次回のアップデートカーネルが出て来たときに確認しようと思います。
思わず grubby のソースまで見てしまいましたが、ZFS の場合だけ特別に扱うようなコードは受け入れられそうにないかなと思いました。