Red Hat Training

A Red Hat training course is available for RHEL 8

44.3.2. cgroups-v2 を使用したアプリケーションへの CPU 制限の設定

アプリケーションでは CPU 時間が多く使用されることがあり、環境全体の健全性に影響を与える可能性があります。コントロールグループのバージョン 2 (cgroups-v2) を使用してアプリケーションへの CPU 制限を設定し、その消費量を制限します。

前提条件

手順

  1. システム起動時に cgroups-v1 が自動的にマウントされないようにします。

    # grubby --update-kernel=/boot/vmlinuz-$(uname -r) --args="cgroup_no_v1=all"

    コマンドは、カーネルコマンドラインパラメーターを現在のブートエントリーに追加します。cgroup_no_v1=all パラメーターは、cgroups-v1 が自動的にマウントされないようにします。

    または、systemd.unified_cgroup_hierarchy=1 カーネルコマンドラインパラメーターを使用して、システム起動時にデフォルトで cgroups-v2 をマウントします。

    注記

    RHEL 8 は、cgroups-v1cgroups-v2 の両方に対応します。ただし、cgroups-v1 は、ブートプロセス時にデフォルトで有効になっており、マウントされます。

  2. システムを再起動して、変更を有効にします。
  3. 必要に応じて、cgroups-v1 機能が無効になっていることを確認します。

    # mount -l | grep cgroup
    tmpfs on /sys/fs/cgroup type tmpfs (ro,nosuid,nodev,noexec,seclabel,mode=755)
    cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,xattr,release_agent=/usr/lib/systemd/systemd-cgroups-agent,name=systemd)

    cgroups-v1 が正常に無効化された場合は、出力に systemd に属するものを除き、「type cgroup」の参照は表示されません。

  4. cgroups-v2 をファイルシステムの任意の場所にマウントします。

    # mount -t cgroup2 none <MOUNT_POINT>
  5. 必要に応じて、cgroups-v2 機能がマウントされていることを確認します。

    # mount -l | grep cgroup2
    none on /cgroups-v2 type cgroup2 (rw,relatime,seclabel)

    この出力例は、cgroups-v2/cgroups-v2/ ディレクトリーにマウントされていることを示しています。

  6. 必要に応じて、/cgroups-v2/ ディレクトリーの内容を確認します。

    # ll /cgroups-v2/
    -r—​r—​r--. 1 root root 0 Mar 13 11:57 cgroup.controllers
    -rw-r—​r--. 1 root root 0 Mar 13 11:57 cgroup.max.depth
    -rw-r—​r--. 1 root root 0 Mar 13 11:57 cgroup.max.descendants
    -rw-r—​r--. 1 root root 0 Mar 13 11:57 cgroup.procs
    -r—​r—​r--. 1 root root 0 Mar 13 11:57 cgroup.stat
    -rw-r—​r--. 1 root root 0 Mar 13 11:58 cgroup.subtree_control
    -rw-r—​r--. 1 root root 0 Mar 13 11:57 cgroup.threads
    -rw-r—​r--. 1 root root 0 Mar 13 11:57 cpu.pressure
    -r—​r—​r--. 1 root root 0 Mar 13 11:57 cpuset.cpus.effective
    -r—​r—​r--. 1 root root 0 Mar 13 11:57 cpuset.mems.effective
    -rw-r—​r--. 1 root root 0 Mar 13 11:57 io.pressure
    -rw-r—​r--. 1 root root 0 Mar 13 11:57 memory.pressure

    /cgroups-v2/ ディレクトリーには、root コントロールグループとも呼ばれるインターフェースファイル (cgroup で始まる) と、cpuset.cpus.effective などのコントローラー固有のファイルが含まれます。

  7. CPU 消費で制限する必要のあるアプリケーションのプロセス ID (PID) を特定します。

    # top
    top - 15:39:52 up  3:45,  1 user,  load average: 0.79, 0.20, 0.07
    Tasks: 265 total,   3 running, 262 sleeping,   0 stopped,   0 zombie
    %Cpu(s): 74.3 us,  6.1 sy,  0.0 ni, 19.4 id,  0.0 wa,  0.2 hi,  0.0 si,  0.0 st
    MiB Mem :   1826.8 total,    243.8 free,   1102.1 used,    480.9 buff/cache
    MiB Swap:   1536.0 total,   1526.2 free,      9.8 used.    565.6 avail Mem
    
      PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
     5473 root      20   0  228440   1740   1456 R  99.7   0.1   0:12.11 sha1sum
     5439 root      20   0  222616   3420   3052 R  60.5   0.2   0:27.08 cpu_load_generator
     2170 jdoe      20   0 3600716 209960  67548 S   0.3  11.2   1:18.50 gnome-shell
     3051 root      20   0  274424   3976   3092 R   0.3   0.2   1:01.25 top
        1 root      20   0  245448  10256   5448 S   0.0   0.5   0:02.52 systemd
    ...

    top プログラムの出力例は、PID 5473 および 5439 (具体例のアプリケーション sha1sum および cpu_load_generator) が CPU などの多くのリソースを消費することを示しています。いずれも cgroups-v2 機能の管理に使用するアプリケーションの例です。

  8. CPU 関連のコントローラーを有効にします。

    # echo "+cpu" > /cgroups-v2/cgroup.subtree_control
    # echo "+cpuset" > /cgroups-v2/cgroup.subtree_control

    上記のコマンドは、root コントロールグループ /cgroups-v2/ の即時サブコントロールグループに cpu および cpuset コントローラーを有効にします。

  9. 以前に作成した /cgroups-v2/ ディレクトリーにサブディレクトリーを作成します。

    # mkdir /cgroups-v2/Example/

    /cgroups-v2/Example/ ディレクトリーはサブコントロールグループを表します。このグループでは、特定のプロセスを配置でき、各種の CPU 制限をプロセスに適用できます。また、前の手順では、このサブ制御グループの cpu コントローラーおよび cpuset コントローラーを有効にしました。

    /cgroups-v2/Example/ の作成時に、cgroups-v2 インターフェースファイルと cpu および cpuset のコントローラー固有のファイルがディレクトリーに作成されます。

  10. 必要に応じて、新しく作成されたコントロールグループを確認します。

    # ll /cgroups-v2/Example/
    -r—​r—​r--. 1 root root 0 Mar 13 14:48 cgroup.controllers
    -r—​r—​r--. 1 root root 0 Mar 13 14:48 cgroup.events
    -rw-r—​r--. 1 root root 0 Mar 13 14:48 cgroup.freeze
    -rw-r—​r--. 1 root root 0 Mar 13 14:48 cgroup.max.depth
    -rw-r—​r--. 1 root root 0 Mar 13 14:48 cgroup.max.descendants
    -rw-r—​r--. 1 root root 0 Mar 13 14:48 cgroup.procs
    -r—​r—​r--. 1 root root 0 Mar 13 14:48 cgroup.stat
    -rw-r—​r--. 1 root root 0 Mar 13 14:48 cgroup.subtree_control
    -rw-r—​r--. 1 root root 0 Mar 13 14:48 cgroup.threads
    -rw-r—​r--. 1 root root 0 Mar 13 14:48 cgroup.type
    -rw-r—​r--. 1 root root 0 Mar 13 14:48 cpu.max
    -rw-r—​r--. 1 root root 0 Mar 13 14:48 cpu.pressure
    -rw-r—​r--. 1 root root 0 Mar 13 14:48 cpuset.cpus
    -r—​r—​r--. 1 root root 0 Mar 13 14:48 cpuset.cpus.effective
    -rw-r—​r--. 1 root root 0 Mar 13 14:48 cpuset.cpus.partition
    -rw-r—​r--. 1 root root 0 Mar 13 14:48 cpuset.mems
    -r—​r—​r--. 1 root root 0 Mar 13 14:48 cpuset.mems.effective
    -r—​r—​r--. 1 root root 0 Mar 13 14:48 cpu.stat
    -rw-r—​r--. 1 root root 0 Mar 13 14:48 cpu.weight
    -rw-r—​r--. 1 root root 0 Mar 13 14:48 cpu.weight.nice
    -rw-r—​r--. 1 root root 0 Mar 13 14:48 io.pressure
    -rw-r—​r--. 1 root root 0 Mar 13 14:48 memory.pressure

    出力例には、cpuset.cpuscpu.max などのファイルが表示されます。これらのファイルは、/cgroups-v2/cgroup.subtree_control ファイルを使用してルート (/cgroups-v2/) のダイレクト子コントロールグループに対して有効にした cpuset および cpu コントローラー固有のものです。また、cgroup.procs または cgroup.controllers などの一般的な cgroup コントロールインターフェースファイルがありますが、これは有効なコントローラーに関係なく、すべてのコントロールグループに共通します。

    デフォルトでは、新しく作成されたサブコントロールグループは、システムの CPU リソース全体へのアクセスを制限なしで継承します。

  11. 制限を指定するプロセスが、同じ CPU 上の CPU 時間を取り合っていることを確認します。

    # echo "1" > /cgroups-v2/Example/cpuset.cpus

    上記のコマンドは、同じ CPU 上で競合する Example サブコントロールグループに置かれたプロセスを保護します。この設定は、cpu コントローラーをアクティベートするのに重要です。

    重要

    cpu コントローラーは、該当のサブコントロールグループに、1 つの CPU 上に CPU 時間を取得するプロセスが 2 つ以上ある場合にのみ、有効になります。

  12. コントロールグループの CPU 制限を設定します。

    # echo "200000 1000000" > /cgroups-v2/Example/cpu.max

    最初の値は、一定の期間 (2 番目の値で指定) でサブコントロールグループにある全プロセスをまとめて実行できる時間クォータ (マイクロ秒単位) です。一期間中にコントロールグループ内のプロセスがこのクォータで指定した時間をすべて使い切ってしまうと、残りの時間がスロットルされて、次の期間まで実行できえなくなります。

    コマンド例は、Example サブコントロールグループのすべてのプロセスが 1 秒あたり 0.2 秒のみ CPU で実行可能になるように CPU 時間制限を設定します。

  13. 必要に応じて、制限を確認します。

    # cat /cgroups-v2/Example/cpu.max
    200000 1000000
  14. アプリケーションの PID を Example サブコントロールグループに追加します。

    # echo "5473" > /cgroups-v2/Example/cgroup.procs
    # echo "5439" > /cgroups-v2/Example/cgroup.procs

    上記のコマンド例は、アプリケーションが Example サブコントロールグループのメンバーであることを確認するため、Example サブコントロールグループに設定された CPU 制限を超えないようにします。

  15. アプリケーションが指定のコントロールグループで実行されていることを確認します。

    # cat /proc/5473/cgroup /proc/5439/cgroup
    1:name=systemd:/user.slice/user-1000.slice/user@1000.service/gnome-terminal-server.service
    0::/Example
    1:name=systemd:/user.slice/user-1000.slice/user@1000.service/gnome-terminal-server.service
    0::/Example

    上記の出力例は、必要なアプリケーションのプロセスが Example サブコントロールグループで実行されることを示しています。

  16. スロットルしたアプリケーションの現在の CPU 使用率を確認します。

    # top
    top - 15:56:27 up  4:02,  1 user,  load average: 0.03, 0.41, 0.55
    Tasks: 265 total,   4 running, 261 sleeping,   0 stopped,   0 zombie
    %Cpu(s):  9.6 us,  0.8 sy,  0.0 ni, 89.4 id,  0.0 wa,  0.2 hi,  0.0 si,  0.0 st
    MiB Mem :   1826.8 total,    243.4 free,   1102.1 used,    481.3 buff/cache
    MiB Swap:   1536.0 total,   1526.2 free,      9.8 used.    565.5 avail Mem
    
      PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
     5439 root      20   0  222616   3420   3052 R  10.0   0.2   6:15.83 cpu_load_generator
     5473 root      20   0  228440   1740   1456 R  10.0   0.1   9:20.65 sha1sum
     2753 jdoe      20   0  743928  35328  20608 S   0.7   1.9   0:20.36 gnome-terminal-
     2170 jdoe      20   0 3599688 208820  67552 S   0.3  11.2   1:33.06 gnome-shell
     5934 root      20   0  274428   5064   4176 R   0.3   0.3   0:00.04 top
     ...

    PID 5439 および PID 5473 の CPU 使用率が 10% に減少していることに注意してください。Example サブコントロールグループは、このグループのプロセスをまとめて CPU 時間の 20% に制限します。コントロールグループにプロセスが 2 つあるため、各プロセスは CPU 時間の 10% を使用できます。

関連情報