LFS分区(和FreeBSD一起Dualboot)

我组装 纳斯NASSE C246 ITX主板 的电脑,部署了 FreeBSD 系统来构建 FreeBSD机器学习 。但是,实践中遇到了一些挫折:

原本想 在bhyve中实现NVIDIA GPU passthrough ,但是NVIDIA显卡在 bhyve(BSD hypervisor) 中PCI passthru无法完成,这阻碍了我进一步的 Machine Learning 学习。由于我购买了2块 AMD Radeon Instinct MI50 ,所以准备继续尝试 在bhyve中实现AMD GPU passthrough

不过, NVIDIA GPU 是目前 Machine Learning 的主流硬件,我需要充分发挥所以的硬件来构建实验环境。所以,我考虑同时安装 LFS(Linux from scratch) ,构建一个 Dualboot 环境:

  • 在 FreeBSD 和 Linux 之间无缝切换:

    • 所有的存储方案( Ceph / ZFS )在两个OS系统中都实现,任何时候切换都不影响整个homelab的运行

    • 存储数据共享: Linux和FreeBSD都能访问相同一份数据,节约资源

  • FreeBSD和LFS仅仅是底座,不影响上层的虚拟化:

    • 切换到任意FreeBSD或LFS,都能启动存储在 ZFS 中的虚拟化,甚至 Docker 容器(可行么? jail 和 docker 能共享兼容么?)

    • 原先计划构建的基础服务,我准备在两个系统中都 1:1 复制构建,来验证我的底层系统无关的构想

磁盘

  • 首先使用 gpart 工具检查(因为已经安装好了 FreeBSD ,使用 ZFS 作为根文件系统):

使用 gpart 检查磁盘分区
gpart show

输出显示:

使用 gpart 检查磁盘分区
=>        34  3907029101  diskid/DISK-54UA4072K7AS  GPT  (1.8T)
          34        2014                            - free -  (1.0M)
        2048   536870912                         1  freebsd-ufs  (256G)
   536872960  3370156032                         2  freebsd-zfs  (1.6T)
  3907028992         143                            - free -  (72K)

=>        40  3907029088  diskid/DISK-Y39B70RTK7AS  GPT  (1.8T)
          40      532480                         1  efi  (260M)
      532520        2008                            - free -  (1.0M)
      534528     4194304                         2  freebsd-swap  (2.0G)
     4728832   536870912                         3  freebsd-zfs  (256G)
   541599744  3365429248                         4  freebsd-zfs  (1.6T)
  3907028992         136                            - free -  (68K)

注意:

  • diskid/DISK-Y39B70RTK7AS 删除分区(系统磁盘):

删除分区
gpart delete -i 4 /dev/diskid/DISK-Y39B70RTK7AS

删除系统磁盘的第 4 分区

  • diskid/DISK-54UA4072K7AS 删除分区(数据磁盘):

删除数据磁盘分区
gpart delete -i 1 /dev/diskid/DISK-54UA4072K7AS
gpart delete -i 2 /dev/diskid/DISK-54UA4072K7AS
  • 现在磁盘不需要的分区已经删除,检查:

使用 gpart 再次检查磁盘分区
gpart show

显示空闲空间:

使用 gpart 再次检查磁盘分区,可以看到空白部分
=>        34  3907029101  diskid/DISK-54UA4072K7AS  GPT  (1.8T)
          34  3907029101                            - free -  (1.8T)

=>        40  3907029088  diskid/DISK-Y39B70RTK7AS  GPT  (1.8T)
          40      532480                         1  efi  (260M)
      532520        2008                            - free -  (1.0M)
      534528     4194304                         2  freebsd-swap  (2.0G)
     4728832   536870912                         3  freebsd-zfs  (256G)
   541599744  3365429384                            - free -  (1.6T)

创建分区(两块磁盘)

  • 在系统盘上创建一个 linux-data 类型的Linux分区256G,并将该系统盘剩余空间创建为zfs分区

使用 gpart 创建一个 linux-datafreebsd-zfs 分区
# 添加linux分区(-t linux-data), 以1M大小进行对齐(-a 1M), 分区大小为256G(-s 256G)
gpart add -t linux-data -a 1M -s 256G /dev/diskid/DISK-Y39B70RTK7AS

# 添加ZFS分区(-t freebsd-zfs), 以1M大小进行对齐(-a 1M), 分区为剩余空间
gpart add -t freebsd-zfs -a 1M /dev/diskid/DISK-Y39B70RTK7AS

另一个数据磁盘则完整划分一个ZFS分区 (下文我修订为只使用一块磁盘,即系统盘)

使用 gpart 将数据盘完整划分为一个ZFS分区
gpart add -t freebsd-zfs -a 1M /dev/diskid/DISK-54UA4072K7AS
  • 最终完成的分区:

使用 gpart 检查磁盘分区
gpart show

显示如下:

使用 gpart 检查最终的分股情况
=>        34  3907029101  diskid/DISK-54UA4072K7AS  GPT  (1.8T)
          34        2014                            - free -  (1.0M)
        2048  3907026944                         1  freebsd-zfs  (1.8T)
  3907028992         143                            - free -  (72K)

=>        40  3907029088  diskid/DISK-Y39B70RTK7AS  GPT  (1.8T)
          40      532480                         1  efi  (260M)
      532520        2008                            - free -  (1.0M)
      534528     4194304                         2  freebsd-swap  (2.0G)
     4728832   536870912                         3  freebsd-zfs  (256G)
   541599744   536870912                         4  linux-data  (256G)
  1078470656  2828558336                         5  freebsd-zfs  (1.3T)
  3907028992         136                            - free -  (68K)

创建分区(一块磁盘)

我现在将一块数据盘撤掉,只剩下使用系统盘来构建存储,所以相当于上述步骤的一部分:

  • 在系统盘上创建一个 freebsd-ufs 类型的FreeBSD分区60G,用于 VNET + Thick(厚) Jail(UFS) (当时为了排查Jail问题)

  • 在系统盘上创建一个 linux-data 类型的Linux分区200G

  • 该系统盘剩余空间创建为zfs分区

使用 gpart 创建一个 freebsd-ufs , linux-datafreebsd-zfs 分区
# 添加UFS分区(56G)
gpart add -t freebsd-ufs -a 1M -s 56G /dev/diskid/DISK-Y39B70RTK7AS

# 添加linux分区(-t linux-data), 以1M大小进行对齐(-a 1M), 分区大小为200G(-s 200G)
gpart add -t linux-data -a 1M -s 200G /dev/diskid/DISK-Y39B70RTK7AS

# 添加ZFS分区(-t freebsd-zfs), 以1M大小进行对齐(-a 1M), 分区为剩余空间
gpart add -t freebsd-zfs -a 1M /dev/diskid/DISK-Y39B70RTK7AS

所以当前最终完成的分区:

使用 gpart 创建一个 freebsd-ufs , linux-datafreebsd-zfs 分区
=>        40  3907029088  diskid/DISK-Y39B70RTK7AS  GPT  (1.8T)
          40      532480                         1  efi  (260M)
      532520        2008                            - free -  (1.0M)
      534528     4194304                         2  freebsd-swap  (2.0G)
     4728832   536870912                         3  freebsd-zfs  (256G)
   541599744   117440512                         4  freebsd-ufs  (56G)
   659040256   419430400                         6  linux-data  (200G)
  1078470656  2828558336                         5  freebsd-zfs  (1.3T)
  3907028992         136                            - free -  (68K)

构建ZFS

两块NVMe磁盘构建

上述2个NVMe磁盘的 1.3T1.8T 分区,采用 ZFS Stripe条带化 (FreeBSD环境实践) 方式再次重建 zdata :

创建 stripe 模式的 zdata
zpool create -f -o ashift=12 zdata \
    /dev/diskid/DISK-Y39B70RTK7ASp5 \
    /dev/diskid/DISK-54UA4072K7ASp1

# 默认启用lz4压缩
zfs set compression=lz4 zdata
  • 检查zpool:

检查zpool
zpool list -v

输出可以看到 zdata 跨了2块磁盘:

zpool zdata 跨了2块磁盘
NAME                           SIZE  ALLOC   FREE  CKPOINT  EXPANDSZ   FRAG    CAP  DEDUP    HEALTH  ALTROOT
zdata                         3.12T   396K  3.12T        -         -     0%     0%  1.00x    ONLINE  -
  diskid/DISK-Y39B70RTK7ASp5  1.32T   204K  1.31T        -         -     0%  0.00%      -    ONLINE
  diskid/DISK-54UA4072K7ASp1  1.82T   192K  1.81T        -         -     0%  0.00%      -    ONLINE
zroot                          254G  13.5G   240G        -         -     1%     5%  1.00x    ONLINE  -
  diskid/DISK-Y39B70RTK7ASp3   256G  13.5G   240G        -         -     1%  5.33%      -    ONLINE

一块NVMe磁盘构建

后期我为了能够将3块NVMe用于在 Raspberry Pi 上构建 Ceph ,所以将 FreeBSD 上2块NVMe构建的 zdata 再次拆除,然后仅仅用一块NVMe磁盘的 1.3T 分区来重新构建 zdata :

单块NVMe zpool list -v 输出详情
NAME                           SIZE  ALLOC   FREE  CKPOINT  EXPANDSZ   FRAG    CAP  DEDUP    HEALTH  ALTROOT
zdata                         1.31T  11.1G  1.30T        -         -     0%     0%  1.00x    ONLINE  -
  diskid/DISK-Y39B70RTK7ASp5  1.32T  11.1G  1.30T        -         -     0%  0.82%      -    ONLINE
zroot                          254G  20.1G   234G        -         -     5%     7%  1.00x    ONLINE  -
  diskid/DISK-Y39B70RTK7ASp3   256G  20.1G   234G        -         -     5%  7.92%      -    ONLINE

构建ZFS的dataset

我已经在 ZFS 复制(replication) 中完成了备份,所以现在将上述 zdata/vmszdata/jails 恢复回来:

恢复 zdata 上数据集
time=`date +%Y-%m-%d_%H:%M:%S`
from_zpool=zstore
to_zpool=zdata

zfs snapshot -r $from_zpool/jails@$time
zfs snapshot -r $from_zpool/vms@$time

zfs send -v -R $from_zpool/jails@$time | zfs receive $to_zpool/jails
zfs send -v -R $from_zpool/vms@$time | zfs receive $to_zpool/vms

下一步

通常我们会用一个常规安装的Linux( DebianFedora )来作为基础系统,安装变硬工具来完成LFS的编译构建。但是我不想这么简单,而是采用 使用 Rocky-Container-base tgz 包部署Linux Jail Rocky 来构建: