17.15.jail 与 ZFS
最后更新于
可向 jail 委托一个或多个 ZFS 数据集的控制权,使 jail 中的 root 用户能够创建、快照、克隆和回滚子数据集,而无需宿主管理员介入。这是为 jail 提供可写、可快照存储的推荐方式。
宿主保留数据集的所有权,仅将所委托的树及其后代的管理权委托给 jail。jailed 属性、zfs jail 子命令以及二者之间的交互在 ZFS 和 Jail 中说明。
此方法适用于所有受支持的 FreeBSD 发行版本。
在宿主上,创建要委托的数据集并将其标记为 jailed:
# zfs create zroot/jails/data
# zfs set jailed=on zroot/jails/data设置 jailed 属性会通知 ZFS 该数据集将从 jail 内部管理,因此宿主不再自动挂载它。
接下来,允许 jail 挂载 ZFS 文件系统,并在创建 jail 时附加数据集。在 /etc/jail.conf 中 jail 的节中添加以下内容:
allow.mount;
allow.mount.zfs;
enforce_statfs = 1;
exec.created += "zfs jail ${name} zroot/jails/data";allow.mount.zfs 权限仅在配合 allow.mount 且 enforce_statfs 值低于 2 时才生效;挂载权限及其与 enforce_statfs 的交互参见 更多 jail 选项。由于委托的数据集在 jail 停止时会分离,exec.created 钩子会在每次启动时重新附加它,其中 ${name} 会展开为 jail 名称。同样的附加操作可对正在运行的 jail 执行 zfs jail <jid|name> zroot/jails/data。
注意
jail 需要访问 /dev/zfs。jail 的默认 devfs 规则集(
devfsrules_jail,规则集 4)已经将其解除隐藏,因此 ZFS 委托无需自定义 devfs 规则集。
在 jail 内部,挂载已委托的数据集并像对待其他数据集一样管理它们:
jail 中的 root 用户可在委托的树之下创建、快照、克隆和回滚数据集,但委托数据集的 quota 属性只能从宿主设置。
注意
zfs.dataset参数需要 FreeBSD 15.0。它不存在于 FreeBSD 14.3 的 jail(8) 中。
从 FreeBSD 15.0 开始,jail(8) 可自行附加数据集,无需手动 jailed 和 zfs jail 步骤。在 zfs.dataset 参数中列出要委托的数据集:
jail(8) 会在 jail 启动时附加每个列出的数据集,因此上面所示的 exec.created 钩子不再需要。此参数要求设置 allow.mount.zfs。
对于尚不支持 zfs.dataset 的未维护 jail 管理器,rc.d/jail 启动脚本也支持 /etc/rc.conf 中的遗留变量 jail_<jailname>_zfs_dataset。
zfs.mount_snapshot 参数在 FreeBSD 14.x 和 15.x 上可用,让 jail 中的用户无需委托整个数据集即可访问快照内容。设置为 1 时,jail 中的用户可在文件系统的 .zfs/snapshot 目录下读取其快照内容:
这对于从宿主拍摄的快照中恢复单个文件非常方便。如果同时设置了 allow.mount.zfs,快照还可在 jail 内挂载。数据集的 snapdir 属性控制 .zfs 目录是否可见。
警告
委托的数据集配合
allow.mount.zfs会让 jail 中的root用户设置与挂载相关的 ZFS 属性并在 jail 内挂载文件系统。请慎重授予这些权限,仅授予受信任管理自己存储的 jail。
最后更新于
# zfs mount -a
# zfs create zroot/jails/data/work
# zfs snapshot zroot/jails/data/work@mondayallow.mount;
allow.mount.zfs;
enforce_statfs = 1;
zfs.dataset = "zroot/jails/data";zfs.mount_snapshot = 1;