Red Hat Training

A Red Hat training course is available for RHEL 8

24.2. 为 CPU 时间分布准备 cgroup

要控制应用程序的 CPU 消耗,您需要启用特定的 CPU 控制器,并创建一个专用的控制组。建议您在 /sys/fs/cgroup/ 根控制组群中至少创建两级子控制组,以更好地保持cgroup 文件的组织清晰性。

先决条件

  • 您有 root 权限。
  • 您已确定了要控制的进程的 PID。
  • 您已挂载了 cgroups-v2 文件系统。如需更多信息,请参阅 挂载 cgroups-v2

流程

  1. 识别您要限制其 CPU 消耗的应用程序的进程 ID(PID):

    # top
    Tasks: 104 total,   3 running, 101 sleeping,   0 stopped,   0 zombie
    %Cpu(s): 17.6 us, 81.6 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.8 hi,  0.0 si,  0.0 st
    MiB Mem :   3737.4 total,   3312.7 free,    133.3 used,    291.4 buff/cache
    MiB Swap:   4060.0 total,   4060.0 free,      0.0 used.   3376.1 avail Mem
    
        PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
      34578 root      20   0   18720   1756   1468 R  99.0   0.0   0:31.09 sha1sum
      34579 root      20   0   18720   1772   1480 R  99.0   0.0   0:30.54 sha1sum
          1 root      20   0  186192  13940   9500 S   0.0   0.4   0:01.60 systemd
          2 root      20   0       0      0      0 S   0.0   0.0   0:00.01 kthreadd
          3 root       0 -20       0      0      0 I   0.0   0.0   0:00.00 rcu_gp
          4 root       0 -20       0      0      0 I   0.0   0.0   0:00.00 rcu_par_gp
    ...

    示例输出显示 PID 3457834579sha1sum的两个说明性应用程序)消耗了大量资源,即 CPU。这两个应用程序都是用于演示 cgroups-v2 功能的应用示例。

  2. 验证 /sys/fs/cgroup/cgroup.controllers 文件中是否提供了 cpucpuset 控制器:

    # cat /sys/fs/cgroup/cgroup.controllers
    cpuset cpu io memory hugetlb pids rdma
  3. 启用与 CPU 相关的控制器:

    # echo "+cpu" >> /sys/fs/cgroup/cgroup.subtree_control
    # echo "+cpuset" >> /sys/fs/cgroup/cgroup.subtree_control

    这些命令为 /sys/fs/cgroup/ 根控制组的直接子组启用了 cpucpuset 控制器。子组 是您可以指定进程,并根据您的标准对每个进程应用控制检查的地方。

    用户可以在任意级别读取 cgroup.subtree_control 文件的内容,以了解即时子组中哪些控制器可用于启用。

    注意

    默认情况下,根控制组中的 /sys/fs/cgroup/cgroup.subtree_control 文件包含 memorypids 控制器。

  4. 创建 /sys/fs/cgroup/Example/ 目录:

    # mkdir /sys/fs/cgroup/Example/

    /sys/fs/cgroup/Example/ 目录定义了一个子组。此外,上一步为这个子组启用了 cpucpuset 控制器。

    创建 /sys/fs/cgroup/Example/ 目录时,一些 cgroups-v2 接口文件以及 cpucpuset 特定于控制器的文件也会在目录中自动创建。/sys/fs/cgroup/Example/ 目录还包含 memorypids 控制器的特定于控制器的文件。

  5. 可选,检查新创建的子控制组:

    # ll /sys/fs/cgroup/Example/
    -r—​r—​r--. 1 root root 0 Jun  1 10:33 cgroup.controllers
    -r—​r—​r--. 1 root root 0 Jun  1 10:33 cgroup.events
    -rw-r—​r--. 1 root root 0 Jun  1 10:33 cgroup.freeze
    -rw-r—​r--. 1 root root 0 Jun  1 10:33 cgroup.max.depth
    -rw-r—​r--. 1 root root 0 Jun  1 10:33 cgroup.max.descendants
    -rw-r—​r--. 1 root root 0 Jun  1 10:33 cgroup.procs
    -r—​r—​r--. 1 root root 0 Jun  1 10:33 cgroup.stat
    -rw-r—​r--. 1 root root 0 Jun  1 10:33 cgroup.subtree_control
    …​
    -rw-r—​r--. 1 root root 0 Jun  1 10:33 cpuset.cpus
    -r—​r—​r--. 1 root root 0 Jun  1 10:33 cpuset.cpus.effective
    -rw-r—​r--. 1 root root 0 Jun  1 10:33 cpuset.cpus.partition
    -rw-r—​r--. 1 root root 0 Jun  1 10:33 cpuset.mems
    -r—​r—​r--. 1 root root 0 Jun  1 10:33 cpuset.mems.effective
    -r—​r—​r--. 1 root root 0 Jun  1 10:33 cpu.stat
    -rw-r—​r--. 1 root root 0 Jun  1 10:33 cpu.weight
    -rw-r—​r--. 1 root root 0 Jun  1 10:33 cpu.weight.nice
    …​
    -r—​r—​r--. 1 root root 0 Jun  1 10:33 memory.events.local
    -rw-r—​r--. 1 root root 0 Jun  1 10:33 memory.high
    -rw-r—​r--. 1 root root 0 Jun  1 10:33 memory.low
    …​
    -r—​r—​r--. 1 root root 0 Jun  1 10:33 pids.current
    -r—​r—​r--. 1 root root 0 Jun  1 10:33 pids.events
    -rw-r—​r--. 1 root root 0 Jun  1 10:33 pids.max

    示例输出显示 cpuset.cpuscpu.max 等文件。这些文件特定于 cpusetcpu 控制器。使用 /sys/fs/cgroup/cgroup.subtree_control 文件,为根的(/sys/fs/cgroup/)直接子控制组 手动启用 cpusetcpu 控制器。

    目录还包含通用 cgroup 控制接口文件,如 cgroup.procscgroup.controllers,它们对所有控制组都通用,无论启用的控制器是什么。

    memory.highpids.max 等文件与 memorypids 控制器有关,它们位于根控制组中(/sys/fs/cgroup/),默认情况下总是启用的。

    默认情况下,新创建的子组继承了对系统所有 CPU 和内存资源的访问权限,没有任何限制。

  6. 启用 /sys/fs/cgroup/Example/ 中与 CPU 相关的控制器,以获取仅与 CPU 相关的控制器:

    # echo "+cpu" >> /sys/fs/cgroup/Example/cgroup.subtree_control
    # echo "+cpuset" >> /sys/fs/cgroup/Example/cgroup.subtree_control

    这些命令确保直接子控制组将 只能 有与控制 CPU 时间相关的控制器,而不是 memorypids 控制器。

  7. 创建 /sys/fs/cgroup/Example/tasks/ 目录:

    # mkdir /sys/fs/cgroup/Example/tasks/

    /sys/fs/cgroup/Example/tasks/ 目录定义了一个子组,以及只与 cpucpuset 控制器相关的文件。

  8. 另外,还可检查其他子控制组:

    # ll /sys/fs/cgroup/Example/tasks
    -r—​r—​r--. 1 root root 0 Jun  1 11:45 cgroup.controllers
    -r—​r—​r--. 1 root root 0 Jun  1 11:45 cgroup.events
    -rw-r—​r--. 1 root root 0 Jun  1 11:45 cgroup.freeze
    -rw-r—​r--. 1 root root 0 Jun  1 11:45 cgroup.max.depth
    -rw-r—​r--. 1 root root 0 Jun  1 11:45 cgroup.max.descendants
    -rw-r—​r--. 1 root root 0 Jun  1 11:45 cgroup.procs
    -r—​r—​r--. 1 root root 0 Jun  1 11:45 cgroup.stat
    -rw-r—​r--. 1 root root 0 Jun  1 11:45 cgroup.subtree_control
    -rw-r—​r--. 1 root root 0 Jun  1 11:45 cgroup.threads
    -rw-r—​r--. 1 root root 0 Jun  1 11:45 cgroup.type
    -rw-r—​r--. 1 root root 0 Jun  1 11:45 cpu.max
    -rw-r—​r--. 1 root root 0 Jun  1 11:45 cpu.pressure
    -rw-r—​r--. 1 root root 0 Jun  1 11:45 cpuset.cpus
    -r—​r—​r--. 1 root root 0 Jun  1 11:45 cpuset.cpus.effective
    -rw-r—​r--. 1 root root 0 Jun  1 11:45 cpuset.cpus.partition
    -rw-r—​r--. 1 root root 0 Jun  1 11:45 cpuset.mems
    -r—​r—​r--. 1 root root 0 Jun  1 11:45 cpuset.mems.effective
    -r—​r—​r--. 1 root root 0 Jun  1 11:45 cpu.stat
    -rw-r—​r--. 1 root root 0 Jun  1 11:45 cpu.weight
    -rw-r—​r--. 1 root root 0 Jun  1 11:45 cpu.weight.nice
    -rw-r—​r--. 1 root root 0 Jun  1 11:45 io.pressure
    -rw-r—​r--. 1 root root 0 Jun  1 11:45 memory.pressure
  9. 确保您要控制 CPU 时间的进程在同一 CPU 上竞争:

    # echo "1" > /sys/fs/cgroup/Example/tasks/cpuset.cpus

    以上命令可确保您将放在 Example/tasks 子控制组中的进程在同一 CPU 上竞争。此设置对于要激活的 cpu 控制器非常重要。

    重要

    cpu 控制器只有在相关子控制组至少有 2 个在单个 CPU 上竞争时间的进程时,才会被激活 。

验证步骤

  1. 可选:确保为直接子 cgroups 启用了与 CPU 相关的控制器:

    # cat /sys/fs/cgroup/cgroup.subtree_control /sys/fs/cgroup/Example/cgroup.subtree_control
    cpuset cpu memory pids
    cpuset cpu
  2. 可选:确保您要控制 CPU 时间的进程在同一 CPU 上竞争:

    # cat /sys/fs/cgroup/Example/tasks/cpuset.cpus
    1

其它资源