了解 DKMS 与 KABI
在 Linux 中,DKMS 和 KABI 是两个与内核模块和驱动程序管理相关的术语,它们具有不同的含义和作用。
DKMS (Dynamic Kernel Module Support):
- DKMS 是一个框架,旨在允许用户空间的软件(如第三方内核模块)在 Linux 内核升级时自动重新编译和安装。这是为了维护内核模块和当前运行内核版本之间的兼容性。
- 当您安装了使用 DKMS 的内核模块(如
zfs-dkms
),每当系统内核更新时,DKMS 会自动重新构建该模块以适应新的内核版本,这样用户就不需要手动重新编译模块。 - DKMS 非常适合于滚动更新的系统或者那些经常需要更新内核的情况,因为它简化了内核模块的维护过程。
KABI (Kernel Application Binary Interface):
- KABI 是指 Linux 内核的应用程序二进制接口,它定义了内核提供给加载的模块(如驱动程序)的稳定符号和接口。只要 KABI 保持稳定,预编译的内核模块就可以在新的内核版本上运行而无需重新编译。
- 一些 Linux 发行版(如 Red Hat Enterprise Linux 和其衍生发行版)承诺在一个主要版本的生命周期内保持 KABI 稳定。这意味着为这些内核编译的模块可以在同一主要版本的任何未来更新中使用,而无需担心兼容性问题。
- KABI 的稳定性对于企业环境非常重要,因为它允许管理员安全地应用内核更新而不会破坏现有的内核模块。
总的来说,DKMS 是一个帮助自动处理内核模块编译的系统,而 KABI 是 Linux 内核提供的一组稳定的接口,保证了内核模块的二进制兼容性。这两者都是为了解决内核更新可能带来的模块兼容性问题,但它们的方法和适用场景不同。
了解 zfs-dkms 与 zfs-kmod
前面我们了解了 DKMS 与 KABI,那它们与 zfs-dkms、zfs-kmod 有什么关系了?简单理解 zfs-dkms 是 ZFS 的 DKMS 实现方式,zfs-kmod 是 ZFS 的 KABI 实现方式。
-
zfs-dkms 是 ZFS 文件系统的 DKMS 实现方式。它会利用 DKMS 框架来自动为新的内核版本重新编译 ZFS 内核模块。这种方式提供了灵活性和方便性,特别是在那些频繁更新内核的系统上。
zfs-dkms
包含了 ZFS 文件系统的动态内核模块源码。- DKMS 代表 Dynamic Kernel Module Support(动态内核模块支持),可以在内核更新时自动重新编译并安装内核模块。
- 当您安装
zfs-dkms
并更新内核时,dkms
系统会自动为新的内核版本重新构建 ZFS 模块,从而确保 ZFS 文件系统在内核更新后依然可以正常工作。 zfs-dkms
在不同版本的内核上更加灵活,因为它不依赖于预编译的模块。
-
zfs-kmod(包名:
kmod-zfs
)是 ZFS 文件系统的预编译内核模块,它符合特定 Linux 发行版所提供的 KABI。使用这种方式,您直接安装特定内核版本的预编译模块,无需在本地编译。这通常用于那些内核更新不频繁,或者需要保持内核接口稳定性的环境中。kmod-zfs
包含了为特定内核版本预编译的 ZFS 内核模块。- 这些模块是专门为配合您当前运行的内核而构建的,因此它们不需要重新编译即可立即使用。
- 当您更新内核时,您必须确保也有一个与新内核版本匹配的
kmod-zfs
包可用,否则 ZFS 文件系统可能无法加载或工作。 kmod-zfs
更适合在内核更新不频繁或者在稳定性至关重要的环境中使用,因为它避免了重新编译的需要,但这也意味着在内核更新后,您需要等待或寻找新版本的kmod-zfs
。
在选择安装哪种方式时,您需要根据您的系统特点和需求来决定。对于在稳定性至关重要的生产环境中,可能更倾向于使用 kmod-zfs
。而对于那些经常升级内核或者使用滚动发行版的用户,zfs-dkms
可能是更好的选择。总结来说,zfs-dkms
提供了更大的灵活性和便利性,尤其是在内核经常更新的情况下,而 zfs-kmod
提供了对特定内核版本的直接支持,可能在某些环境中更稳定。您的选择取决于您的系统环境,以及您对 ZFS 文件系统稳定性和维护方便性的需求。
安装 ZFS
了解了 zfs-dkms 与 zfs-kmod 后,对于我们安装 ZFS 来说,就更加简单了,我们根据自己的实际需求选择安装方式即可。
ZFS-DKMS 方式安装 ZFS
# 启用 EPEL(企业 Linux 的额外软件包)存储库
[root@demo ~]# dnf install epel-release -y
# 从官方 OpenZFS 存储库 安装 ZFS 包
[root@demo ~]# dnf install -y https://zfsonlinux.org/epel/zfs-release-2-3$(rpm --eval "%{dist}").noarch.rpm
# 默认情况下,ZFS 存储库提供 DKMS 包,为确保您使用的是 DKMS 存储库,您可以运行以下命令进行启用。
[root@demo ~]# dnf config-manager --enable zfs
# 在安装 ZFS DKMS 包之前,您需要安装必要的开发工具,开发者工具依赖内核开发工具(kernel-devel)和内核开发头(kernel-headers)文件。
[root@demo ~]# dnf groupinstall "Development Tools" -y
# 删除旧内核开发工具
[root@demo ~]# dnf remove kernel-devel
# 因为删除旧内核的时候会同时删除 openssl-devel,所以在安装新的 kernel-devel 之前,先安装 openssl-devel,安装的 kernel-devel 必须与现有内核版本一致。
[root@demo ~]# dnf install openssl-devel
[root@demo ~]# dnf --disablerepo=\* --enablerepo=elrepo-kernel install -y kernel-lt-devel.x86_64
# kernel-headers-5.14.0-362.18.1.el9_3.0.1.x86_64 是安装 Development Tools 时 gcc 必须的。
[root@demo ~]# rpm -qa | grep kernel
kernel-lt-core-6.1.80-1.el9.elrepo.x86_64
kernel-lt-modules-6.1.80-1.el9.elrepo.x86_64
kernel-lt-6.1.80-1.el9.elrepo.x86_64
kernel-lt-tools-libs-6.1.80-1.el9.elrepo.x86_64
kernel-lt-tools-6.1.80-1.el9.elrepo.x86_64
kernel-srpm-macros-1.0-13.el9.noarch
kernel-headers-5.14.0-362.18.1.el9_3.0.1.x86_64
kernel-lt-devel-6.1.80-1.el9.elrepo.x86_64
# 内核开发工具必须与现在内核版本一致 kernel-lt-devel-6.1.80-1.el9.elrepo.x86_64
[root@demo ~]# uname -r
6.1.80-1.el9.elrepo.x86_64
# 安装 zfs-dkms
[root@demo ~]# dnf install -y zfs-dkms
# 查看 dkms 状态
[root@demo ~]# dkms status
zfs/2.1.15: added
# 安装 zfs(编译安装 zfs)
[root@demo ~]# dkms install zfs/2.1.15
# 安装 zfs 命令行工具
[root@demo ~]# dnf install -y zfs
# 验证是否安装成功
[root@demo ~]# dkms status
zfs/2.1.15, 6.1.80-1.el9.elrepo.x86_64, x86_64: installed
# 启用 dkms 存储库,禁用 kmod 存储库
[root@demo ~]# dnf config-manager --enable zfs
[root@demo ~]# dnf config-manager --disable zfs-kmod
ZFS-KMOD 方式安装 ZFS
默认情况下 ZFS 存储库使用 DKMS 包安装方式。如果要使用 kABI-tracking kmod (ZFS-KMOD) 包安装方式,您需要禁用 DKMS 存储库并启用该 kmod 存储库。需要注意的是,当使用 zfs-kmod 方式安装 zfs 时,由于 Linux 发行版的官方很可能只支持默认内核版本,比如: RockyLinux 9.3 自带 ZFS 只支持 5.14.0
内核版本,在安装 ZFS 的时候需要 kernel-core 5.14.0-362.8.1.el9_3.x86_64
和 kernel-modules-core 5.14.0-362.18.1.el9_3.0.1
包,这时候如果您的内核升级至 6.x 版本,再使用 ZFS-KMOD 方式安装 zfs 就不适用了,后面在加载 modprobe zfs
模块时,会出现 modprobe: FATAL: Module zfs not found in directory /lib/modules/6.1.45-1.el9.elrepo.x86_64
类似报错,这种情况下建议使用 DKMS 方式安装 ZFS。
# 禁用 dkms 存储库,启用 kmod 存储库
[root@demo ~]# dnf config-manager --disable zfs
[root@demo ~]# dnf config-manager --enable zfs-kmod
# 执行此命令可能需要几分钟时间,具体取决于您的系统性能。
[root@demo ~]# dnf install -y zfs
设置开机自动加载 ZFS 模块
# 加载 ZFS 内核模块
[root@demo ~]# modprobe zfs
# 检测是否加载成功
[root@demo ~]# lsmod | grep zfs
zfs 4046848 0
zunicode 339968 1 zfs
zzstd 593920 1 zfs
zlua 192512 1 zfs
zavl 20480 1 zfs
icp 331776 1 zfs
zcommon 114688 2 zfs,icp
znvpair 118784 2 zfs,zcommon
spl 126976 6 zfs,icp,zzstd,znvpair,zcommon,zavl
# 配置开机自动加载
echo "zfs" >> /etc/modules-load.d/zfs.conf
现在,您已经成功在 Rocky Linux 9 上部署了 ZFS 文件系统了。如果您使用的是 ZFS-DKMS 方式部署,每当内核更新时,ZFS 内核模块都会自动进行重新编译,以此确保在各个内核版本间保持优良的兼容性。
ZFS 异常排查
在 ZFS 文件系统中,zfs-import-cache
、zfs-import-scan
、zfs-mount
、zfs-share
和 zfs-zed
是几个重要的服务,它们各自有不同的职责和作用,当您的 ZFS 文件系统出现任何异常,建议从以下 ZFS 服务进行排错。
zfs-import-cache
:
这个服务负责导入存储池,使用缓存文件来加快存储池的导入过程。ZFS 会在/etc/zfs/zpool.cache
文件中保存存储池的信息,这使得系统在重启时可以快速地重新导入存储池。这个缓存文件包含了关于存储池配置的信息,比如磁盘布局和文件系统属性。zfs-import-scan
:
与zfs-import-cache
服务不同,zfs-import-scan
服务在没有可用的缓存文件时,通过扫描所有可用的磁盘来查找和导入 ZFS 存储池。这个服务在系统中没有找到zpool.cache
或者缓存文件已经过时的情况下是非常有用。zfs-mount
:
这个服务负责在系统启动时自动挂载 ZFS 文件系统。它会遍历已导入的存储池,并根据存储池中各文件系统的属性挂载它们。zfs-share
:
zfs-share
服务用于在系统启动时自动共享 ZFS 文件系统。这可能涉及到通过 NFS 或 Samba 等协议共享文件系统。如果文件系统的属性设置为共享,这个服务会确保它们在启动时变得可用。zfs-zed
:
zed
是 ZFS 事件守护进程(ZFS Event Daemon)的简称。这个服务监听并响应 ZFS 事件,例如: 磁盘故障、存储池状态变化或其他系统事件。zed
可以配置来发送邮件提醒、自动替换坏盘或执行自定义脚本来处理各种事件。
这些服务共同确保了 ZFS 文件系统在系统启动时能够正确地导入、挂载和共享,同时还能够响应运行时发生的事件。由于这些服务对于 ZFS 的正常运行至关重要,通常建议在系统启动时自动启动它们。如果需要手动控制这些服务,可以使用 systemctl
命令来启动、停止、重启或检查它们的状态。
[root@demo ~]# systemctl status zfs-share
● zfs-share.service - ZFS file system shares
Loaded: loaded (/usr/lib/systemd/system/zfs-share.service; enabled; preset: enabled)
Active: active (exited) since Wed 2024-03-06 16:12:20 CST; 17min ago
Docs: man:zfs(8)
Process: 1906 ExecStart=/sbin/zfs share -a (code=exited, status=0/SUCCESS)
Main PID: 1906 (code=exited, status=0/SUCCESS)
CPU: 13ms
Mar 06 16:12:20 demo systemd[1]: Starting ZFS file system shares...
Mar 06 16:12:20 demo systemd[1]: Finished ZFS file system shares.
[root@demo ~]# systemctl status zfs-mount
● zfs-mount.service - Mount ZFS filesystems
Loaded: loaded (/usr/lib/systemd/system/zfs-mount.service; enabled; preset: enabled)
Active: active (exited) since Wed 2024-03-06 16:12:13 CST; 17min ago
Docs: man:zfs(8)
Process: 1493 ExecStart=/sbin/zfs mount -a (code=exited, status=0/SUCCESS)
Main PID: 1493 (code=exited, status=0/SUCCESS)
CPU: 19ms
Mar 06 16:12:13 demo systemd[1]: Starting Mount ZFS filesystems...
Mar 06 16:12:13 demo systemd[1]: Finished Mount ZFS filesystems.
[root@demo ~]# systemctl status zfs-zed
● zfs-zed.service - ZFS Event Daemon (zed)
Loaded: loaded (/usr/lib/systemd/system/zfs-zed.service; enabled; preset: enabled)
Active: active (running) since Wed 2024-03-06 16:12:13 CST; 17min ago
Docs: man:zed(8)
Main PID: 1541 (zed)
Tasks: 4 (limit: 99368)
Memory: 3.5M
CPU: 208ms
CGroup: /system.slice/zfs-zed.service
└─1541 /sbin/zed -F
Mar 06 16:12:13 demo systemd[1]: Started ZFS Event Daemon (zed).
Mar 06 16:12:13 demo zed[1541]: ZFS Event Daemon 2.1.15-1 (PID 1541)
Mar 06 16:12:13 demo zed[1541]: Processing events since eid=0
Mar 06 16:12:14 demo zed[1558]: eid=3 class=pool_import pool='SSD'
[root@demo ~]# systemctl status zfs-import-cache
● zfs-import-cache.service - Import ZFS pools by cache file
Loaded: loaded (/usr/lib/systemd/system/zfs-import-cache.service; enabled; preset: enabled)
Active: active (exited) since Wed 2024-03-06 16:12:13 CST; 17min ago
Docs: man:zpool(8)
Process: 969 ExecStart=/sbin/zpool import -c /etc/zfs/zpool.cache -aN $ZPOOL_IMPORT_OPTS (code=exited, status=0/SUCCESS)
Main PID: 969 (code=exited, status=0/SUCCESS)
CPU: 70ms
Mar 06 16:12:13 demo systemd[1]: Starting Import ZFS pools by cache file...
Mar 06 16:12:13 demo systemd[1]: Finished Import ZFS pools by cache file.
[root@demo ~]# systemctl status zfs-import-scan
○ zfs-import-scan.service - Import ZFS pools by device scanning
Loaded: loaded (/usr/lib/systemd/system/zfs-import-scan.service; disabled; preset: disabled)
Active: inactive (dead)
Docs: man:zpool(8)
关于 ZFS 更新
如果您已经使用 ZFS 文件系统构建了存储池,并考虑更新 ZFS 版本或者升级 Rocky Linux 操作系统,建议您首先备份存储池中的重要数据。通常情况下,在更新软件或操作系统的过程中,建议保持数据的完整性和安全性。需要指出的是,卸载 ZFS 软件并重新安装,并不会直接影响到已存在的 ZFS 存储池。这是因为 ZFS 设计之中包含了一种健壮的特性,即将文件系统的元数据分布式存储于存储池的所有磁盘上。这意味着,即便在卸载 ZFS 软件之后,存储池的配置和数据仍被保留在磁盘上。当您在重新安装了 ZFS 软件并重启操作系统之后,ZFS 存储池通常能够被自动识别并顺利地恢复到工作状态。操作系统会读取磁盘上的元数据,重新组装存储池,使得原先的文件系统可用,就如同之前未进行升级前一样。尽管如此,备份仍然是升级和维护过程中的一个最佳实践,以防万一出现意外情况导致数据丢失。因此,在执行任何可能影响系统数据的操作之前,确保对关键数据进行了备份。
写在最后
至此,我们已经成功在系统上部署了 ZFS,为我们的数据管理奠定了坚实的基础。然而,理解和使用 ZFS 的旅程还远未结束。接下来,我们将进入到下一个重要的步骤 – 存储池管理。这将是我们对 ZFS 进一步深入探索的重要一步,让我们一起期待接下来的学习旅程吧。
变更记录
- 2024-03-06
- 增加【zfs-dkms】与【zfs-kmod】区别说明。
- 拆分 ZFS 两种不同方式安装细化说明。
- 增加【ZFS 异常排查】。
- 增加【关于 ZFS 更新】。
根据指引步骤安装完zfs后,执行“modprobe zfs”内核模块加载时提示:modprobe: FATAL: Module zfs not found in directory /lib/modules/6.1.45-1.el9.elrepo.x86_64
请问是哪里出错了;
烦请指导,谢谢!
如果更新了 Rocky Linux 的内核版本,不建议使用 zfs-kmod 方式安装 zfs,而应该采用 zfs-dkms 方式安装。
查看内核版本:
[root@demo ~]# uname -r
6.1.33-1.el9.elrepo.x86_64
查看 dkms 状态,确保内核版本是一致的,如果您正在使用 DKMS,确保您已经安装了与你的内核版本匹配的内核头文件,这对于 DKMS 构建内核模块是必须的。
[root@demo ~]# dkms status
zfs/2.1.12, 6.1.33-1.el9.elrepo.x86_64, x86_64: installed
如果不一致,可以手动安装
dkms install zfs/版本号
在執行”dnf –disablerepo=* –enablerepo=elrepo-kernel install -y kernel-lt-devel.x86_64″ 可能連不上elerpo的鏡像,可以參考中國清華大學的方式修改文件裡的 kernel mirrorlist,再選擇自己偏好的鏡像。
中國清華大學修改elerpo連結 https://mirrors.tuna.tsinghua.edu.cn/help/elrepo/
elrepo.org官方鏡像列表網站 https://elrepo.org/wiki/doku.php?id=download
可参考此文:在 Rocky Linux 8 & 9 中启用 EPEL、REMI、RPM Fusion 仓库