19.2 Jail 系统更新
19.2.1 多 Jail 管理与分层架构
管理多个 Jail 时,逐个执行更新操作,既浪费存储空间,也不便管理。建立统一模板后,所有 Jail 可共用同一个基础环境,各自拥有独立的可写空间且互不干扰。
本节将建立如下目录结构:
- /jail/mroot 是模板目录,是所有 Jail 共用的只读部分,在本例中将被挂载到 /jail/www。
- /jail/skel 是框架目录,用于创建 Jail,本身不直接供任何 Jail 使用。
- /jail/www 是 Jail
www运行的根目录,也是只读模板的挂载点,本身是个空目录。 - /jail/www/s 是 Jail
www的可写部分的挂载点,也是个空目录。 - /jail/files/www 是 Jail
www的可写部分的实际存放位置,将被挂载到 /jail/www/s。
相关文件结构图:
/jail/
├── mroot/ # 只读模板目录(所有 Jail 共用)
│ ├── usr/
│ │ ├── ports/ # Ports 树
│ │ └── src/ # 系统源代码
│ └── s/ # 符号链接目标目录
├── skel/ # 框架目录(创建 Jail 的模板)
│ ├── home/
│ ├── usr-X11R6/
│ ├── distfiles/
│ ├── portbuild/
│ ├── etc/
│ ├── usr-local/
│ ├── tmp/
│ ├── var/
│ └── root/
├── www/ # Jail www 的根目录(空目录,挂载点)
│ └── s/ # Jail www 的可写部分挂载点(空目录)
├── files/
│ └── www/ # Jail www 的可写部分实际存放位置
└── www.fstab # Jail www 的 fstab 配置文件需要创建多个 Jail 时,只需重复创建数据目录和项目目录,所有 Jail 均可共用 /jail/mroot。
19.2.2 安装 cpdup 工具
cpdup 是 FreeBSD 系统中用于高效复制目录结构的专用工具,可精确复制文件系统的所有属性,包括权限、时间戳和特殊文件。
使用 pkg 安装 cpdup:
# pkg install cpdup或者使用 Ports 安装:
# cd /usr/ports/sysutils/cpdup/
# make install clean安装完成后,可运行 cpdup 验证工具是否正确安装。
19.2.3 创建框架目录结构
创建所需 Jail 路径并将基本系统文件放入目录,并将 Ports 树和系统源代码放入模板。注意源代码的版本应与 /jail/mroot 对应的基本系统(basejail)版本一致。FreeBSD 源代码可参照相关章节获取:
创建 Jail 根目录:
# mkdir -p /jail/mroot克隆 FreeBSD Ports 仓库到 Jail 内:
# git clone --filter=tree:0 https://mirrors.ustc.edu.cn/freebsd-ports/ports.git /jail/mroot/usr/ports复制宿主机源代码到 Jail 内(需版本一致):
# cpdup /usr/src /jail/mroot/usr/src建立符号链接,将可写部分映射到实际存储位置:
# cd /jail/mroot # 进入模板目录
# mkdir s # 创建用于符号链接的目标目录
# 注意:在创建符号链接之前,确保相关目录已被移动到骨架目录,或使用 -f 选项强制创建
# ln -sf s/etc etc # 创建或替换 /etc 的符号链接
# ln -sf s/home home # 创建或替换 /home 的符号链接
# ln -sf s/root root # 创建或替换 /root 的符号链接
# ln -sf ../s/usr-local usr/local # 创建或替换 /usr/local 的符号链接
# ln -sf ../s/usr-X11R6 usr/X11R6 # 创建或替换 /usr/X11R6 的符号链接
# ln -sf ../../s/distfiles usr/ports/distfiles # 创建或替换 /usr/ports/distfiles 的符号链接
# ln -sf s/tmp tmp # 创建或替换 /tmp 的符号链接
# ln -sf s/var var # 创建或替换 /var 的符号链接19.2.4 创建骨架目录
创建骨架目录及其子目录,然后将可写目录移动到骨架目录:
# mkdir -p /jail/skel # 创建骨架目录
# mkdir -p /jail/skel/home /jail/skel/usr-X11R6 /jail/skel/distfiles /jail/skel/portbuild # 创建子目录
# 将可写目录移动到骨架目录
# mv /jail/mroot/etc /jail/skel # 移动 /etc
# mv /jail/mroot/usr/local /jail/skel/usr-local # 移动 /usr/local
# mv /jail/mroot/tmp /jail/skel # 移动 /tmp
# mv /jail/mroot/var /jail/skel # 移动 /var
# mv /jail/mroot/root /jail/skel # 移动 /root使用 etcupdate 同步系统配置文件。etcupdate 是 FreeBSD 系统用于管理系统配置文件更新的专用工具,能够在系统升级过程中自动合并本地修改与系统默认配置,避免配置文件丢失或冲突。-s 指定源代码树路径,-D 指定目标根目录,-d 指定存储合并历史记录的数据库目录。
# etcupdate -s /jail/mroot/usr/src -d /jail/skel/var/db/etcupdate -D /jail/skel设置 Ports 构建工作目录前缀:设置 WRKDIRPREFIX 变量,即可将 Ports 构建过程中的临时工作目录统一指向指定路径,便于集中管理和空间回收。
# echo "WRKDIRPREFIX?=/s/portbuild" >> /jail/skel/etc/make.conf19.2.5 创建数据目录
复制一份框架目录作为数据目录:
# cpdup /jail/skel /jail/files/www19.2.6 创建项目目录
创建项目目录及其子目录:
# mkdir /jail/www /jail/www/s19.2.7 创建 fstab 文件
编辑 /jail/www.fstab 文件。nullfs 是 FreeBSD 提供的一种特殊文件系统,可在同一主机的不同位置重复挂载同一文件系统,支持 ro(只读)和 rw(读写)等挂载选项。若需手动挂载而非通过 fstab,也可使用 mount_nullfs 命令直接操作:
# 将公共的只读系统挂载到项目目录
/jail/mroot /jail/www nullfs ro 0 0
# 将项目数据目录挂载到项目目录
/jail/files/www /jail/www/s nullfs rw 0 019.2.8 jail.conf 文件配置示例
以下为 jail.conf 配置文件示例:
# 全局配置部分
exec.start = "/bin/sh /etc/rc"; # 启动命令
exec.stop = "/bin/sh /etc/rc.shutdown jail"; # 停止命令
exec.clean; # 清理执行环境
mount.devfs; # 挂载 devfs
allow.raw_sockets = 1; # 允许原始套接字
allow.sysvipc = 1; # 允许 System V IPC
# 主机名可使用变量替代
hostname = "${name}.domain.local";
# Jail 的路径,可使用变量替代
path = "/jail/$name";
# IPv4 地址
ip4.addr = 192.168.1.$ip;
# fstab 文件位置
mount.fstab = "/jail/$name.fstab";
www { # Jail 名称为 www
$ip = 2; # 占位变量,此处是指定 IP 为 192.168.1.2
# 如不使用 fstab,可覆盖全局配置
# mount.fstab = "";
}布尔参数(如 allow.raw_sockets、mount.devfs)除赋值 "true"/"false" 外,还可使用无值快捷写法(如 allow.raw_sockets 等价于 allow.raw_sockets = "true"),或以 no 前缀表示否定(如 allow.nomount 等价于 allow.mount = "false")。
19.2.9 参考文献
- FreeBSD Project. jail -- manage system jails[EB/OL]. [2026-04-14]. https://man.freebsd.org/cgi/man.cgi?query=jail&sektion=8. Jail 管理工具手册页,涵盖创建、修改与删除 Jail 的参数与操作。
- FreeBSD Project. jail.conf -- configuration file for jail(8)[EB/OL]. [2026-04-14]. https://man.freebsd.org/cgi/man.cgi?query=jail.conf&sektion=5. Jail 配置文件格式手册页,定义参数语法与伪参数。
- FreeBSD Project. nullfs -- null file system[EB/OL]. [2026-04-14]. https://man.freebsd.org/cgi/man.cgi?query=nullfs&sektion=4. nullfs 文件系统手册页,描述只读与读写挂载选项。
- FreeBSD Project. mount_nullfs -- mount a null layer[EB/OL]. [2026-04-14]. https://man.freebsd.org/cgi/man.cgi?query=mount_nullfs&sektion=8. nullfs 挂载命令手册页。
- FreeBSD Project. cpdup -- mirror directories[EB/OL]. [2026-04-14]. https://man.freebsd.org/cgi/man.cgi?query=cpdup&sektion=1. 目录镜像复制工具手册页,用于 Jail 文件系统复制。
- FreeBSD Project. devfs -- device file system[EB/OL]. [2026-04-14]. https://man.freebsd.org/cgi/man.cgi?query=devfs&sektion=4. 设备文件系统手册页,描述 devfs 挂载与规则集管理。
- FreeBSD Project. devfs -- device file system manager[EB/OL]. [2026-04-14]. https://man.freebsd.org/cgi/man.cgi?query=devfs&sektion=8. devfs 管理工具手册页,描述规则集配置与设备访问控制。
- FreeBSD Project. etcupdate -- manage updates to system files not updated by installworld[EB/OL]. [2026-04-14]. https://man.freebsd.org/cgi/man.cgi?query=etcupdate&sektion=8. 系统配置文件更新管理工具手册页。
- FreeBSD Project. Jails[EB/OL]. FreeBSD Wiki, [2026-04-14]. https://wiki.freebsd.org/Jails. FreeBSD Wiki 中关于 Jail 的配置与管理信息。