VNET + Thick(厚) Jail(UFS)

实践总是磕磕绊绊,我在 FreeBSD Alpha 2 上实践 FreeBSD Linux Jail 发现在 ZFS 上构建 FreeBSD Linux Jail 或者关闭ZFS的压缩属性,都出现了无法解决的 ls访问文件系统报错 Invalid argument

考虑到UFS虽然能够实现 在UFS文件系统上构建Thin Jail ,但是如果使用NullFS应该还会和 FreeBSD Linux Jail 的Linux分区文件系统挂载冲突,所以改为采用传统的 FreeBSD Thick(厚) Jail ,在 FreeBSD Thick(厚) Jail 基础上结合VNET的形成本文实践。

Thick Jail

  • 为方便调整,我设置了环境变量来方便后续操作

设置 jail目录和release版本环境变量
# 这里的 udir 表示 UFS dir, 和我之前设置 dir 表示 ZFS dir 进行区别
# /udata 是主机上挂载的 UFS 文件系统
export jail_udir="udata/jails"
export bsd_ver="14.3"
# 在FreeBSD中root用户的shell默认是sh,所以调整 ~/.shrc
echo 'export jail_udir="udata/jails"' >> ~/.shrc
echo 'export bsd_ver="14.3"' >> ~/.shrc
下载用户空间
fetch https://download.freebsd.org/ftp/releases/amd64/amd64/$bsd_ver-RELEASE/base.txz -o /$jail_dir/media/$bsd_ver-RELEASE-base.txz
  • 解压缩到jail目录:

设置一个 $jail_name 方便灵活配置( ludev )
export jail_name=ludev
解压缩到jail目录( ludev 命名)
mkdir -p /$jail_udir/containers/$jail_name
tar -xf /$jail_dir/media/$bsd_ver-RELEASE-base.txz -C /$jail_udir/containers/$jail_name --unlink
  • jail目录内容就绪以后,需要复制时区和DNS配置文件:

复制复制时区和DNS配置文件
cp /etc/resolv.conf /$jail_udir/containers/$jail_name/etc/resolv.conf
cp /etc/localtime /$jail_udir/containers/$jail_name/etc/localtime
  • 更新最新补丁:

更新jail
freebsd-update -b /$jail_udir/containers/$jail_name/ fetch install

配置Thick Jail

备注

VNET + Thin Jail(NullFS) 配置基础上完成

  • 适合不同Jail的公共配置 /etc/jail.conf :

混合多种jail的公共 /etc/jail.conf
# STARTUP/LOGGING
exec.start = "/bin/sh /etc/rc";
exec.stop = "/bin/sh /etc/rc.shutdown";
exec.consolelog = "/var/log/jail_console_${name}.log";

# PERMISSIONS
allow.raw_sockets;
exec.clean;
mount.devfs;

allow.mount;
allow.mount.devfs;

enforce_statfs = 1;

# HOSTNAME
host.hostname = "${name}";

# NETWORK - VNET/VIMAGE
#ip4 = inherit;
interface = igc0bridge;
vnet;
vnet.interface = "${epair}b";
# common NETWORK config
$gateway = "192.168.7.221";
$bridge = "igc0bridge";
$epair = "epair${id}";

# ADD TO bridge INTERFACE
exec.prestart += "ifconfig ${epair} create up";
exec.prestart += "ifconfig ${epair}a up descr jail:${name}";
exec.prestart += "ifconfig ${bridge} addm ${epair}a up";
exec.start    += "ifconfig ${epair}b ${ip} up";
exec.start    += "route add default ${gateway}";
exec.poststop = "ifconfig ${bridge} deletem ${epair}a";
exec.poststop += "ifconfig ${epair}a destroy";

.include "/etc/jail.conf.d/*.conf";
  • UFS文件系统上构建的 ludev 独立配置 /etc/jail.conf.d/ludev.conf :

UFS文件系统上构建的 ludev 独立配置 /etc/jail.conf.d/ludev.conf
ludev {
  # thin jail devfs_ruleset 5 和Linux Jail的4不同
  devfs_ruleset=4;

  # HOSTNAME/PATH - Snapshot
  path = "/udata/jails/containers/${name}";

  # NETWORKS/INTERFACES
  $id = "252";
  $ip = "192.168.7.${id}/24";

}

启动jail

  • 最后启动 ludev :

启动 ludev
service jail start ludev

通过 jexec ludev 进入jail

  • 设置Jail ludev 在操作系统启动时启动,修改 /etc/rc.conf :

/etc/rc.conf
# Jails
jail_enable="YES"
jail_parallel_start="YES"
jail_list="jdev ldev ludev"
jail_reverse_stop="YES"