配置ZFS自动启动¶
在完成 Docker ZFS 存储驱动 配置并使用之后,如果重启物理主机,你会惊讶地发现 docker.service
启动失败,原因是 /var/lib/docker
没有就绪。
手工启动zfs¶
此时检查ZFS会发现 zpool
是空的:
# zpool list
no pools available
zfs list
no datasets available
检查
zpool import
可以看到存储池是就绪的(但是没有导入):
# zpool import
pool: zpool-docker
id: 4553342928876801142
state: ONLINE
action: The pool can be imported using its name or numeric identifier.
config:
zpool-docker ONLINE
nvme0n1p9 ONLINE
手工导入:
zpool import zpool-docker
此时再次检查就能够看到zfs文件系统已经挂载 ( df -h
):
Filesystem Size Used Avail Use% Mounted on
...
zpool-docker 102G 6.4G 95G 7% /var/lib/docker
并且 zfs list
可以看到所有该存储池下文件系统:
NAME USED AVAIL REFER MOUNTPOINT
zpool-docker 8.04G 94.7G 6.34G /var/lib/docker
zpool-docker/03ebbb6554f2f15ee36cedacade890f080081631375a60e3796fd160e6788a6d 104K 94.7G 16.6M legacy
zpool-docker/09315a96dcbfbfbc33929960905fc09793bd731a7645cdc625d56079d1643545 112K 94.7G 16.6M legacy
...
配置自动导入和启动ZFS¶
ZFS被其创建者视为”零管理”文件系统,所以配置ZFS非常简单,主要使用 zfs
和 zpool
命令
自动启动¶
为了实现ZFS的”零管理”:
必须启用
zfs-import-cache.service
以导入存储池(import pools):zfs-import-cache.service
是通过/etc/zfs/zpool.cache
配置来导入ZFS存储池必须启用
zfs-mount.service
以挂载存储池中可用的文件系统(这样就不需要使用/etc/fstab
来挂载ZFS)
对于每个想要 自动 通过 zfs-import-cache.service
自动实现自动导入的存储池,可以执行如下命令:
zpool set cachefile=/etc/zfs/zpool.cache <pool>
备注
从 OpenZFS 0.6.5.8 版本开始,必须明确激活ZFS服务
除了 zfs-mount.service
以外,也可以使用 zfs-mount-generator
来完成 zfs-import-cache.service
之后的zfs挂载,区别在于 zfs-mount.service
不能保证 /var
目录足够提前完成挂载,此时就需要使用 zfs-mount-generator
来替代实现
方法一: zfs-import-cache
+ zfs-mount
¶
激活
zfs-import-cache
+zfs-mount
:
sudo systemctl enable zfs-import-cache.service
sudo systemctl enable zfs-mount.service
备注
升级 Arch Linux 系统可能启动时日志显示报错:
[ 0.879506 ] systemd[306]: /usr/lib/systemd/system-generators/zfs-mount-generator failed with exit status 127.
启动后执行 zpool import
报错:
zpool: error while loading shared libraries: libcrypto.so.1.1: cannot open shared object file: No such file or directory
原因是系统默认安装最新版本的 openssl 3.0.7-2
,自动卸载了不需要的 openssl-1.1 1.1.1.s-2
,但是第三方安装需要这个库,所以单独安装:
pacman -S openssl-1.1
这样就不会再出现 zpool import
报lib库文件问题,启动日志也就不报错了。为避免后续升级 openssl-1.1
被自动清理,采用 Pacman 的版本hold配置,也就是修订 /etc/pacman.conf
添加:
IgnorePkg = openssl-1.1
不过,对于 /var
目录及其下子目录,挂载还是需要采用 zfs-mount-generator
方法二: zfs-import-cache
+ zfs-mount-generator
¶
对于 Docker ZFS 存储驱动 ,ZFS存储池是位于 /var/lib/docker
,也就是 /var
子目录。如果采用上文 zfs-import-cache
+ zfs-mount
会发现启动还是没有自动挂载。
原因是 /var
目录需要在系统启动早期时挂载,此时 zfs
内核模块尚未加载。这就导致 zpool-docker
这个 zpool
导入失败。
对于上述问题,需要改为使用 zfs-mount-generator
替代 zfs-mount.service
来确保启动时创建好 systemd mount units
,这样 Systemd进程管理器 就会自动基于 mount units
完成文件系统挂载而无需使用 zfs-mount.service
:
创建
/etc/zfs/zfs-list.cache
目录:mkdir /etc/zfs/zfs-list.cache
激活 ZFS Event Daemon(ZED) 脚本(称为 ZEDLET) 请求来创建一系列ZFS文件系统挂载列表(对于OpenZFS>=2.0.0这个链接是自动创建的):
ln -s /usr/lib/zfs/zed.d/history_event-zfs-list-cacher.sh /etc/zfs/zed.d
激活
zfs.target
和zfs-zed.service
并启动zfs-zed.service
systemctl enable zfs-import-cache systemctl disable zfs-mount systemctl enable zfs.target systemctl enable zfs-zed.service systemctl start zfs-zed.service
在
/etc/zfs/zfs-lilst.cache
目录下创建存储池命名的空文件:touch /etc/zfs/zfs-list.cache/<pool-name>
检查
/etc/zfs/zfs-list.cache/<pool-name>
内容,如果这个文件是空的,则确保zfs-zed.service
正在运行情况下,然后通过以下命令修改ZFS文件系统的canmount
属性:zfs set canmount=off zroot/fs1
这个命令会导致ZFS的事件被ZED捕获,此时就会运行ZEDLET来更新 /etc/zfs/zfs-list.cache
目录下文件内容。如果此时检查了 /etc/zfs/zfs-list.cache/<pool-name>
有内容之后,再将文件系统重新设置 canmount
属性:
zfs set canmount=on zroot/fs1
备注
我这里没有采用设置 zpool/zpool-docker
的 canmount
属性开关,是因为我这时刚重启主机, zpool-docker
尚未自动导入。所以我采用了命令 zpool import zpool-docker
命令,也同样可以触发 ZED
自动更新 /etc/zfs/zfs-list.cache/zpool-docker
内容。anyway,只要有ZED事件发生就能触发更新。
完整的针对
zpool-docker
zpool存储池的操作命令如下:
mkdir /etc/zfs/zfs-list.cache
systemctl enable zfs-import-cache
systemctl disable zfs-mount
systemctl enable zfs.target
systemctl enable zfs-zed.service
systemctl start zfs-zed.service
touch /etc/zfs/zfs-list.cache/zpool-docker
# 触发 /etc/zfs/zfs-list.cache/zpool-docker 更新
zfs set canmount=off zpool/zpool-docker
zfs set canmount=on zpool/zpool-docker
然后重新启动操作系统观察 /var/lib/docker
就是正常自动挂载的:
Filesystem Size Used Avail Use% Mounted on
...
zpool-docker 102G 6.8G 95G 7% /var/lib/docker
couldn't start libzfs
¶
我在完成 zfs-import-cache
+ zfs-mount-generator
配置之后,确实启动之后自动导入 zpool/zpool-docker
并挂载好 /var/lib/docker
,但是我发现 dmesg -T
依然有一个ZFS相关报错:
[Mon Nov 21 15:21:34 2022] zfs-mount-generator[322]: couldn't start libzfs, ignoring
[Mon Nov 21 15:21:35 2022] ZFS: Loaded module v2.1.6-1, ZFS pool version 5000, ZFS filesystem version 5
暂时没有发现 zpool
和 zfs
问题,待查