For the complete documentation index, see llms.txt. This page is also available as Markdown.

17.10.管理 jail

jail 创建完成后,可执行许多操作,如启动、重启或删除 jail、在其中安装软件等。本节将介绍可从主机对 jail 执行的不同操作。

17.10.1. 列出正在运行的 jail

要列出主机系统上正在运行的 jail,可使用 jls(8) 命令:

# jls

输出应该类似于以下内容:

   JID  IP Address      Hostname                      Path
     1  192.168.1.151  classic                       /usr/local/jails/containers/classic

jls(8) 支持 --libxo 参数,能通过 libxo(3) 库以其他格式显示输出,例如 JSONHTML 等。

例如,执行以下命令以获取 JSON 输出:

# jls --libxo=json

输出应该类似于如下内容:

{"__version": "2", "jail-information": {"jail": [{"jid":1,"ipv4":"192.168.1.151","hostname":"classic","path":"/usr/local/jails/containers/classic"}]}}

默认列表只是 jls(8) 能报告内容的一小部分。加上 -v 标志可获取每个 jail 的详细多行摘要,包括其状态和分配的 cpuset ID:

# jls -v

使用 -h 可在所请求参数的值之上打印带字段名的标题行:

# jls -h jid name path

要查询单个 jail 的特定参数,用 -j 指定其名称并列出要打印的参数:

输出应该类似于以下内容:

加上 -d 可包含正在关闭的 jail,否则它们在 dying 状态下会被隐藏:

17.10.2. 启动、重启和停止 jail

service(8) 用于在主机上启动、重启或停止 jail。

例如,要启动 jail,运行以下命令:

start 参数更改为 restartstop 可对 jail 执行其他操作。

停止 jail 不止是杀掉其中的进程。当 jail 停止时,jail(8) 会先在 jail 内运行其 exec.stop 参数中的命令——通常是 /bin/sh /etc/rc.shutdown——以便其服务干净地关闭。然后向 jail 中仍在运行的进程发送 SIGTERM,并等待最多 stop.timeout 秒(默认为 10 秒)让它们退出。超时之后,jail 会被移除,并用 SIGKILL 杀掉剩余的一切。如果 stop.timeout 设置为零,则不会发送 SIGTERM,jail 会立即被移除。这正是运行慢停止守护进程的 jail 在停止时看似挂起十秒的原因;对于运行数据库或其他需要更长时间才能优雅关闭的服务的 jail,可在 /etc/jail.conf 中调高 stop.timeout

17.10.3. 销毁 jail

销毁 jail 不是像使用 service(8) 停止 jail 并删除 jail 目录和 /etc/jail.conf 条目那么简单。

FreeBSD 非常重视系统安全。因此,某些文件即使是 root 用户也不能删除。这种功能称为文件标志(File Flags)。对于文件存储在 UFS 文件系统上的 jail,必须先清除这些标志才能删除 jail 目录。

第一步是停止所需的 jail,执行以下命令:

第二步是使用 chflags(1) 移除这些标志,执行以下命令,其中 classic 是要删除的 jail 名称:

第三步是删除包含 jail 的目录:

以上两步适用于存储在 UFS 文件系统上的 jail。如果 jail 由其专用的 ZFS 数据集支撑——如 设置 jail 目录结构 中所创建——则改为销毁数据集来移除。数据集销毁不受文件标志阻挡,因此此时不需要 chflags(1) 这一步:

加上 -r 可同时销毁数据集持有的所有快照。

注意

通过克隆模板快照创建的 ZFS 瘦 jail(参见 瘦 jail)依赖于该快照。只要还有克隆存在,zfs(8) 就会拒绝销毁模板快照,并打印依赖它的克隆列表。要退役一个模板,请先销毁从它克隆出的每个 jail,或对某个克隆执行 zfs promote 使其不再依赖模板。

最后,无论哪种情况,都需删除 /etc/jail.conf/etc/jail.conf.d 中的 jail 条目。对于 NullFS 瘦 jail,还要删除其 .fstab 文件和现已为空的挂载点目录。

17.10.4. 在 jail 中处理软件包

pkg(8) 工具支持 -j 参数,用于处理安装在 jail 中的软件包。

例如,要在 jail 中安装 www/nginx-lite,可从主机执行以下命令:

有关在 FreeBSD 中使用软件包的更多信息,请参见 安装应用程序:软件包和 Ports

17.10.5. 从主机管理 jail 中的服务

jail 中的服务可从主机启用和控制,无需先用 jexec(8) 进入 jail。service(8)sysrc(8) 都接受 -j 参数,通过 ID 或名称指定目标 jail,并作用于该 jail 的 rc(8) 配置。

延续上面的软件包示例,直接从主机在 classic jail 中启用并启动 nginx:

这些命令的效果与通过 jexec(8) 运行 sysrc(8)service(8) 相同,但它们让主机端的管理和脚本与非 jail 系统保持一致。

17.10.6. 访问 jail

虽然前面提到最好从主机系统管理 jail,但可使用 jexec(8) 进入 jail。

可从主机系统执行 jexec(8) 命令来进入 jail:

-u 标志选择以哪个用户身份运行,并针对主机的密码数据库解析名称。若要针对 jail 自己的密码数据库解析用户,请使用 -U。当未给定命令时(如这里),jexec(8) 会启动该用户在 jail 内的登录 shell。加上 -l 可在干净的登录环境中运行,仅保留 HOMESHELLTERMUSER,将 PATH 重置为 /bin:/usr/bin,行为如同全新登录;-d 设置工作目录,默认为 jail 根目录。

当进入 jail 时,系统将显示在 motd(5) 中配置的消息。

17.10.7. 在 jail 中执行命令

要从主机系统在 jail 中执行命令,可使用 jexec(8)

例如,要停止在 jail 中运行的服务,可执行以下命令:

17.10.8. 从主机查看 jail 中的进程和套接字

从主机上,每个 jail 的进程和套接字都是可见的,并可按 jail 过滤。

ps(1) 接受 -J 将输出限制为单个 jail,按 JID 或名称指定:

输出应该类似于以下内容,其中 STAT 列中的 J 标记表示进程在 jail 中运行:

使用 ps -J 0 可仅显示主机自己的进程。还可在 -o 输出格式中加入 jailjid 关键字,以显示每个进程所属的 jail。例如,列出主机上的每个进程及其所属 jail:

top(1) 接受 -J 将其实时显示过滤为单个 jail,这会隐含启用 -j 并添加 JID 列:

sockstat(1)-j 列出属于某个 jail 的套接字,这是检查 jail 中的守护进程在启动服务后实际绑定了哪些端口的自然方式:

从 jail 内部情况正好相反:jail 中的进程只能看到自己 jail 的进程和套接字,永远看不到主机或其他 jail 的。

17.10.9. 使用 jail 工具直接管理 jail

上面所示的 service(8) 包装器是开机时运行 jail 的常规方式,但 jail(8) 也可直接创建、修改和移除 jail,这对于脚本编写以及在不依赖 rc 框架的情况下测试配置很有用。

按名称创建已配置的 jail:

移除正在运行的 jail;这同时会移除它创建的任何子 jail 并杀掉其中的进程:

-m 标志可在不重启的情况下修改正在运行的 jail 的参数。例如,向正在运行的 jail 添加第二个 IPv4 地址:

jail(8) 指出“某些参数不能在正在运行的 jail 上更改”;实际中这包括 pathvnet,它们要求重启 jail。

最后,-e 可展示所有已配置的非通配符 jail 及其参数,而不会创建、修改或移除任何内容,便于验证配置文件。它接受一个用于分隔参数的字符串:

17.10.10. 备份和迁移 jail

jail 在很大程度上是自包含的,因此备份或迁移到另一台主机主要就是复制其文件和配置。

先停止 jail 以获得一致的副本;基于 ZFS 的 jail 可在运行时直接快照。对于位于其专用 ZFS 数据集上的 jail,可递归快照并流式传输到目标主机:

zfs-send(8)zfs-receive(8) 的完整机制(包括增量传输)在 复制 中说明。

对于位于 UFS 文件系统上的 jail,使用 tar(1)-p 以保留所有权、权限和文件标志:

在目标主机上以 root 身份用 tar -xpf 解压归档,以保留文件标志。当 jail 占用其专用的 UFS 文件系统时,dump(8)restore(8) 是替代方案;它们作用于整个文件系统,因此不适用于本章使用的布局——所有 jail 都是同一共享文件系统内的目录。

最后,将 jail 在 /etc/jail.conf 中的块——或它在 /etc/jail.conf.d 中的文件——复制到新主机,调整任何主机相关的参数(如 interfaceip4.addr 或 VNET jail 使用的网桥),然后在新主机上启动 jail。

警告

目标主机运行的 FreeBSD 发行版本不能比 jail 的用户空间旧,遵循与 jail 永远不能运行比宿主更新版本相同的规则。NullFS 瘦 jail 不是自包含的:其模板和骨架也必须存在于目标主机上,因此需一并迁移,或先将 jail 转换为厚拷贝。/etc/rctl.conf 中保存的任何 rctl(8) 规则必须单独带过去。

最后更新于