Gentoo上运行ZFS(xcloud)
我在重新构建的xcloud比基本上,重新构建了基于 Gentoo Linux 的 移动云架构 :
采用 macOS 和 Gentoo Linux 双启动,通过macOS的disk utility对磁盘进行重新分区,空出部分磁盘分区给Linux使用
由于不是一次性完成磁盘划分,而且我需要分阶段缩减macOS磁盘空间,所以为Getoo Linux提供的存储磁盘分区也是不断增加的
当前状态
使用
fdisk -l
检查当前磁盘分区,其中分区4是我最初安装 Gentoo Linux 的系统分区,分区3则是我刚刚从macOS中调整分区获得的空白分区,也就是准备用于ZFS存储的分区
Disk /dev/nvme0n1: 953.87 GiB, 1024209543168 bytes, 2000409264 sectors
Disk model: SAMSUNG MZVL21T0HCLR-00B00
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 18605302-CCCB-46EC-B43E-1514878C11E5
Device Start End Sectors Size Type
/dev/nvme0n1p1 40 409639 409600 200M EFI System
/dev/nvme0n1p2 409640 1000231247 999821608 476.8G Apple APFS
/dev/nvme0n1p3 1000232960 1750198271 749965312 357.6G Microsoft basic data
/dev/nvme0n1p4 1750198272 2000408575 250210304 119.3G Linux filesystem
安装
和 Gentoo上运行ZFS 实践相同,首先安装OpenZFS提供的ZFS软件:
emerge --ask sys-fs/zfs
警告
每次内核编译之后,都需要重新 emerge sys-fs/zfs-kmod
,即使内核修改是微不足道的。如果你在merge了内核模块之后重新编译内核,则可能会是的zpool进入不可中断的睡眠(也就是不能杀死的进程)或者直接crash。
每次内核变更(例如 升级Gentoo ,执行以下命令 remerge zfs-kmod :
emerge -va @module-rebuild
ZFS Event Daemon通知
ZED(ZFS Event Daemon)监控ZFS内核模块产生的事件: 当一个 zevent
(ZFS Event)发出是,ZED将为对应的zevent分类运行一个 ZEDLETs
(ZFS Event Daemon Linkage for Executable Tasks)。
配置
/etc/zfs/zed.d/zed.rc
:
/etc/zfs/zed.d/zed.rc
配置案例,激活通知邮件地址以及定期发送pool健康通知##
# Email address of the zpool administrator for receipt of notifications;
# multiple addresses can be specified if they are delimited by whitespace.
# Email will only be sent if ZED_EMAIL_ADDR is defined.
# Enabled by default; comment to disable.
#
ZED_EMAIL_ADDR="[email protected]"
##
# Notification verbosity.
# If set to 0, suppress notification if the pool is healthy.
# If set to 1, send notification regardless of pool health.
#
ZED_NOTIFY_VERBOSE=1
OpenRC
配置 openrc 设置ZFS在操作系统启动时启动:
# 多数情况下只需要配置 zfs-import 和 zfs-mount
rc-update add zfs-import boot
rc-update add zfs-mount boot
# zfs-share 是提供NFS共享
rc-update add zfs-share default
# zfs-zed 是ZFS Event Daemon用于处理磁盘hotspares替换以及故障的电子邮件通知
rc-update add zfs-zed default
备注
多数情况下只需要配置 zfs-import 和 zfs-mount
zfs-share 是提供NFS共享
zfs-zed 是ZFS Event Daemon用于处理磁盘hotspares替换以及故障的电子邮件通知
备注
我的gentoo实践中没有使用 Systemd进程管理器 ,而是采用轻量级 OpenRC
内核
目前尚未定制内核,待后续实践...
使用
使用 parted分区工具 工具对磁盘分区进行检查:
parted
检查当前磁盘分区parted /dev/nvme0n1 print
输出显示:
parted
检查当前磁盘分区显示分区3具备384GModel: SAMSUNG MZVL21T0HCLR-00B00 (nvme)
Disk /dev/nvme0n1: 1024GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:
Number Start End Size File system Name Flags
1 20.5kB 210MB 210MB fat32 EFI System Partition boot, esp
2 210MB 512GB 512GB
3 512GB 896GB 384GB msftdata
4 896GB 1024GB 128GB xfs primary
警告
磁盘分区操作是高危操作,务必提前备份,特别是已有多个分区在使用中,特别容易出现操作错误导致分区破坏。慎重!!!
磁盘分区: 删除掉第3分区(原先使用 macOS 的diskutils工具调整磁盘后空出分区,并重建分区用于ZFS存储
parted /dev/nvme0n1 rm 3
此时分区3被删除,此时再次检查分区
parted
检查当前磁盘分区parted /dev/nvme0n1 print
显示分区3已经消失了:
parted
检查当前磁盘分区显示分区3已经被删除了Model: SAMSUNG MZVL21T0HCLR-00B00 (nvme)
Disk /dev/nvme0n1: 1024GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:
Number Start End Size File system Name Flags
1 20.5kB 210MB 210MB fat32 EFI System Partition boot, esp
2 210MB 512GB 512GB
4 896GB 1024GB 128GB xfs primary
再次执行 parted分区工具 工具来完成分区创建,一定要确保分区位置不要覆盖现有使用分区:
parted
创建分区3parted -s -a optimal /dev/nvme0n1 mkpart primary 512GB 896GB
parted /dev/nvme0n1 name 3 zpool-data
怎么检查分区是否正确(大小和位置),我使用 parted /dev/nvme0n1 print
和 fdisk -l /dev/nvme0n1
分别检查,可以看到分区3创建正确,没有出现分区错位问题:
parted /dev/nvme0n1 print
输出显示重新创建的分区3Model: SAMSUNG MZVL21T0HCLR-00B00 (nvme)
Disk /dev/nvme0n1: 1024GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:
Number Start End Size File system Name Flags
1 20.5kB 210MB 210MB fat32 EFI System Partition boot, esp
2 210MB 512GB 512GB
3 512GB 896GB 384GB zpool-data
4 896GB 1024GB 128GB xfs primary
fdisk -l /dev/nvme0n1
显示重新创建的分区3,可以看到和之前记录完全一致分区Disk /dev/nvme0n1: 953.87 GiB, 1024209543168 bytes, 2000409264 sectors
Disk model: SAMSUNG MZVL21T0HCLR-00B00
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 18605302-CCCB-46EC-B43E-1514878C11E5
Device Start End Sectors Size Type
/dev/nvme0n1p1 40 409639 409600 200M EFI System
/dev/nvme0n1p2 409640 1000231247 999821608 476.8G Apple APFS
/dev/nvme0n1p3 1000232960 1750198271 749965312 357.6G Linux filesystem
/dev/nvme0n1p4 1750198272 2000408575 250210304 119.3G Linux filesystem
ZFS文件系统构建
我最终目标是在一个完整的底层host主机上构建3个ZFS存储池:
zpool-data
数据存储池zpool-libvirt
用于 libvirt ZFS存储池 (虽然不一定要用独立的ZFS pool,但是为了区分不混用,实际正式环境我还是独立设置一个zpoolzpool-docker
用于 Docker ZFS 存储驱动 : Docker需要直接使用存储池作ZFS后端驱动,并且要挂载到/var/lib/docker
目录,这和 Libvirt虚拟机管理器 不同,libvirt
可以使用多个存储,libvirt只需配置一个ZFS zpool作为libvirt的pool就可以(可以复用现有的ZFS存储池)
备注
在非正式开发测试环境,我暂时合并 zpoool-data
和 zpoool-libvirt
,只使用 zpool-data
: 本文的测试环境实践也是我后期在 树莓派5 NVMe存储ZFS 所采用的布局,以便能够在模拟测试环境中尽可能节约存储资源,同时满足模拟大规模集群架构
不过这个合并方式对于运维比较容易混淆,所以后续我构建服务器的时候,将拆分开: 详见 ZFS管理准备 方案(针对实际生产环境构建了3个不同用途的zpool存储池)
备注
根据文档和我的之前实践,我初步判断 libvirt ZFS存储池 对于zpool没有强制要求,所以实际上是可以复用 Docker ZFS 存储驱动 的zpool,甚至我的数据存储也可以在 docker zpool 下继续构建。由于是个人笔记本测试环境,我小心地构建了这个混用zpool存储(但不推荐),后续我的服务器实践将改进为分离存储池
警告
这段是测试笔记本,使用了一个存储池 zpool-data
,挂载到 /var/lib/docker
目录(为了满足 Docker ZFS 存储驱动 要求,仅适合测试环境。生产环境压力大, Libvirt虚拟机管理器 和 Docker 同时操作共用存储池预计会发生冲突,影响性能和稳定性。
创建
zpool-data
存储池,默认挂载到/var/lib/docker
目录(特例,为了满足 Docker ZFS 存储驱动 :
zpool-data
存储池挂载到 /var/lib/docker
目录zpool create -f zpool-data -m /var/lib/docker /dev/nvme0n1p3
zfs set compression=lz4 zpool-data
完成后使用 df -h
检查分区挂载:
df -h
检查分区挂载Filesystem Size Used Avail Use% Mounted on
devtmpfs 10M 0 10M 0% /dev
tmpfs 7.8G 520K 7.8G 1% /dev/shm
tmpfs 7.8G 1000K 7.8G 1% /run
/dev/nvme0n1p4 120G 106G 14G 89% /
/dev/nvme0n1p1 197M 114M 84M 58% /boot
tmpfs 1.6G 60K 1.6G 1% /run/user/502
zpool-data 345G 128K 345G 1% /var/lib/docker
存储就绪之后,则可以开始构建 Gentoo 虚拟化 以便运行一个多虚拟化的开发测试环境