24.2. CPU 時間配分のための cgroup の準備
アプリケーションの CPU 消費を制御するには、特定の CPU コントローラーを有効にして専用のコントロールグループを作成する必要があります。cgroup ファイルの組織的な明確さを維持するために、/sys/fs/cgroup/ root コントロールグループ内に少なくとも 2 つのレベルの子コントロールグループを作成することが推奨されます。
前提条件
- root 権限がある。
- 制御するプロセスの PID を把握している。
-
cgroups-v2ファイルシステムをマウントしている。詳細は、cgroups-v2 のマウント を参照してください。
手順
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 34578および34579(sha1sumの 2 つの例示的なアプリケーション) が大量のリソース、つまり CPU を消費していることを示しています。いずれもcgroups-v2機能の管理を示すために使用されるサンプルアプリケーションです。cpuおよびcpusetコントローラーが/sys/fs/cgroup/cgroup.controllersファイルで利用可能であることを確認します。# cat /sys/fs/cgroup/cgroup.controllers cpuset cpu io memory hugetlb pids rdmaCPU 関連のコントローラーを有効にします。
# echo "+cpu" >> /sys/fs/cgroup/cgroup.subtree_control # echo "+cpuset" >> /sys/fs/cgroup/cgroup.subtree_controlこれらのコマンドにより、
/sys/fs/cgroup/ルートコントロールグループ直下のサブグループに対してcpuおよびcpusetコントローラーが有効になります。サブグループ で指定した各プロセスに対して、基準に基づいてコントロールチェックを適用できます。任意のレベルで
cgroup.subtree_controlファイルを確認して、直下の子グループで有効にできるコントローラーを識別できます。注記デフォルトでは、ルートコントロールグループの
/sys/fs/cgroup/cgroup.subtree_controlファイルにはmemoryとpidsコントローラーが含まれます。/sys/fs/cgroup/Example/ディレクトリーを作成します。# mkdir /sys/fs/cgroup/Example//sys/fs/cgroup/Example/ディレクトリーはサブグループを定義します。また、前の手順では、このサブグループのcpuコントローラーおよびcpusetコントローラーを有効にしました。/sys/fs/cgroup/Example/ディレクトリーを作成すると、cgroups-v2インターフェイスファイルとcpuおよびcpusetのコントローラー固有のファイルがディレクトリーに自動的に作成されます。/sys/fs/cgroup/Example/ディレクトリーは、memoryおよびpidsコントローラー用のコントローラー固有のファイルも提供します。オプション: 新しく作成された子コントロールグループを確認します。
# 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.cpusやcpu.maxなどのファイルが表示されます。これらのファイルは、cpusetコントローラーおよびcpuコントローラーに固有のものです。cpusetおよびcpuコントローラーは、/sys/fs/cgroup/cgroup.subtree_controlファイルを使用して、ルート (/sys/fs/cgroup/) の直下のサブコントローラーグループに対して手動で有効にされます。ディレクトリーには
cgroup.procsまたはcgroup.controllersなどの一般的なcgroupコントロールインターフェイスファイルがありますが、これは有効なコントローラーに関係なく、すべてのコントロールグループに共通のものです。memory.highおよびpids.maxなどのファイルは、memoryおよびpidsコントローラーに関連し、ルートコントロールグループ (/sys/fs/cgroup/) にあり、常にデフォルトで有効になります。デフォルトでは、新しく作成されたサブグループは、制限なしで、システムのすべての CPU およびメモリーリソースへのアクセスを継承します。
/sys/fs/cgroup/Example/の CPU 関連のコントローラーを有効にし、CPU にのみ関連するコントローラーを取得します。# echo "+cpu" >> /sys/fs/cgroup/Example/cgroup.subtree_control # echo "+cpuset" >> /sys/fs/cgroup/Example/cgroup.subtree_controlこれらのコマンドにより、直下のサブコントロールグループに、(
memoryまたはpidsコントローラーではなく) CPU 時間の配分の調整に関係するコントローラー だけが設定されるようになります。/sys/fs/cgroup/Example/tasks/ディレクトリーを作成します。# mkdir /sys/fs/cgroup/Example/tasks//sys/fs/cgroup/Example/tasks/ディレクトリーは、cpuおよびcpusetコントローラーにのみ関連するファイルを持つサブグループを定義します。オプション: 別の子コントロールグループを検査します。
# 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.pressureCPU 時間を制御するプロセスが同じ CPU で競合していることを確認します。
# echo "1" > /sys/fs/cgroup/Example/tasks/cpuset.cpusこれにより、
Example/tasks子コントロールグループに配置するプロセスが、同じ CPU 上で競合するようになります。この設定は、cpuコントローラーをアクティベートするのに重要です。重要cpuコントローラーは、関連する子コントロールグループに、単一の CPU 上で時間を競合するプロセスが少なくとも 2 つある場合にのみアクティブになります。
検証
オプション: 直下の子 cgroups に対して CPU 関連コントローラーが有効になっていることを確認します。
# cat /sys/fs/cgroup/cgroup.subtree_control /sys/fs/cgroup/Example/cgroup.subtree_control cpuset cpu memory pids cpuset cpuオプション:CPU 時間を制御するプロセスが同じ CPU で競合していることを確認します。
# cat /sys/fs/cgroup/Example/tasks/cpuset.cpus 1