在多个Jail间共享文件目录

我在部署 FreeBSD Linux Jail 时想到 debootstrap 部分能否像 FreeBSD Thin(薄) Jail 中使用 zfs 卷的clone模式共享,这样多个Linux Jail实际上只需要使用一份数据就可以。

实际上在FreeBSD中,对于Jail中使用Host上目录,采用了一种名为 nullfs 的回环文件系统。在部署 FreeBSD Linux Jail 时已经使用,也就是将host主机的 /tmp/home 目录挂载到 Linux Jail中: 这样就可以在Jail中使用X11

Linux Jail /etc/jail.conf.d/d2l.conf 配置了host目录通过nullfs挂载到Jail
d2l {
  devfs_ruleset=4;
  ip4.addr="10.0.0.9/24";
  
  # MOUNT
  mount += "devfs     $path/compat/debian/dev     devfs     rw  0 0";
  mount += "tmpfs     $path/compat/debian/dev/shm tmpfs     rw,size=1g,mode=1777  0 0";
  mount += "fdescfs   $path/compat/debian/dev/fd  fdescfs   rw,linrdlnk 0 0";
  mount += "linprocfs $path/compat/debian/proc    linprocfs rw  0 0";
  mount += "linsysfs  $path/compat/debian/sys     linsysfs  rw  0 0";
  mount += "/tmp      $path/compat/debian/tmp     nullfs    rw  0 0";
  mount += "/home     $path/compat/debian/home    nullfs    rw  0 0";
}

但是,我发现一个问题,查看 /home 目录目录下,只有两个空目录 /home/huatai/home/admin ,并没有像我预期中的将物理Host主机的 /home/admin 内容展示出来。而同样的 /tmp 目录确实和host主机完全一致。

备注

参考 Files and folders not visible when mounted will nullfs 似乎ZFS有自己的 jail 子命令,可以将整个zfs dataset委托给jail处理。

具体我需要再学习一下ZFS手册

注意到 /tmp/home 同为 zfs dataset ,但是通过 nullfs 映射到jail中表现同步,所以怀疑是zfs配置不同,例如前面提到的 zfs jail委托

通过 zfs get all 获取 /home/tmp 的属性进行对比
zfs get all zroot/home > zfs_home
zfs get all zroot/tmp > zfs_tmp

sdiff zfs_home zfs_tmp

对比发现主要的差异是 zroot/home 设置了 setuid=on ,而 zroot/tmp 设置了 setuid=off

ZFS and Jail :: nullfs mount :: nothing visible from 有一些讨论值得关注:

  • 如果想要在jail中管理ZFS dataset,需要使用 zfs set jailed=on 属性,但是这个zfs dataset不能挂载为 nullfs ,而是直接提供给jail: 我已经在 FreeBSD Jail访问ZFS文件系统 中完成实践

  • 如果在host主机上管理ZFS dataset(常规方式),那么就可以像 VNET + Thin Jail(NullFS) 一样,使用NullFS实现将host主机的ZFS挂载目录bind到jail内部。这种方式不仅简单(只需要配置thin jail的fstab),而且可以在多个jail上共享host主机提供的ZFS dataset

实践

  • 首先完成 VNET + Thin Jail(NullFS) 部署,其中配置NullFS Thin jail的NullFS挂载使用了一个 /zdata/jails/${name}-nullfs-base.fstab 配置文件

  • 在host主机上创建数据集 zdata/docs :

创建ZFS数据集
zfs create zdata/docs

这个数据集就是用于不同jail共享的host主机ZFS

  • 修改 /zdata/jails/${name}-nullfs-base.fstab (host主机上 /etc/jail.conf 配置为每个jail指定了一个挂载文件系统配置)。以 dev jail为例,对应的配置文件就是 /zdata/jails/dev-nullfs-base.fstab :

修改 dev jail对应的fstab配置文件 /zdata/jails/dev-nullfs-base.fstab
/zdata/jails/templates/14.3-RELEASE-base  /zdata/jails/dev-nullfs-base/         nullfs  ro  0 0
/zdata/jails/containers/dev               /zdata/jails/dev-nullfs-base/skeleton nullfs  rw  0 0
/zdata/docs                               /zdata/jails/dev-nullfs-base/skeleton/docs nullfs rw,noatime,nosuid,nocache 0 0
  • 为jail的skeleton目录下创建一个挂载目录:

创建挂载目录
# 如果想为每个jail的模版中就添加挂载目录,可以在 「VNET + Thin Jail」 实践步骤的skeleton模版中创建目录
# mkdir -p /$jail_zfs/templates/$bsd_ver-RELEASE-skeleton/docs

# 这里为已经创建好的 dev jail 创建一个挂载目录,则直接执行
mkdir /zdata/jails/dev-nullfs-base/skeleton/docs
  • 重新启动 dev jail,就可以看到NullFS将host主机上的 /zdata/docs 挂载到jail中,所以在 dev jail 中执行 df -h 会看到:

dev jail 中查看 df -h
Filesystem                                  Size    Used   Avail Capacity  Mounted on
/zdata/jails/templates/14.3-RELEASE-base    6.1T    457M    6.1T     0%    /
/zdata/jails/containers/dev                 6.1T    860M    6.1T     0%    /skeleton
/zdata/docs                                 6.1T     96K    6.1T     0%    /skeleton/docs
devfs                                       1.0K      0B    1.0K     0%    /dev

参考