FreeBSD Jail访问ZFS文件系统
ZFS数据集可以委托给Jail使用:
zfs set jailed=on <volume name>
将ZFS卷集设置给jail使用zfs jail <jailid|jailname> filesystem
命令可以将ZFS文件系统attach到FreeBSD jail上jexec <jailname> zfs mount filesystem
命令在jail内部挂载上文件系统就可以开始使用
整个过程有一些技巧,特别适合在jail中运行数据库这种独占卷集的方案: 在FreeBSD Jail中运行PostgreSQL
实践案例
目标: host主机的 zdata/docs
分配给 dev
jail使用
创建
zdata/docs
(可选设置挂载目录)
zdata/docs
# 创建挂载到 /docs 目录的卷集 zdata/docs
#zfs create -o mountpoint=/docs zdata/docs
zfs create zdata/docs
此时在host主机上执行 df -h
可以看到一个被挂载到 /docs
目录上的ZFS卷集:
/docs
目录的卷集 zdata/docs
的挂载情况Filesystem Size Used Avail Capacity Mounted on
zroot/ROOT/default 192G 1.4G 191G 1% /
devfs 1.0K 0B 1.0K 0% /dev
zdata 6.1T 96K 6.1T 0% /zdata
...
zdata/docs 6.1T 96K 6.1T 0% /docs
设置卷集
jailed=on
属性:
jailed=on
属性zfs set jailed=on zdata/docs
备注
此时再执行 df -h
就会看到 zdata/docs
卷集挂载从host主机上消失了,因为这个卷集已经设置为用于jail,对于host主机将不可用
执行
zfs jail
命令将设置了jailed=on
的ZFS卷集分配给jaildev
:
jailed=on
属性的ZFS卷集分配给jail dev
zfs jail dev zdata/docs
备注
只有执行了 zfs jail dev zdata/docs
命令之后,才能在 dev
jail 中看到这个ZFS卷集
另外,如果host主机重启,则 dev
jail中就看不到这个ZFS卷集,需要重新执行这个命令。
要持久化配置,需要调整 dev
jail 配置,加入这个jail启动时自动执行命令,见下文。
现在在
dev
jail中可以看到卷集:
dev
jail中可以看到卷集# 在jail中检查
zfs list
可以在
dev
jail 中执行挂载:
dev
jail 中执行挂载zfs mount zdata/docs
这里遇到一个报错:
dev
jail 中执行挂载报错cannot mount '/docs': failed to create mountpoint: Read-only file system
这个报错是因为我部署的是 VNET + Thin Jail 的NullFS jail,其中根文件目录是只读的snapshot挂载。不过,NullFS模式有部分目录是读写模式的,例如 /home
。所以调整 zdata/docs
的挂载点来重试:
修订挂载点(host)
# 首先要将jailed属性关闭才能在host主机上修改zfs
# 否则修改mountpoint会报错: cannot set property for 'zdata/docs': 'mountpoint' cannot be set on dataset in a non-global zone
zfs set jailed=off zdata/docs
zfs set mountpoint=/home/docs zdata/docs
zfs set jailed=on zdata/docs
# 因为之前已经执行过 zfs jail 命令,我发现不需要再执行
# zfs jail dev zdata/docs
此时在
dev
jail 中执行zfs list
可以看到ZFS卷集zdata/docs
已经自动反映出挂载点修改了
dev
jail 可以看到挂载点修订NAME USED AVAIL REFER MOUNTPOINT
zdata 2.32G 6.12T 96K /zdata
zdata/docs 96K 6.12T 96K /home/docs
再次执行挂载
zfs mount zdata/docs
,可以看到另外一个报从显示jail没有权限:
cannot mount 'zdata/docs': Insufficient privileges
调整
dev`
jail的权限,先停止dev
jail,然后修订/etc/jail.conf
(公共设置) 或/etc/jail.conf.d/dev.conf
(单独设置)
# PERMISSIONS
allow.raw_sockets;
exec.clean;
mount.devfs;
allow.mount;
allow.mount.devfs;
allow.mount.zfs;
enforce_statfs = 1;
备注
这里同时需要配置:
allow.mount.zfs;
enforce_statfs = 1;
否则挂载时候都会报同样的错误:
cannot mount 'zdata/docs': Insufficient privileges
重新启动
dev
jail之后,就可以在该 jail 内部执行ZFS挂载:zfs mount zdata/docs
自动化ZFS挂载
上述执行步骤完整展示了如何在jail内部使用一个ZFS数据集,但是整个过程是纯手工命令完成的。如何在jail启动时自动完成ZFS卷集的挂载呢?
修改
/dev/jail.conf.d/dev.conf
:
dev
jail 启动时自动挂载分配的ZFS datasetdev {
# PERMISSIONS
allow.mount.zfs;
# NETWORKS/INTERFACES
$id = "253";
$ip = "192.168.7.${id}/24";
# auto mount ZFS datasets
$dataset = "zdata/docs";
exec.created += "/sbin/zfs jail ${name} ${dataset}";
exec.created += "jexec ${name} zfs mount ${dataset}";
exec.release += "/sbin/zfs unjail ${name} ${dataset}";
exec.release += "umount -f ${dataset}";
}
这样启动 dev
jail后,通过 jexec dev
进入jail,检查 df -h
就可以看到这个 zdata/docs
被自动挂载到指定的 /skeleton/home/docs
目录:
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
devfs 1.0K 0B 1.0K 0% /dev
zdata/docs 6.1T 96K 6.1T 0% /skeleton/home/docs