systemd.resource-control 中文手册

译者:金步国


版权声明

本文译者是一位开源理念的坚定支持者,所以本文虽然不是软件,但是遵照开源的精神发布。

其他作品

本文译者十分愿意与他人分享劳动成果,如果你对我的其他翻译作品或者技术文章有兴趣,可以在如下位置查看现有的作品集:

联系方式

由于译者水平有限,因此不能保证译文内容准确无误。如果你发现了译文中的错误(哪怕是错别字也好),请来信指出,任何提高译文质量的建议我都将虚心接纳。


手册索引 . 指令索引systemd-231

名称

systemd.resource-control — 单元的资源限制

大纲

slice.slice, scope.scope, service.service, socket.socket, mount.mount, swap.swap

描述

slice, scope, service, socket, mount, swap 单元共享一组用于限制进程资源占用的配置选项(亦称"配置指令"或"单元属性")。 本质上,这些选项依赖于内核的 Control Groups 功能: 将一组进程组织成树形层次结构, 并对其允许占用的各种资源进行限制。

systemd.unit(5) 列出了通用于所有单元的配置选项, 而本文列出的配置选项仅通用于如下六种单元: systemd.slice(5), systemd.scope(5), systemd.service(5), systemd.socket(5), systemd.mount(5), systemd.swap(5) 。 注意, 根据所处单元类型的不同, 应该将本文的配置选项分别放置到对应的 [Slice], [Scope], [Service], [Socket], [Mount], [Swap] 小节中。

参见 New Control Group Interfaces 文档以了解如何在程序中利用资源控制API

自动依赖

所有设置了 Slice= 的单元都会自动添加对于指定 slice 单元的 Requires=After= 依赖。

新式资源控制选项

从Linux-4.5开始,内核正式引入了新式的单一层次(unified hierarchy)资源控制接口,也就是"Cgroup v2"。 新接口最大的变化在于同一个进程现在只能属于单个层次(hierarchy),而不是原来的多个层次,从而降低了代码复杂度并且更易于理解。 新接口不仅增强了资源控制的能力,也导致了某些资源控制选项的名称发生了变化:

IO

IO 为前缀的新选项取代了原来以 BlockIO 为前缀的选项,并且新增了一些原来没有的选项。 现在这些新式的IO资源控制选项也可以作用于有缓存的写操作。

Memory

新式的 MemoryMax= 选项替代了原有的 MemoryLimit= 选项; 同时新增了 MemoryLow=MemoryHigh= 选项。

尽管 systemd 开发者已经尽了最大努力来确保可以在新旧两组选项之间平滑过度。 但是用户还是必须确保要么统一使用新式选项(内核版本大于4.5)、要么统一使用旧式选项(内核版本小于4.5), 混合使用新旧两种选项可能会导致意想不到的结果。

选项

可以识别的资源控制选项(亦称"指令"或"属性")如下:

CPUAccounting=

若设为"yes"则表示为此单元开启CPU占用统计。 注意,这同时也隐含的开启了该单元 所属的 slice 以及父 slice 内所有单元的CPU占用统计。 此选项的默认值由 DefaultCPUAccounting= 决定(参见 systemd-system.conf(5)手册)。

CPUShares=weight, StartupCPUShares=weight

为此单元的进程设置CPU时间的分配权重, 这两个选项控制着cgroup的 "cpu.shares" 属性值, 这两个选项的默认值都是1024, 取值范围都是 2-262144 之间的整数。 详见 sched-design-CFS.txt 文档。 总的可用CPU时间会在同一 slice 内的每个单元之间, 依据各单元的分配权重进行分配。

StartupCPUShares= 仅用于系统启动过程, 而 CPUShares= 则用于系统正常运行过程, 并且在前者未设置时亦可作用于系统启动过程。 通常使用 StartupCPUShares= 让特定的服务 在系统启动过程中拥有与运行时不一样的CPU优先级。

这两个选项都隐含着 "CPUAccounting=yes"

CPUQuota=

为此单元的进程设置CPU时间限额, 必须设为一个以"%"结尾的百分数, 表示该单元最多可使用单颗CPU总时间的百分之多少。 若设为大于 100% 的值则表示可以占用多颗CPU资源。 此选项控制着cgroup的 "cpu.cfs_quota_us" 属性值, 详见 sched-design-CFS.txt 文档。

例如 CPUQuota=20% 能够确保 此单元的进程永远不会使用超过 20% 的单颗CPU时间。

此选项隐含着 "CPUAccounting=yes"

MemoryAccounting=

若设为"yes"则表示为此单元开启内存占用统计。 注意,这同时也隐含的开启了该单元 所属的 slice 以及父 slice 内所有单元的内存占用统计。 此选项的默认值由 DefaultMemoryAccounting= 决定(参见 systemd-system.conf(5) 手册)。

MemoryLow=bytes

尽可能保障该单元中的进程至少可以使用多少内存。 如果该单元及其所有父单元的内存用量都低于最低保障线,那么只要还可以从其他未受保护的单元回收内存, 就不会回收该单元占用的内存。

选项值可以是以字节为单位的绝对内存大小(可以使用以1024为基数的 K, M, G, T 后缀), 也可以是以百分比表示的相对内存大小(相对于系统的全部物理内存)。 此选项控制着cgroup的 "memory.low" 属性值, 详见 cgroup-v2.txt 文档。

此选项隐含着 "MemoryAccounting=yes"

此选项是新式资源控制选项

MemoryHigh=bytes

尽可能限制该单元中的进程最多可以使用多少内存。 虽然这是一个允许被突破的柔性限制,但是突破限制后,进程的运行速度将会大打折扣, 并且系统将会尽可能尽快回收超出的内存。此选项的目的在于柔性限制内存使用量。

选项值可以是以字节为单位的绝对内存大小(可以使用以1024为基数的 K, M, G, T 后缀), 也可以是以百分比表示的相对内存大小(相对于系统的全部物理内存), 还可以设为特殊值 "infinity" 表示不作限制。 此选项控制着cgroup的 "memory.high" 属性值,详见 cgroup-v2.txt 文档。

此选项隐含着 "MemoryAccounting=yes"

此选项是新式资源控制选项

MemoryMax=bytes

绝对刚性的限制该单元中的进程最多可以使用多少内存。 这是一个不允许突破的刚性限制,触碰此限制会导致进程由于内存不足而被强制杀死。 建议将 MemoryHigh= 用作主要的内存限制手段, 而将 MemoryMax= 用作不可突破的底线。

选项值可以是以字节为单位的绝对内存大小(可以使用以1024为基数的 K, M, G, T 后缀), 也可以是以百分比表示的相对内存大小(相对于系统的全部物理内存), 还可以设为特殊值 "infinity" 表示不作限制。 此选项控制着cgroup的 "memory.max" 属性值,详见 cgroup-v2.txt 文档。

此选项隐含着 "MemoryAccounting=yes"

此选项是新式资源控制选项。 相当于旧式的 MemoryLimit= 选项。

MemoryLimit=bytes

绝对刚性的限制该单元中的进程最多可以使用多少内存。 这是一个不允许突破的刚性限制,触碰此限制会导致进程由于内存不足而被强制杀死。 选项值可以是以字节为单位的绝对内存大小(可以使用以1024为基数的 K, M, G, T 后缀), 也可以是以百分比表示的相对内存大小(相对于系统的全部物理内存), 还可以设为特殊值 "infinity" 表示不作限制。 此选项控制着cgroup的 "memory.limit_in_bytes" 属性值, 详见 memory.txt 文档。

此选项隐含着 "MemoryAccounting=yes"

此选项是旧式资源控制选项。 建议使用新式的 MemoryMax= 选项。

TasksAccounting=

若设为"yes"则表示为此单元开启 任务数量统计(内核空间线程数+用户空间进程数)。 注意,这同时也隐含的开启了该单元 所属的 slice 以及父 slice 内所有单元的任务数量统计。 此选项的默认值由 DefaultTasksAccounting= 决定 (参见 systemd-system.conf(5) 手册)。

TasksMax=N

为此单元设置总任务数量限制。 可以设为一个正整数绝对值,也可以设为一个相对于系统全局所允许的最大任务数量的百分比, 而特殊值 "infinity" 表示不作任何限制。 此选项控制着cgroup的 "pids.max" 属性值, 详见 pids.txt 文档。

此选项隐含着 "TasksAccounting=yes" 。 此选项的默认值由 DefaultTasksMax= 决定(参见 systemd-system.conf(5) 手册)。

IOAccounting=

若设为"yes"则表示为此单元开启块设备IO统计。 注意,这同时也隐含的开启了该单元所属的 slice 以及父 slice 内所有单元的块设备IO统计。 此选项的默认值由 DefaultIOAccounting= 决定(参见 systemd-system.conf(5) 手册)。

此选项是新式资源控制选项。 相当于旧式的 BlockIOAccounting= 选项。

IOWeight=weight, StartupIOWeight=weight

为此单元的进程设置默认的块设备IO带宽的分配权重。 这两个选项的默认值都是"100",取值范围都是 1-10000 之间的整数。 这两个选项控制着cgroup的 "io.weight" 属性值, 详见 cgroup-v2.txt 文档。 总的可用块设备IO带宽会在同一个 slice 内的每个单元之间,依据各单元的分配权重进行分配。

StartupIOWeight= 仅用于系统启动过程, 而 IOWeight= 则用于系统正常运行过程, 并且在前者未设置时亦可作用于系统启动过程。 通常使用 StartupIOWeight= 让特定的服务 在系统启动过程中拥有与运行时不一样的IO优先级。

这两个选项都隐含着 "IOAccounting=yes"

此选项是新式资源控制选项。 相当于旧式的 BlockIOWeight=StartupBlockIOWeight= 选项。

IODeviceWeight=device weight

为此单元的进程设置针对特定块设备的IO带宽的分配权重。选项的值由空格分隔的两部分组成(例如"/dev/sda 1000"): device 可以是以"/dev/"开头的块设备节点路径, 也可以是一个普通的文件路径(表示此文件所在文件系统的底层块设备)。 weight 是针对此块设备的IO带宽的分配权重, 是一个介于1-10000之间的整数,默认值为"100"。 此选项控制着cgroup的 "io.weight" 属性值, 详见 cgroup-v2.txt 文档。

此选项隐含着 "IOAccounting=yes"

此选项是新式资源控制选项。 相当于旧式的 BlockIODeviceWeight= 选项。

IOReadBandwidthMax=device bytes, IOWriteBandwidthMax=device bytes

为此单元的进程设置针对特定块设备的读/写速率刚性上限。 这是一种非工作保留模式(non-work-conserving)的限制, 也就是说即使设备当前处于空闲状态,该单元中的进程也不允许超限使用。 选项的值由空格分隔的两部分组成(例如"/dev/disk/by-path/pci-0000:00:1f.2-scsi-0:0:0:0 5M"): device 可以是以"/dev/"开头的块设备节点路径,也可以是一个普通的文件路径(表示此文件所在文件系统的底层块设备)。 bytes 是针对此块设备的读/写速率上限(单位是"字节/秒"), 其值是一个正整数,且可以使用以1000为基数的 K, M, G, T 后缀。 这两个选项控制着cgroup的 "io.max" 属性值, 详见 cgroup-v2.txt 文档。 可以分别针对多个不同的块设备多次使用这两个选项。

这两个选项都隐含着 "IOAccounting=yes"

这两个选项是新式资源控制选项。 相当于旧式的 BlockIOReadBandwidth=BlockIOWriteBandwidth= 选项。

IOReadIOPSMax=device IOPS, IOWriteIOPSMax=device IOPS

为此单元的进程设置针对特定块设备的读/写IOPS刚性上限。 这是一种非工作保留模式(non-work-conserving)的限制, 也就是说即使设备当前处于空闲状态,该单元中的进程也不允许超限使用。 选项的值由空格分隔的两部分组成(例如"/dev/disk/by-path/pci-0000:00:1f.2-scsi-0:0:0:0 1K"): device 可以是以"/dev/"开头的块设备节点路径,也可以是一个普通的文件路径(表示此文件所在文件系统的底层块设备)。 IOPS 是针对此块设备的读/写IOPS上限(单位是"次/秒"), 其值是一个正整数,且可以使用以1000为基数的 K, M, G, T 后缀。 这两个选项控制着cgroup的 "io.max" 属性值, 详见 cgroup-v2.txt 文档。 可以分别针对多个不同的块设备多次使用这两个选项。

这两个选项都隐含着 "IOAccounting=yes"

这两个选项是新式资源控制选项。

BlockIOAccounting=

若设为"yes"则表示为此单元开启块设备IO统计。 注意,这同时也隐含的开启了该单元 所属的 slice 以及父 slice 内所有单元的块设备IO统计。 此选项的默认值由 DefaultBlockIOAccounting= 决定(参见 systemd-system.conf(5) 手册)。

建议使用新式的 IOAccounting= 资源控制选项取代此选项。

BlockIOWeight=weight, StartupBlockIOWeight=weight

为此单元的进程设置默认的块设备IO带宽的分配权重。这两个选项的默认值都是500,取值范围都是 10-1000 之间的整数。 这两个选项控制着cgroup的 "blkio.weight" 属性值, 详见 blkio-controller.txt 文档。 总的可用块设备IO带宽会在同一 slice 内的每个单元之间,依据各单元的分配权重进行分配。

StartupBlockIOWeight= 仅用于系统启动过程, 而 BlockIOWeight= 则用于系统正常运行过程, 并且在前者未设置时亦可作用于系统启动过程。 通常使用 StartupBlockIOWeight= 让特定的服务在系统启动过程中拥有与运行时不一样的IO优先级。

这两个选项都隐含着 "BlockIOAccounting=yes"

建议使用新式的 IOWeight=StartupIOWeight= 资源控制选项取代此选项。

BlockIODeviceWeight=device weight

为此单元的进程设置针对特定块设备的IO带宽的分配权重。 选项的值由空格分隔的两部分组成(例如"/dev/sda 500"): device 可以是块设备节点路径(以"/dev/"开头),也可以是一个普通的文件路径(表示此文件所在文件系统的底层块设备)。 weight 是针对此块设备的IO带宽的分配权重,是一个介于10-1000之间的整数。 可以分别针对多个不同的块设备多次使用此选项。 此选项控制着cgroup的 "blkio.weight_device" 属性值(默认值为1000), 详见 blkio-controller.txt 文档。

此选项隐含着 "BlockIOAccounting=yes"

建议使用新式的 IODeviceWeight= 资源控制选项取代此选项。

BlockIOReadBandwidth=device bytes, BlockIOWriteBandwidth=device bytes

为此单元的进程设置针对特定块设备的读/写速率上限。 选项的值由空格分隔的两部分组成(例如"/dev/disk/by-path/pci-0000:00:1f.2-scsi-0:0:0:0 5M"): device 可以是块设备节点路径(以"/dev/"开头), 也可以是一个普通的文件路径(表示此文件所在文件系统的底层块设备)。 bytes 是针对此块设备的读/写速率上限(单位是"字节/秒"),其值是一个正整数, 且可以使用以1000为基数的 K, M, G, T 后缀。 可以分别针对多个不同的块设备多次使用这两个选项。 这两个选项控制着cgroup的 "blkio.throttle.read_bps_device" 与 "blkio.throttle.write_bps_device" 属性值, 详见 blkio-controller.txt 文档。

此选项隐含着 "BlockIOAccounting=yes"

建议使用新式的 IOReadBandwidthMax=IOWriteBandwidthMax= 资源控制选项取代此选项。

DeviceAllow=device mode

为此单元的进程设置设备访问权限白名单。 此选项控制着cgroup的 "devices.allow" 与 "devices.deny" 属性值, 详见 devices.txt 文档。 选项的值由空格分隔的两部分组成:

device 可以是以 /dev/ 开头的设备节点路径, 例如 /dev/sda5 表示第一块ATA或SCSI硬盘; 也可以是以 "char-" 或 "block-" 开头、 后跟设备组名称(/proc/devices)的字符串, 例如 "char-pts" 与 "char-alsa" 就分别涵盖了所有伪终端与所有ALSA声卡。 后一种表示法可以一次性作用于一组设备 (包括当前已有的与未来可能出现的)。 最后,还可以在后一种表示法的设备组名称中使用 "*" 与 "?" 通配符,例如 "char-cpu/*" 表示所有与CPU相关的设备组。

moder, w, m 三个字母的组合,分别表示: 读取此设备(read)、 写入此设备(write)、 创建此设备(mknod)

DevicePolicy=auto|closed|strict

为此单元的进程设置设备访问策略:

strict

仅允许在 DeviceAllow= 中明确允许的访问, 默认拒绝一切其他访问。

closed

在 strict 的基础上 额外允许对如下标准伪设备的访问: /dev/null, /dev/zero, /dev/full, /dev/random, /dev/urandom

auto

这是默认值。 对于已在 DeviceAllow= 中列出的设备,仅允许在 DeviceAllow= 中明确允许的访问; 对于未在 DeviceAllow= 中列出的设备,默认允许一切形式的访问(相当于拥有"rwm"权限)。

Slice=

将此单元放到哪个 slice 单元中。 对于非 slice 单元来说, 非实例化单元的默认值是 system.slice , 实例化单元的默认值是 system.slice 之下 与模版单元同名的 slice 单元。

利用此选项, 可将各单元按照 slice 单元的层次结构组织起来, 以便分层次、分组的对单元进行资源分配。

对于 slice 单元来说, 因为此选项仅允许设为父 slice 单元, 所以此选项没有实际的意义, 也不需要设置此选项。

当依赖于默认 slice 分配规则时, 需要特别小心那些明确设置了 DefaultDependencies=no 的实例化服务单元。详见 systemd.service(5) 手册的"自动依赖"小节。

Delegate=

设为"yes"表示允许此单元对其拥有的资源, 在该单元内部进行更进一步的划分与分配。 对于非特权服务(也就是使用了 User= 设置), 这表示允许进程在其自身所处的cgroup路径之下创建自己的子层次结构。 对于 scope 与特权服务, 这表示允许进程使用所有的 cgroup controller

参见

systemd(1), systemd.unit(5), systemd.service(5), systemd.slice(5), systemd.scope(5), systemd.socket(5), systemd.mount(5), systemd.swap(5), systemd.directives(7), systemd.special(7), 有关控制组(control groups)与各种控制器的文档: cgroups.txt, cpuacct.txt, memory.txt, blkio-controller.txt.