7 リソースの管理
この章では、Oracle Linuxシステムでリソースの使用を管理する方法について説明します。
制御グループについて
Oracle Linuxの制御グループ(cgroups
)機能を使用すると、CPUやメモリーなどの独自のシステム・リソースのグループを、選択した使用設定で作成できます。cgroups
を作成すると、プロセスおよびシステム要件に従って各cgroupにプロセスを割り当てることができます。たとえば、CPU時間を150:100:50の比率で割り当てる必要がある3セットのプロセスを特定した場合は、3つのcgroups
を作成し、それぞれに比率の3つの値のいずれかに対応するCPUの重みを割り当て、各cgroup
に適切なプロセスを割り当てることができます。
制御グループは、複数の仮想マシン、Kubernetesクラスタなどをホストし、そのアプリケーションがリソースの使用について競合するシステム構成では重要です。
cgroup
機能は/sys/fs/cgroup
に仮想ファイル・システムとしてマウントされています。/sys/fs/cgroup
ファイル・システムは、より効率的なシステム・パフォーマンスを得るために、サブディレクトリおよびファイルを作成して、リソース割当てを細かいレベルで制御できる階層構造を提供します。
Oracle Linuxには、次の2つのタイプの制御グループがあります:
- 制御グループ・バージョン1 (
cgroups v1
) -
これらのグループは、リソースごとのコントローラ階層を提供します。CPU、メモリー、I/Oなどの各リソースには、独自の制御グループ階層があります。このグループの短所は、異なるプロセス階層に属する可能性のあるグループ間でリソース使用を適切に調整することが困難なことです。
- 制御グループ・バージョン2 (
cgroups v2
) -
これらのグループは、すべてのリソース・コントローラがマウントされる単一の制御グループ階層を提供します。この階層では、異なるリソース・コントローラ間でのリソース使用をより適切に調整できます。このバージョンは、柔軟性が高すぎてシステム利用者間のリソース利用の適切な調整を妨げていた
cgroups v1
の改良版です。
どちらのバージョンもOracle Linuxに存在します。ただし、デフォルトでは、cgroups v2
機能が有効になっており、Oracle Linux 9システムにマウントされています。
両方のバージョンの制御グループの詳細は、cgroups(7)
およびsysfs(5)
のマニュアル・ページを参照してください。
カーネル・リソース・コントローラについて
制御グループは、カーネル・リソース・コントローラを介してリソースの使用を管理します。カーネル・リソース・コントローラは、CPU時間、メモリー、ネットワーク帯域幅、ディスクI/Oなどの単一のリソースを表します。
システムにマウントされているリソース・コントローラを識別するには、/procs/cgroups
ファイルの内容を確認します。次に例を示します:
less /proc/cgroups
#subsys_name hierarchy num_cgroups enabled
cpuset 0 103 1
cpu 0 103 1
cpuacct 0 103 1
blkio 0 103 1
memory 0 103 1
devices 0 103 1
freezer 0 103 1
net_cls 0 103 1
perf_event 0 103 1
net_prio 0 103 1
hugetlb 0 103 1
pids 0 103 1
rdma 0 103 1
misc 0 103 1
cgroups v1
とcgroups v2
の両方のカーネル・リソース・コントローラの詳細な説明は、cgroups(7)
マニュアル・ページを参照してください。
制御グループ・ファイル・システムについて
この項では、cgroup
機能が/sys/fs/cgroup
で階層ファイル・システムとしてどのようにマウントされているかを説明します。
ディレクトリ/sys/fs/cgroup
は、ルート制御グループとも呼ばれます。ルート制御グループ・ディレクトリの内容は、システムにマウントされているcgroup
のバージョンによって異なります。cgroups v2
の場合、ディレクトリの内容は次のとおりです。
ls /sys/fs/cgroup
cgroup.controllers cpuset.mems.effective memory.stat
cgroup.max.depth cpu.stat misc.capacity
cgroup.max.descendants dev-hugepages.mount sys-fs-fuse-connections.mount
cgroup.procs dev-mqueue.mount sys-kernel-config.mount
cgroup.stat init.scope sys-kernel-debug.mount
cgroup.subtree_control io.pressure sys-kernel-tracing.mount
cgroup.threads io.stat system.slice
cpu.pressure memory.numa_stat user.slice
cpuset.cpus.effective memory.pressure
mkdir
コマンドを使用して、ルート制御グループの下に独自のcgroup
サブディレクトリを作成できます。たとえば、次のcgroup
サブディレクトリを作成します。
-
/sys/fs/cgroup/MyGroups/
-
/sys/fs/cgroup/MyGroups/cgroup1
-
/sys/fs/cgroup/MyGroups/cgroup2
ノート:
ベスト・プラクティスは、/sys/fs/cgroup
内に少なくとも2つのレベルの子cgroups
を作成することです。前述のリストの例では、最初の子グループMyGroups
を、システムに必要な様々なcgroups
を含む親として使用することで、このプラクティスに従っています。
階層内の各cgroup
には、次のファイルが含まれます。
-
cgroup.controllers
-
この読取り専用ファイルには、現在の
cgroup
で使用可能なコントローラがリストされます。このファイルの内容は、親のcgroup
内のcgroup.subtree_control
ファイルの内容と一致します。 -
cgroup.subtree_control
-
このファイルには、現在の
cgroup
の直下の子cgroups
に対して有効になっているcgroup.controllers
ファイル内のコントローラが含まれています。コントローラ(
pids
など)がcgroup.subtree_control
ファイルに存在する場合、対応するコントローラ・インタフェース・ファイル(pids.max
など)は、現在のcgroup
の直下の子に自動的に作成されます。
アプリケーションのリソース管理を実装できる子グループを作成する手順の例は、CPUの重みの設定によるCPU時間配分の制御を参照してください。
cgroup
を削除するには、cgroup
に他の子グループが含まれていないことを確認してから、ディレクトリを削除します。たとえば、子グループ/sys/fs/cgroup/MyGroups/cgroup1
を削除するには、次のコマンドを実行します。
sudo rmdir /sys/fs/cgroup/MyGroups/cgroup1
制御グループおよびsystemdについて
制御グループは、リソース管理のためにsystemd
システムおよびサービス・マネージャで使用できます。systemd
は、これらのグループを使用して、リソースを消費するユニットおよびサービスを編成します。systemd
の詳細は、systemdサービス・マネージャについてを参照してください。
systemd
は様々なユニット・タイプを提供しており、そのうちの3つはリソース制御を目的としたものです:
-
サービス: ユニット構成ファイルに基づく設定を持つプロセスまたはプロセスのグループ。サービスは、
systemd
が1つのセットとしてプロセスを開始または停止できるように、指定されたプロセスを「コレクション」に包含します。サービス名はname.service
の形式に従います。 -
スコープ: ユーザー・セッション、コンテナ、仮想マシンなど、外部で作成されたプロセスのグループ。サービスと同様に、スコープはこれらの作成されたプロセスをカプセル化し、任意のプロセスによって起動または停止され、実行時に
systemd
によって登録されます。スコープ名はname.scope
の形式に従います。 -
スライス: サービスとスコープが配置される、階層的に編成されたユニットのグループ。したがって、スライス自体にはプロセスが含まれていません。かわりに、スライス内のスコープおよびサービスによってプロセスが定義されます。スライス・ユニットのすべての名前が、階層内の場所へのパスに対応します。ルート・スライス(通常、すべてのユーザーベースのプロセスの場合は
user.slice
、システムベースのプロセスの場合はsystem.slice
)が、階層内に自動的に作成されます。親スライスがルート・スライスのすぐ下に存在し、parent-name.slice
という形式に従います。これらのルート・スライスは、複数のレベルのサブスライスを持つことができます。
サービス、スコープおよびスライス・ユニットは、制御グループ階層内のオブジェクトに直接マップされます。これらのユニットがアクティブ化されると、ユニット名から構築される制御グループ・パスに直接マップされます。systemd
リソース・ユニット・タイプと制御グループの間のマッピングを表示するには、次のように入力します。
sudo systemd-cgls
Working directory /sys/fs/cgroup:
├─user.slice (#1243)
│ → trusted.invocation_id: 50ce3909b2644f919ee420adc39edb4b
│ ├─user-1001.slice (#4167)
│ │ → trusted.invocation_id: 02e80a960d4549a7a9c69ce0fb546c26
│ │ ├─session-2.scope (#4405)
│ │ │ ├─2417 sshd: alice [priv]
│ │ │ ├─2430 sshd: alice@pts/0
│ │ │ ├─2431 -bash
│ │ │ ├─2689 sudo systemd-cgls
│ │ │ ├─2691 systemd-cgls
│ │ │ └─2692 less
...
│ └─user@984.service … (#3827)
│ → trusted.delegate: 1
│ → trusted.invocation_id: 09b47ce9f3124239b75814114353f3f2
│ └─init.scope (#3861)
│ ├─2058 /usr/lib/systemd/systemd --user
│ └─2099 (sd-pam)
├─init.scope (#19)
│ └─1 /usr/lib/systemd/systemd --switched-root --system --deserialize 17
└─system.slice (#53)
...
├─chronyd.service (#2467)
│ → trusted.invocation_id: c0f77aaa9c7844e6bef6a6898ae4dd56
│ └─1358 /usr/sbin/chronyd -F 2
├─auditd.service (#2331)
│ → trusted.invocation_id: 756808add6a348609316c9e8c1801846
│ └─1310 /sbin/auditd
├─tuned.service (#3079)
│ → trusted.invocation_id: 2c358135fc46464d862b05550338d4f4
│ └─1415 /usr/bin/python3 -Es /usr/sbin/tuned -l -P
├─systemd-journald.service (#1651)
│ → trusted.invocation_id: 7cb7ccb14e044a899aadf47bbb583ada
│ └─977 /usr/lib/systemd/systemd-journald
├─atd.service (#3623)
│ → trusted.invocation_id: 597a7a4e5646468db407801b8562d869
│ └─1915 /usr/sbin/atd -f
├─sshd.service (#3419)
│ → trusted.invocation_id: 490504a683fc4311ab0fbeb0864a1a34
│ └─1871 sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups
...
systemctl
などのsystemd
コマンドを使用してリソースを管理する方法の例は、システム・リソースへのアクセスの制御を参照してください。技術的な詳細は、systemctl(1)
、systemd-cgls(1)
、およびsystemd.resource-control(5)
の各マニュアル・ページを参照してください。
リソース配分モデルについて
次の配分モデルでは、cgroups v2
で使用するリソースを配分する際に制御または規制を実装する方法について説明します。
- 重み
-
このモデルでは、すべての制御グループの重みが合計されます。各グループは、合計の重みに対するグループの重みの比率に基づいて、リソースの一部を受け取ります。
10個の制御グループについて考えてみます。それぞれの重みは100で、合計は1000です。この場合、各グループは、指定されたリソースの10分の1を使用できます。
通常、重みはステートレス・リソースの配分に使用されます。このリソースを適用するには、
CPUWeight
オプションが使用されます。 - 制限
-
制御グループは、構成済のリソース量を使用できます。ただし、リソースをオーバーコミットすることもできます。したがって、サブグループの制限の合計が親グループの制限を超える可能性があります。
この配分モデルを実装するには、
MemoryMax
オプションが使用されます。 - 保護
-
このモデルでは、グループに保護された境界が割り当てられます。グループのリソース使用量が保護された量に収まっている場合、カーネルは、同じリソースについて競合する他のグループのためにリソースの使用を奪うことはできません。このモデルでは、リソースのオーバーコミットが許可されます。
このモデルを実装するには、
MemoryLow
オプションが使用されます。 - 割当て
-
このモデルでは、リアルタイム予算など、有限タイプのリソースの使用に対して特定の絶対金額が割り当てられます。
cgroups v2を使用したアプリケーションのリソースの管理
この項では、システムで実行されているプロセス間でのリソースの分散を管理するためにcgroups
を作成および構成できるように、cgroups v2
機能を有効にする方法を示します。
この項に含まれている手順例では、それぞれに異なるアプリケーションPIDが割り当てられたcgroups
間でCPU時間を割り当てています。CPU時間およびアプリケーションPID値は、各グループのCPU.weight
およびcgroup.procs
ファイルに設定されています。
この項には、手順例に従って /sys/fs/cgroup
の下に作成する必要があるcgroups
で、cpu
コントローラおよびそれに関連付けられたファイル(cpu.weight
ファイルを含む)を使用できるようにするために必要なステップも含まれています。
cgroups v2の有効化
ブート時に、Oracle Linux 9はデフォルトでcgroups v2
をマウントします。
-
cgroups v2
が有効で、システムにマウントされていることを確認します。sudo mount -l | grep cgroup
cgroup2 on /sys/fs/cgroup type cgroup2 (rw,nosuid,nodev,noexec,relatime,seclabel,nsdelegate,memory_recursiveprot)
-
必要に応じて、ルート制御グループとも呼ばれる
/sys/fs/cgroup
ディレクトリの内容を確認します。ll /sys/fs/cgroup/
cgroups v2
の場合、ディレクトリ内のファイルには、cgroup
.*、cpu
.*、memory
.*などのファイル名への接頭辞が必要です。制御グループ・ファイル・システムについてを参照してください。
CPU時間の配分のための制御グループの準備
-
/sys/fs/cgroup/cgroup.controllers
ファイルの内容を画面に出力して、cpu
コントローラが階層の最上部(ルート制御グループ)で使用可能であることを確認します。sudo cat /sys/fs/cgroup/cgroup.controllers
cpuset cpu io memory hugetlb pids rdma misc
cgroup.controllers
ファイルにリストされているコントローラを同じディレクトリのcgroup.subtree_control
ファイルに追加して、グループの直下の子cgroups
で使用できるようにすることができます。 -
cpu
コントローラをcgroup.subtree_control
ファイルに追加して、ルートの直下の子cgroups
で使用できるようにします。デフォルトでは、
memory
およびpids
コントローラのみがファイルに含まれます。cpu
コントローラを追加するには、次のように入力します。echo "+cpu" | sudo tee /sys/fs/cgroup/cgroup.subtree_control
-
オプションで、
cpu
コントローラが期待どおりに追加されたことを確認します。sudo cat /sys/fs/cgroup/cgroup.subtree_control
cpu memory pids
-
ルート制御グループの下に、アプリケーションのCPUリソースを管理するための新しい制御グループになる子グループを作成します。
sudo mkdir /sys/fs/cgroup/MyGroups
-
必要に応じて、新しいサブディレクトリまたは子グループの内容をリストし、
cpu
コントローラが期待どおりに存在することを確認します。ll /sys/fs/cgroup/MyGroups
-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 … -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
-
MyGroups
ディレクトリのcgroup.subtree_control
ファイルでcpu
コントローラを有効にして、その直下の子cgroups
で使用できるようにします。echo "+cpu" | sudo tee /sys/fs/cgroup/MyGroups/cgroup.subtree_control
-
必要に応じて、
cpu
コントローラがMyGroups
の子グループに対して有効になっていることを確認します。sudo cat /sys/fs/cgroup/MyGroups/cgroup.subtree_control
cpu
CPU時間の配分を制御するためのCPUの重みの設定
この手順は、次の仮定に基づいています。
-
次の
top
コマンドの出力例に示すように、CPUリソースを過度に消費しているアプリケーションはsha1sum
です:sudo top
... PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 33301 root 20 0 18720 1756 1468 R 99.0 0.0 0:31.09 sha1sum 33302 root 20 0 18720 1772 1480 R 99.0 0.0 0:30.54 sha1sum 33303 root 20 0 18720 1772 1480 R 99.0 0.0 0:30.54 sha1sum 1 root 20 0 109724 17196 11032 S 0.0 0.1 0:03.28 systemd 2 root 20 0 0 0 0 S 0.0 0.0 0:00.00 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 ...
-
前述のサンプル出力に示されているように、
sha1sum
プロセスには、PID 33301、33302および33303があります。
重要:
以降の手順の前提条件として、CPU時間の配分のための制御グループの準備の説明に従って、cgroup-v2
の準備を完了する必要があります。これらの準備をスキップした場合、この手順は完了できません。
-
MyGroups
サブディレクトリに3つの子グループを作成します。sudo mkdir /sys/fs/cgroup/MyGroups/g1 sudo mkdir /sys/fs/cgroup/MyGroups/g2 sudo mkdir /sys/fs/cgroup/MyGroups/g3
-
子グループごとにCPUの重みを構成します。
echo "150" | sudo tee /sys/fs/cgroup/MyGroups/g1/cpu.weight echo "100" | sudo tee /sys/fs/cgroup/MyGroups/g2/cpu.weight echo "50" | sudo tee /sys/fs/cgroup/MyGroups/g3/cpu.weight
-
アプリケーションPIDを対応する子グループに適用します。
echo "33301" | sudo tee /sys/fs/cgroup/Example/g1/cgroup.procs echo "33302" | sudo tee /sys/fs/cgroup/Example/g2/cgroup.procs echo "33303" | sudo /sys/fs/cgroup/Example/g3/cgroup.procs
これらのコマンドは、選択したアプリケーションを
MyGroups/g*/
制御グループのメンバーになるように設定します。各sha1sum
プロセスのCPU時間は、各グループに対して構成されたCPU時間配分によって異なります。実行中のプロセスを持つ
g1
、g2
およびg3
グループの重みは、親制御グループであるMyGroups
のレベルで合計されます。この構成では、すべてのプロセスが同時に実行されると、カーネルは、次のように、それぞれの
cgroup
のcpu.weight
ファイルに基づいて比例するCPU時間を各sha1sum
プロセスに割り当てます。子グループ cpu.weight
設定CPU時間割当ての割合 g1 150 ~50% (150/300) g2 100 ~33% (100/300) g3 50 ~16% (50/300) ある子グループに実行中のプロセスがない場合、実行中のプロセスのCPU時間割当ては、実行中のプロセスを持つ残りの子グループの合計の重みに基づいて再計算されます。たとえば、
g2
子グループに実行中のプロセスがない場合、合計の重みはg1+g3
の重みである200になります。この場合、g1
のCPU時間は150/200 (~75%)になり、g3
の場合は50/200 (~25%)になります。 -
指定した制御グループでアプリケーションが実行されていることを確認します。
sudo cat /proc/33301/cgroup /proc/33302/cgroup /proc/33303/cgroup
0::/MyGroups/g1 0::/MyGroups/g2 0::/MyGroups/g3
-
CPUの重みを設定した後で、現在のCPU消費を確認します。
top
... PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 33301 root 20 0 18720 1748 1460 R 49.5 0.0 415:05.87 sha1sum 33302 root 20 0 18720 1756 1464 R 32.9 0.0 412:58.33 sha1sum 33303 root 20 0 18720 1860 1568 R 16.3 0.0 411:03.12 sha1sum 760 root 20 0 416620 28540 15296 S 0.3 0.7 0:10.23 tuned 1 root 20 0 186328 14108 9484 S 0.0 0.4 0:02.00 systemd 2 root 20 0 0 0 0 S 0.0 0.0 0:00.01 kthread ...
cgroups v2を使用したユーザーのリソースの管理
前述のサンプル手順では、アプリケーションによるシステム・リソースの使用を管理する方法について説明します。システムにログインするユーザーにリソース・フィルタを直接実装して、リソースの使用を管理することもできます。
Oracle LinuxでのControl Groups Version 2の実行は、ユーザーによるシステム・リソースの使用を制御する方法の例を示すチュートリアルです。さらに、このチュートリアルでは、ユーザーがリソース消費を規制するためのステップをリアルタイムで実行できるラボ環境を提供しています。