17.12.升级 jail
升级 FreeBSD jail 可确保这些隔离环境保持安全、最新,并与 FreeBSD 生态系统中可用的最新功能和改进保持一致。
正确的工具取决于 jail 用户空间的安装方式。从发行集安装的 jail(创建章节中解压的 base.txz,或由 bsdinstall(8) 生成的发行集)在 FreeBSD 14.x 和 15.x 上都通过 -j 标志从主机上用 freebsd-update(8) 更新。从 FreeBSD 15.0 起可用的、从基础软件包安装的 jail,改用 pkg(8) 更新;freebsd-update(8) 不适用于它们。从源码构建的 jail 用源码流程(make installworld 和 make distribution)更新。绝不要在同一 jail 上混用这些机制。
注意
对发行集的支持计划在 FreeBSD 16 中移除,但将与 freebsd-update(8) 一起在 FreeBSD 15 稳定分支的生命周期内继续存在。基础软件包在 FreeBSD 15.0 中作为技术预览提供,并有望在未来的发行版本中成为标准方法,因此 pkgbase 是面向未来的路径。
技巧
在 OpenZFS 上,升级前对 jail 的数据集进行快照,这样失败的升级可立即撤销:
# zfs snapshot zroot/jails/containers/classic@preupgrade如果升级失败,停止 jail 并运行
zfs rollback zroot/jails/containers/classic@preupgrade以恢复之前的状态。这要求 jail 是其独立的数据集:OpenZFS 瘦 jail 克隆已经是了,但用 mkdir(1) 创建的传统 jail 不是,因此请改用zfs create创建。对于 NullFS 瘦 jail,改为对模板数据集快照。zfs-rollback(8) 仅回滚到最近的快照,除非加上-r以销毁更新的快照。
17.12.1. 升级传统 jail 或使用 OpenZFS 快照的瘦 jail
jail 必须从主机操作系统更新。FreeBSD 的默认行为是不能在 jail 中使用 chflags(1),这会阻止某些文件的更新,因此从 jail 内部更新将失败。
要将 jail 更新为正在运行的 FreeBSD 版本的最新补丁版本,请在主机上执行以下命令:
# freebsd-update -j classic fetch install
# service jail restart classic要将 jail 升级到新的主要或次要版本,首先按照 执行主要和次要版本升级 的说明升级主机系统。主机系统升级并重新启动后,便可升级 jail。
技巧
在版本之间升级时,创建新 jail 比完全升级更容易。
例如,要将 classic jail 升级到 14.3-RELEASE,请在主机上执行以下命令:
注意
必须执行两次
install步骤。jail 没有自己的内核(它运行宿主的内核),因此这里不会升级任何内核。第一次install将新的用户空间写入 jail;jail 在更新的文件上重启后,第二次install完成替换那些在之前版本仍在使用时无法更改的组件。
然后,如果是主要版本升级,则需要重新安装所有已安装的软件包并重新启动 jail。这是因为在主要版本之间升级时,ABI 版本会发生变化。
从主机执行以下命令:
17.12.2. 升级 OpenZFS 瘦 jail
使用 OpenZFS 快照创建瘦 jail 中创建的瘦 jail 是模板快照的 OpenZFS 克隆,但克隆一旦存在就独立于该模板。刷新模板不会更新已经从它克隆出的 jail,而更新克隆也不会更新模板。因此有两种方式来保持这些 jail 最新。
第一种方式是用 freebsd-update(8) 就地更新每个克隆,与传统 jail 完全相同,如本节“升级传统 jail 或使用 OpenZFS 快照的瘦 jail”小节所述。对于少量 jail 这是最简单的方式,但每个被打过补丁的克隆都会偏离模板快照:更改的块按每个 jail 重复存储,从而侵蚀了空间节省;而主要版本升级会重写大量用户空间,使大部分共享丢失。
第二种方式通过刷新模板并重新克隆来保持共享。在主机上将模板更新到最新的补丁级别:
注意
带有
-b的 freebsd-update(8) 从主机的uname -r读取正在运行的发行版本,而非从模板读取。如果模板运行的发行版本比宿主旧,请加上--currently-running <template-release>,使其为模板的发行版本打补丁而非宿主的,如 使用 NullFS 升级瘦 jail 中所示。
然后拍摄新的快照并从它克隆未来的 jail:
现有的克隆会保留创建时使用的基础,直到从新快照重新创建为止。对于主要或次要版本升级,请按照 使用 OpenZFS 快照创建瘦 jail 为新发行版本创建全新的模板数据集,而不是就地升级现有模板,并从其 @base 快照克隆新 jail。
技巧
将每个 jail 的应用数据和配置保存在独立的数据集上,或保存在 jail 的本地存储中,这样从更新的模板快照重新创建 jail 的成本低廉,并优于逐个为每个克隆打补丁。
17.12.3. 使用 NullFS 升级瘦 jail
由于使用 NullFS 的瘦 jail 共享大部分系统目录,因此它们非常容易更新。只需要更新模板即可,这样就能同时更新多个 jail。
要将模板更新为正在运行的 FreeBSD 版本的最新补丁版本,请在主机上执行以下命令:
要将模板升级到新的主要或次要版本,首先按照 执行主要和次要版本升级 的说明升级主机系统。主机系统升级并重新启动后,便可升级模板。
因为主机先升级,带 -b 的 freebsd-update(8) 会检测到宿主的新发行版本而非模板的旧发行版本:-b 从主机的 uname -r 读取运行版本,与 -j 不同——后者检测 jail 自己的用户空间。传入 --currently-running <template-release>,使模板从其真实发行版本打补丁。以下示例将运行 14.2-RELEASE 的模板升级到 14.3-RELEASE;请替换为适用的发行版本:
17.12.4. 升级 pkgbase jail
从 FreeBSD 15.0 起可用的、从基础软件包安装的 jail,用 pkg(8) 针对 FreeBSD-base 存储库升级,而非用 freebsd-update(8)。
FreeBSD-base 存储库在 /etc/pkg/FreeBSD.conf 中定义,但在 FreeBSD 15.0 上默认禁用,因此升级前请先启用它。
从主机上,用 -r(--rootdir)将 pkg(8) 指向 jail 的根目录:
同样的升级可从 jail 内部用 jexec(8) 和普通的 pkg upgrade 执行:
pkg(8) 对 /etc 下带标记的配置文件执行三方合并。当合并无法自动完成时,它将新版本留作 .pkgnew;当它接管之前未打包的文件时,将旧副本保存为 .pkgsave。升级后请检查 /etc,并手动调和这些文件。不要在 pkgbase 系统上运行 etcupdate(8);pkg(8) 自行处理配置合并。主机的 base package 工作流参见 使用软件包更新 FreeBSD。
最后更新于