> 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.5.-shou-jail.md).

# 17.5.瘦 jail

虽然瘦 jail 使用与厚 jail 相同的技术，但创建过程是不同的。瘦 jail 可通过 OpenZFS 快照或使用模板和 NullFS 创建。使用 OpenZFS 快照和模板结合 NullFS 相比传统的 jail 有一些优势，例如能更快速地从快照中创建，或者能通过 NullFS 更新多个 jail。

## 17.5.1. 使用 OpenZFS 快照创建瘦 jail

由于 FreeBSD 和 OpenZFS 的良好集成，通过 OpenZFS 快照创建新的瘦 jail 非常容易。

要通过 OpenZFS 快照创建瘦 jail，第一步是按照[设置 jail 目录结构](/handbook/di-17-zhang-jail-yu-rong-qi/17.3.-zhu-ji-pei-zhi-jail.md)中的说明创建 jail 目录树。

接下来，创建模板。模板仅用于创建新的 jail。因此，它们以“只读”模式创建，以便基于不可变的基础创建 jail。

要为模板创建数据集，执行以下命令：

```sh
# zfs create -p zroot/jails/templates/15.1-RELEASE
```

然后执行以下命令下载用户空间：

```sh
# fetch https://download.freebsd.org/ftp/releases/amd64/amd64/15.1-RELEASE/base.txz -o /usr/local/jails/media/15.1-RELEASE-base.txz
```

下载完成后，需要通过以下命令将内容解压到模板目录中：

```sh
# tar -xf /usr/local/jails/media/15.1-RELEASE-base.txz -C /usr/local/jails/templates/15.1-RELEASE --unlink
```

在模板目录中提取用户空间后，需要通过以下命令将时区和 DNS 服务器文件复制到模板目录中：

```sh
# cp /etc/resolv.conf /usr/local/jails/templates/15.1-RELEASE/etc/resolv.conf
# cp /etc/localtime /usr/local/jails/templates/15.1-RELEASE/etc/localtime
```

接下来，执行以下命令更新到最新的补丁级别：

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

更新完成后，模板就准备好了。

要从模板创建 OpenZFS 快照，执行以下命令：

```sh
# zfs snapshot zroot/jails/templates/15.1-RELEASE@base
```

创建 OpenZFS 快照后，即可使用 OpenZFS 克隆功能创建无限多个 jail。

要创建名为 `thinjail` 的瘦 jail，执行以下命令：

```sh
# zfs clone zroot/jails/templates/15.1-RELEASE@base zroot/jails/containers/thinjail
```

最后一步是配置 jail。需要在配置文件 **/etc/jail.conf** 或 **jail.conf.d** 目录中添加包含该 jail 参数的条目。

例如，配置可能如下所示：

```sh
thinjail {
  # 启动/日志记录
  exec.start = "/bin/sh /etc/rc";
  exec.stop = "/bin/sh /etc/rc.shutdown";
  exec.consolelog = "/var/log/jail_console_${name}.log";

  # 权限
  allow.raw_sockets;
  exec.clean;
  mount.devfs;

  # 主机名/路径
  host.hostname = "${name}";
  path = "/usr/local/jails/containers/${name}";

  # 网络
  ip4 = inherit;
  interface = em0;
}
```

执行以下命令启动 jail：

```sh
# service jail start thinjail
```

有关如何管理 jail 的更多信息，请参阅[管理 jail](/handbook/di-17-zhang-jail-yu-rong-qi/17.10.-guan-li-jail.md)一节。

## 17.5.2. 使用 NullFS 创建瘦 jail

通过使用瘦 jail 技术并利用 NullFS 有选择性地共享主机系统中的特定目录，可减少系统文件的重复，从而创建瘦 jail。

第一步是创建用于保存模板的数据集。如果使用 OpenZFS，请执行以下命令：

```sh
# zfs create -p zroot/jails/templates/15.1-RELEASE-base
```

如果使用 UFS，请执行以下命令：

```sh
# mkdir /usr/local/jails/templates/15.1-RELEASE-base
```

然后执行以下命令下载用户空间：

```sh
# fetch https://download.freebsd.org/ftp/releases/amd64/amd64/15.1-RELEASE/base.txz -o /usr/local/jails/media/15.1-RELEASE-base.txz
```

下载完成后，需要通过以下命令将内容解压到模板目录中：

```sh
# tar -xf /usr/local/jails/media/15.1-RELEASE-base.txz -C /usr/local/jails/templates/15.1-RELEASE-base --unlink
```

用户空间提取到模板目录后，需要通过以下命令将时区和 DNS 服务器文件复制到模板目录中：

```sh
# cp /etc/resolv.conf /usr/local/jails/templates/15.1-RELEASE-base/etc/resolv.conf
# cp /etc/localtime /usr/local/jails/templates/15.1-RELEASE-base/etc/localtime
```

将文件移动到模板中后，接下来执行以下命令更新到最新的补丁级别：

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

除了基础模板外，还需要创建目录来存放 `skeleton`。一些目录将从模板复制到 `skeleton` 中。

如果使用 OpenZFS，请执行以下命令来创建 `skeleton` 的数据集：

```sh
# zfs create -p zroot/jails/templates/15.1-RELEASE-skeleton
```

如果使用 UFS，请执行以下命令：

```sh
# mkdir /usr/local/jails/templates/15.1-RELEASE-skeleton
```

然后创建 `skeleton` 目录。`skeleton` 目录将存放 jail 的本地目录。

执行以下命令创建这些目录：

```sh
# mkdir -p /usr/local/jails/templates/15.1-RELEASE-skeleton/home
# mkdir -p /usr/local/jails/templates/15.1-RELEASE-skeleton/usr
# mv /usr/local/jails/templates/15.1-RELEASE-base/etc /usr/local/jails/templates/15.1-RELEASE-skeleton/etc
# mv /usr/local/jails/templates/15.1-RELEASE-base/usr/local /usr/local/jails/templates/15.1-RELEASE-skeleton/usr/local
# mv /usr/local/jails/templates/15.1-RELEASE-base/tmp /usr/local/jails/templates/15.1-RELEASE-skeleton/tmp
# mv /usr/local/jails/templates/15.1-RELEASE-base/var /usr/local/jails/templates/15.1-RELEASE-skeleton/var
# mv /usr/local/jails/templates/15.1-RELEASE-base/root /usr/local/jails/templates/15.1-RELEASE-skeleton/root
```

接下来，执行以下命令创建指向 `skeleton` 的符号链接：

```sh
# cd /usr/local/jails/templates/15.1-RELEASE-base/
# mkdir skeleton
# ln -s skeleton/etc etc
# ln -s skeleton/home home
# ln -s skeleton/root root
# ln -s ../skeleton/usr/local usr/local
# ln -s skeleton/tmp tmp
# ln -s skeleton/var var
```

`skeleton` 准备好后，需要将数据复制到 jail 目录中。

如果使用 OpenZFS，可使用 OpenZFS 快照轻松创建所需数量的 jail，执行以下命令：

```sh
# zfs snapshot zroot/jails/templates/15.1-RELEASE-skeleton@base
# zfs clone zroot/jails/templates/15.1-RELEASE-skeleton@base zroot/jails/containers/thinjail
```

如果使用 UFS，可使用 [cp(1)](https://man.freebsd.org/cgi/man.cgi?query=cp\&sektion=1\&format=html) 程序，执行以下命令：

```sh
# cp -R /usr/local/jails/templates/15.1-RELEASE-skeleton /usr/local/jails/containers/thinjail
```

然后创建目录，用于挂载基础模板和 `skeleton`：

```sh
# mkdir -p /usr/local/jails/thinjail-nullfs-base
```

在 **/etc/jail.conf** 或 **jail.conf.d** 目录的文件中添加 jail 条目，如下所示：

```sh
thinjail {
  # 启动/日志记录
  exec.start = "/bin/sh /etc/rc";
  exec.stop = "/bin/sh /etc/rc.shutdown";
  exec.consolelog = "/var/log/jail_console_${name}.log";

  # 权限
  allow.raw_sockets;
  exec.clean;
  mount.devfs;

  # 主机名/路径
  host.hostname = "${name}";
  path = "/usr/local/jails/${name}-nullfs-base";

  # 网络
  ip4.addr = 192.168.1.153;
  interface = em0;

  # 挂载
  mount.fstab = "/usr/local/jails/${name}-nullfs-base.fstab";
}
```

然后创建 **/usr/local/jails/thinjail-nullfs-base.fstab** 文件，内容如下：

```sh
/usr/local/jails/templates/15.1-RELEASE-base  /usr/local/jails/thinjail-nullfs-base/ nullfs   ro          0 0
/usr/local/jails/containers/thinjail     /usr/local/jails/thinjail-nullfs-base/skeleton nullfs  rw  0 0
```

**fstab** 文件控制 [mount\_nullfs(8)](https://man.freebsd.org/cgi/man.cgi?query=mount_nullfs\&sektion=8\&format=html) 如何在 jail 内部呈现基础模板和 skeleton。基础模板以只读（`ro`）方式挂载，使每个 NullFS jail 共享一份不可变的基本系统副本。每个 jail 的 skeleton 以读写（`rw`）方式挂载，这是每个 jail 存放自己可写 **/etc**、**/var**、**/usr/local** 等本地目录的地方。由于所有 jail 共享同一份只读基础模板，更新该模板可同时更新所有 NullFS jail，这与必须分别独立更新的 OpenZFS 克隆不同。

执行以下命令启动 jail：

```sh
# service jail start thinjail
```


---

# 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.5.-shou-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.
