Red Hat Training

A Red Hat training course is available for RHEL 8

24.2. CPU 時間配分のための cgroup の準備

アプリケーションの CPU 消費を制御するには、特定の CPU コントローラーを有効にして専用のコントロールグループを作成する必要があります。cgroup ファイルの組織的な明確さを維持するために、/sys/fs/cgroup/ ルートコントロールグループ内に少なくとも 2 つのレベルのサブコントロールグループを作成することが推奨されます。

前提条件

  • 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 34578 および 34579(sha1sum の 2 つのアプリケーションとして識別) が多くのリソース (具体的には CPU) を消費していることを示しています。いずれも cgroups-v2 機能の管理に使用するアプリケーションの例です。

  2. cpu および cpuset コントローラーが /sys/fs/cgroup/cgroup.controllers ファイルで利用可能であることを確認します。

    # 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/ ルートコントロールグループ直下のサブグループに対して cpu および cpuset コントローラーが有効になります。サブグループ で指定した各プロセスに対して、基準に基づいてコントロールチェックを適用できます。

    ユーザーは任意のレベルの cgroup.subtree_control ファイルの内容を読み取り、直下のサブグループで有効にするコントローラーについて把握することができます。

    注記

    デフォルトでは、ルートコントロールグループの /sys/fs/cgroup/cgroup.subtree_control ファイルには memorypids コントローラーが含まれます。

  4. /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 コントローラー用のコントローラー固有のファイルも含まれます。

  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 などのファイルが表示されます。これらのファイルは、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 およびメモリーリソースへのアクセスを継承します。

  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

    これらのコマンドにより、直下のサブコントロールグループに、(memory または pids コントローラーではなく) CPU 時間の配分の調整に関係するコントローラー だけが設定されるようになります。

  7. /sys/fs/cgroup/Example/tasks/ ディレクトリーを作成します。

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

    /sys/fs/cgroup/Example/tasks/ ディレクトリーは、cpu および cpuset コントローラーにのみ関連するファイルを持つサブグループを定義します。

  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 コントローラーは、該当のサブコントロールグループに、同じ CPU の CPU 時間を取り合うプロセスが 2 つ以上ある場合にのみ、有効になります。

検証手順

  1. 必要に応じて、CPU 関連のコントローラーが直下のサブ cgroups に対して有効になっていることを確認します。

    # 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