> For the complete documentation index, see [llms.txt](https://book.bsdcn.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://book.bsdcn.org/handbook/di-17-zhang-jail-yu-rong-qi/17.12.-geng-xin-jail.md).

# 17.12.升级 jail

升级 FreeBSD jail 可确保这些隔离环境保持安全、最新，并与 FreeBSD 生态系统中可用的最新功能和改进保持一致。

正确的工具取决于 jail 用户空间的安装方式。从发行集安装的 jail（创建章节中解压的 **base.txz**，或由 [bsdinstall(8)](https://man.freebsd.org/cgi/man.cgi?query=bsdinstall\&sektion=8\&format=html) 生成的发行集）在 FreeBSD 14.x 和 15.x 上都通过 `-j` 标志从主机上用 [freebsd-update(8)](https://man.freebsd.org/cgi/man.cgi?query=freebsd-update\&sektion=8\&format=html) 更新。从 FreeBSD 15.0 起可用的、从基础软件包安装的 jail，改用 [pkg(8)](https://man.freebsd.org/cgi/man.cgi?query=pkg\&sektion=8\&format=html) 更新；[freebsd-update(8)](https://man.freebsd.org/cgi/man.cgi?query=freebsd-update\&sektion=8\&format=html) 不适用于它们。从源码构建的 jail 用源码流程（`make installworld` 和 `make distribution`）更新。绝不要在同一 jail 上混用这些机制。

> **注意**
>
> 对发行集的支持计划在 FreeBSD 16 中移除，但将与 [freebsd-update(8)](https://man.freebsd.org/cgi/man.cgi?query=freebsd-update\&sektion=8\&format=html) 一起在 FreeBSD 15 稳定分支的生命周期内继续存在。基础软件包在 FreeBSD 15.0 中作为技术预览提供，并有望在未来的发行版本中成为标准方法，因此 pkgbase 是面向未来的路径。

> **技巧**
>
> 在 OpenZFS 上，升级前对 jail 的数据集进行快照，这样失败的升级可立即撤销：

```sh
# zfs snapshot zroot/jails/containers/classic@preupgrade
```

> 如果升级失败，停止 jail 并运行 `zfs rollback zroot/jails/containers/classic@preupgrade` 以恢复之前的状态。这要求 jail 是其独立的数据集：OpenZFS 瘦 jail 克隆已经是了，但用 [mkdir(1)](https://man.freebsd.org/cgi/man.cgi?query=mkdir\&sektion=1\&format=html) 创建的传统 jail 不是，因此请改用 `zfs create` 创建。对于 NullFS 瘦 jail，改为对模板数据集快照。[zfs-rollback(8)](https://man.freebsd.org/cgi/man.cgi?query=zfs-rollback\&sektion=8\&format=html) 仅回滚到最近的快照，除非加上 `-r` 以销毁更新的快照。

## 17.12.1. 升级传统 jail 或使用 OpenZFS 快照的瘦 jail

jail **必须从主机**操作系统更新。FreeBSD 的默认行为是不能在 jail 中使用 [chflags(1)](https://man.freebsd.org/cgi/man.cgi?query=chflags\&sektion=1\&format=html)，这会阻止某些文件的更新，因此从 jail 内部更新将失败。

要将 jail 更新为正在运行的 FreeBSD 版本的最新补丁版本，请在主机上执行以下命令：

```sh
# freebsd-update -j classic fetch install
# service jail restart classic
```

要将 jail 升级到新的主要或次要版本，首先按照 [执行主要和次要版本升级](/handbook/di-27-zhang-freebsd-geng-xin-yu-sheng-ji/27.2.-geng-xin-freebsd.md) 的说明升级主机系统。主机系统升级并重新启动后，便可升级 jail。

> **技巧**
>
> 在版本之间升级时，创建新 jail 比完全升级更容易。

例如，要将 `classic` jail 升级到 14.3-RELEASE，请在主机上执行以下命令：

```sh
# freebsd-update -j classic -r 14.3-RELEASE upgrade
# freebsd-update -j classic install
# service jail restart classic
# freebsd-update -j classic install
# service jail restart classic
```

> **注意**
>
> 必须执行两次 `install` 步骤。jail 没有自己的内核（它运行宿主的内核），因此这里不会升级任何内核。第一次 `install` 将新的用户空间写入 jail；jail 在更新的文件上重启后，第二次 `install` 完成替换那些在之前版本仍在使用时无法更改的组件。

然后，如果是主要版本升级，则需要重新安装所有已安装的软件包并重新启动 jail。这是因为在主要版本之间升级时，ABI 版本会发生变化。

从主机执行以下命令：

```sh
# pkg -j classic upgrade -f
# service jail restart classic
```

## 17.12.2. 升级 OpenZFS 瘦 jail

[使用 OpenZFS 快照创建瘦 jail](/handbook/di-17-zhang-jail-yu-rong-qi/17.5.-shou-jail.md) 中创建的瘦 jail 是模板快照的 OpenZFS 克隆，但克隆一旦存在就独立于该模板。刷新模板*不会*更新已经从它克隆出的 jail，而更新克隆也*不会*更新模板。因此有两种方式来保持这些 jail 最新。

第一种方式是用 [freebsd-update(8)](https://man.freebsd.org/cgi/man.cgi?query=freebsd-update\&sektion=8\&format=html) 就地更新每个克隆，与传统 jail 完全相同，如本节“升级传统 jail 或使用 OpenZFS 快照的瘦 jail”小节所述。对于少量 jail 这是最简单的方式，但每个被打过补丁的克隆都会偏离模板快照：更改的块按每个 jail 重复存储，从而侵蚀了空间节省；而主要版本升级会重写大量用户空间，使大部分共享丢失。

第二种方式通过刷新模板并重新克隆来保持共享。在主机上将模板更新到最新的补丁级别：

```sh
# freebsd-update -b /usr/local/jails/templates/14.3-RELEASE/ fetch install
```

> **注意**
>
> 带有 `-b` 的 [freebsd-update(8)](https://man.freebsd.org/cgi/man.cgi?query=freebsd-update\&sektion=8\&format=html) 从主机的 `uname -r` 读取正在运行的发行版本，而非从模板读取。如果模板运行的发行版本比宿主旧，请加上 `--currently-running <template-release>`，使其为模板的发行版本打补丁而非宿主的，如 [使用 NullFS 升级瘦 jail](/handbook/di-17-zhang-jail-yu-rong-qi/17.12.-geng-xin-jail.md) 中所示。

然后拍摄新的快照并从它克隆未来的 jail：

```sh
# zfs snapshot zroot/jails/templates/14.3-RELEASE@base-p2
# zfs clone zroot/jails/templates/14.3-RELEASE@base-p2 zroot/jails/containers/newjail
```

现有的克隆会保留创建时使用的基础，直到从新快照重新创建为止。对于主要或次要版本升级，请按照 [使用 OpenZFS 快照创建瘦 jail](/handbook/di-17-zhang-jail-yu-rong-qi/17.5.-shou-jail.md) 为新发行版本创建全新的模板数据集，而不是就地升级现有模板，并从其 `@base` 快照克隆新 jail。

> **技巧**
>
> 将每个 jail 的应用数据和配置保存在独立的数据集上，或保存在 jail 的本地存储中，这样从更新的模板快照重新创建 jail 的成本低廉，并优于逐个为每个克隆打补丁。

## 17.12.3. 使用 NullFS 升级瘦 jail

由于使用 NullFS 的瘦 jail 共享大部分系统目录，因此它们非常容易更新。只需要更新模板即可，这样就能同时更新多个 jail。

要将模板更新为正在运行的 FreeBSD 版本的最新补丁版本，请在主机上执行以下命令：

```sh
# freebsd-update -b /usr/local/jails/templates/14.3-RELEASE-base/ fetch install
# service jail restart
```

要将模板升级到新的主要或次要版本，首先按照 [执行主要和次要版本升级](/handbook/di-27-zhang-freebsd-geng-xin-yu-sheng-ji/27.2.-geng-xin-freebsd.md) 的说明升级主机系统。主机系统升级并重新启动后，便可升级模板。

因为主机先升级，带 `-b` 的 [freebsd-update(8)](https://man.freebsd.org/cgi/man.cgi?query=freebsd-update\&sektion=8\&format=html) 会检测到宿主的新发行版本而非模板的旧发行版本：`-b` 从主机的 `uname -r` 读取运行版本，与 `-j` 不同——后者检测 jail 自己的用户空间。传入 `--currently-running <template-release>`，使模板从其真实发行版本打补丁。以下示例将运行 14.2-RELEASE 的模板升级到 14.3-RELEASE；请替换为适用的发行版本：

```sh
# freebsd-update -b /usr/local/jails/templates/14.2-RELEASE-base/ --currently-running 14.2-RELEASE -r 14.3-RELEASE upgrade
# freebsd-update -b /usr/local/jails/templates/14.2-RELEASE-base/ install
# service jail restart
# freebsd-update -b /usr/local/jails/templates/14.2-RELEASE-base/ install
# service jail restart
```

## 17.12.4. 升级 pkgbase jail

从 FreeBSD 15.0 起可用的、从基础软件包安装的 jail，用 [pkg(8)](https://man.freebsd.org/cgi/man.cgi?query=pkg\&sektion=8\&format=html) 针对 `FreeBSD-base` 存储库升级，而非用 [freebsd-update(8)](https://man.freebsd.org/cgi/man.cgi?query=freebsd-update\&sektion=8\&format=html)。

`FreeBSD-base` 存储库在 **/etc/pkg/FreeBSD.conf** 中定义，但在 FreeBSD 15.0 上默认禁用，因此升级前请先启用它。

从主机上，用 `-r`（`--rootdir`）将 [pkg(8)](https://man.freebsd.org/cgi/man.cgi?query=pkg\&sektion=8\&format=html) 指向 jail 的根目录：

```sh
# pkg -r /usr/local/jails/containers/pkgjail update
# pkg -r /usr/local/jails/containers/pkgjail upgrade
# service jail restart pkgjail
```

同样的升级可从 jail 内部用 [jexec(8)](https://man.freebsd.org/cgi/man.cgi?query=jexec\&sektion=8\&format=html) 和普通的 `pkg upgrade` 执行：

```sh
# jexec -l pkgjail pkg upgrade
# service jail restart pkgjail
```

[pkg(8)](https://man.freebsd.org/cgi/man.cgi?query=pkg\&sektion=8\&format=html) 对 **/etc** 下带标记的配置文件执行三方合并。当合并无法自动完成时，它将新版本留作 **.pkgnew**；当它接管之前未打包的文件时，将旧副本保存为 **.pkgsave**。升级后请检查 **/etc**，并手动调和这些文件。不要在 pkgbase 系统上运行 [etcupdate(8)](https://man.freebsd.org/cgi/man.cgi?query=etcupdate\&sektion=8\&format=html)；[pkg(8)](https://man.freebsd.org/cgi/man.cgi?query=pkg\&sektion=8\&format=html) 自行处理配置合并。主机的 base package 工作流参见 [使用软件包更新 FreeBSD](/handbook/di-27-zhang-freebsd-geng-xin-yu-sheng-ji/27.7.-pkgbase.md)。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://book.bsdcn.org/handbook/di-17-zhang-jail-yu-rong-qi/17.12.-geng-xin-jail.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
