Skip to content

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

相关文件结构图:

sh
/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:

sh
# pkg install cpdup

或者使用 Ports 安装:

sh
# cd /usr/ports/sysutils/cpdup/
# make install clean

安装完成后,可运行 cpdup 验证工具是否正确安装。

19.2.3 创建框架目录结构

创建所需 Jail 路径并将基本系统文件放入目录,并将 Ports 树和系统源代码放入模板。注意源代码的版本应与 /jail/mroot 对应的基本系统(basejail)版本一致。FreeBSD 源代码可参照相关章节获取:

创建 Jail 根目录:

sh
# mkdir -p /jail/mroot

克隆 FreeBSD Ports 仓库到 Jail 内:

sh
# git clone --filter=tree:0 https://mirrors.ustc.edu.cn/freebsd-ports/ports.git /jail/mroot/usr/ports

复制宿主机源代码到 Jail 内(需版本一致):

sh
# cpdup /usr/src /jail/mroot/usr/src

建立符号链接,将可写部分映射到实际存储位置:

sh
# 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 创建骨架目录

创建骨架目录及其子目录,然后将可写目录移动到骨架目录:

sh
# 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 指定存储合并历史记录的数据库目录。

sh
# etcupdate -s /jail/mroot/usr/src -d /jail/skel/var/db/etcupdate -D /jail/skel

设置 Ports 构建工作目录前缀:设置 WRKDIRPREFIX 变量,即可将 Ports 构建过程中的临时工作目录统一指向指定路径,便于集中管理和空间回收。

sh
# echo "WRKDIRPREFIX?=/s/portbuild" >> /jail/skel/etc/make.conf

19.2.5 创建数据目录

复制一份框架目录作为数据目录:

sh
# cpdup /jail/skel /jail/files/www

19.2.6 创建项目目录

创建项目目录及其子目录:

sh
# mkdir /jail/www /jail/www/s

19.2.7 创建 fstab 文件

编辑 /jail/www.fstab 文件。nullfs 是 FreeBSD 提供的一种特殊文件系统,可在同一主机的不同位置重复挂载同一文件系统,支持 ro(只读)和 rw(读写)等挂载选项。若需手动挂载而非通过 fstab,也可使用 mount_nullfs 命令直接操作:

ini
# 将公共的只读系统挂载到项目目录
/jail/mroot /jail/www nullfs ro 0 0
# 将项目数据目录挂载到项目目录
/jail/files/www /jail/www/s nullfs rw 0 0

19.2.8 jail.conf 文件配置示例

以下为 jail.conf 配置文件示例:

ini
# 全局配置部分
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_socketsmount.devfs)除赋值 "true"/"false" 外,还可使用无值快捷写法(如 allow.raw_sockets 等价于 allow.raw_sockets = "true"),或以 no 前缀表示否定(如 allow.nomount 等价于 allow.mount = "false")。

19.2.9 参考文献