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

# 17.13.jail 资源限制

从主机系统控制 jail 使用的资源是系统管理员需要考虑的任务。

使用 [rctl(8)](https://man.freebsd.org/cgi/man.cgi?query=rctl\&sektion=8\&format=html) 从主机系统管理 jail 可使用的资源。

> **技巧**
>
> 必须在 **/boot/loader.conf** 中启用可调参数 `kern.racct.enable`。

限制 jail 资源的语法如下：

```sh
rctl -a jail:<jailname>:resource:action=amount[/per]
```

可选的 `per` 组件不是百分比，而是应用限制的核算实体，取值为 `process`、`user`、`loginclass` 或 `jail` 之一。例如，`deny=2G/jail` 限制整个 jail 的总和，而 `deny=2G/process` 对每个进程单独应用同一数值。百分比仅对 `pcpu` 资源有意义，其数量表示为单个 CPU 核心的百分比。

例如，要限制 jail 可访问的最大内存，可执行以下命令：

```sh
# rctl -a jail:classic:memoryuse:deny=2G
```

为了使此限制在主机系统重启后仍然生效，需要将规则添加到 **/etc/rctl.conf** 文件中，如下所示：

```sh
jail:classic:memoryuse:deny=2G/jail
```

[rctl(8)](https://man.freebsd.org/cgi/man.cgi?query=rctl\&sektion=8\&format=html) 能限制的远不止内存。与 jail 最相关的资源包括 `pcpu`（单个 CPU 核心的百分比）、`maxproc`（进程数）、`openfiles`（打开的文件描述符）、`vmemoryuse`（地址空间）和 `swapuse`（交换空间）。它们的设置方式相同：

```sh
# rctl -a jail:classic:pcpu:deny=80
# rctl -a jail:classic:maxproc:deny=1000
# rctl -a jail:classic:openfiles:deny=5000
# rctl -a jail:classic:vmemoryuse:deny=4G
```

磁盘吞吐量用 `readbps` 和 `writebps` 限制，但这两个资源不支持 `deny` 动作；需配合 `throttle` 使用：

```sh
# rctl -a jail:classic:writebps:throttle=1m
```

资源后的动作选择达到限制时的行为：`deny` 阻止操作，`log` 将其记录到系统日志，`devctl` 通过 [devd(8)](https://man.freebsd.org/cgi/man.cgi?query=devd\&sektion=8\&format=html) 发送通知。

用 `-u` 标志报告 jail 当前的资源使用情况，加上 `-h` 可获取易读的单位：

```sh
# rctl -hu jail:classic
```

列出应用于某个 jail 的规则：

```sh
# rctl jail:classic
```

用 `-r` 移除匹配某个 jail 的所有规则：

```sh
# rctl -r jail:classic
```

有关资源限制的更多信息，请参见安全一章中的 [资源限制一节](/di-16-zhang-an-quan/16.14.-zi-yuan-xian-zhi.md)。

## 17.13.1. 使用 cpuset 进行 CPU 绑定

带 `pcpu` 的 [rctl(8)](https://man.freebsd.org/cgi/man.cgi?query=rctl\&sektion=8\&format=html) 上限控制的是 jail 可消耗的 CPU 时间，但它不会将 jail 绑定到特定核心；[cpuset(1)](https://man.freebsd.org/cgi/man.cgi?query=cpuset\&sektion=1\&format=html) 则负责分配特定核心。

按名称或 JID 将正在运行的 jail 限制到一组 CPU：

```sh
# cpuset -l 0-3 -j classic
```

用 `-g` 查询 jail 当前被允许使用的核心：

```sh
# cpuset -g -j classic
```

分配的集合也显示在 `jls -v` 的 cpuset 列中。没有用于 CPU 亲和性的 jail.conf 参数，因此在启动时通过 `exec.created` 或 `exec.poststart` 钩子运行 [cpuset(1)](https://man.freebsd.org/cgi/man.cgi?query=cpuset\&sektion=1\&format=html) 来绑定 jail，这两个钩子都在宿主环境中运行：

```sh
exec.poststart = "cpuset -l 0-3 -j classic";
```

## 17.13.2. 限制磁盘空间

[rctl(8)](https://man.freebsd.org/cgi/man.cgi?query=rctl\&sektion=8\&format=html) 没有用于文件系统空间的资源。当每个 jail 位于其自己的 ZFS 数据集中时，改用 ZFS 配额和预留来上限化和保证其磁盘使用：

```sh
# zfs set quota=20G zroot/jails/containers/classic
# zfs set reservation=5G zroot/jails/containers/classic
```

这要求 jail 是其独立的数据集。前面创建的 ZFS 瘦 jail 已经是了，但传统 jail 流程在共享的 **containers** 数据集内用 `mkdir` 创建 jail 目录，因此要使这些命令生效，请先用 `zfs create` 创建。数据集布局参见 [设置 jail 目录结构](/di-17-zhang-jail-yu-rong-qi/17.3.-zhu-ji-pei-zhi-jail.md)，`quota` 和 `reservation` 属性参见 [zfs-set(8)](https://man.freebsd.org/cgi/man.cgi?query=zfs-set\&sektion=8\&format=html)。
