7.3. リソース制御
LinuxOSにはユーザが使用できるシステムリソース量を制限できる機能があり、制限にはulimitコマンドを用いる。
7.3.1. ユーザーおよびシェルのリソース制限(ulimit)
ulimitコマンド
シェルやシェルにより開始されるプロセスが使用できるリソースを制限できるコマンド。
ulimit -a| オプション | 説明 | 
|---|---|
| -a | 現在設定されている値を全て表示 | 
| -f | シェルとその子によって書き込まれるファイルの最大サイズ | 
| -t | 最大 CPU 時間 (秒単位) | 
| -d | データセグメントの最大サイズ | 
| -v | 仮想メモリの最大サイズ | 
| -l | Swapされないメモリの最大容量 | 
| -c | コアファイルの最大サイズ | 
| -u | 1 人のユーザーが使用できるプロセスの最大数 | 
| -T | スレッドの最大数 | 
| -H | ハードリミットの指定 | 
| -S | ソフトリミットの指定 | 
恒久的なリソース制限の設定
再起動時にulimitの設定を維持するには、/etc/security/limits.confでシステム全体に制限をかける必要がある。
なお制限方法は以下の2種類がある。
- ソフトリミット … 現在有効なユーザーの利用可能なリソースの制限
- ハードリミット … 実際の最大制限
pam_limits.so
pam_limits.soモジュールはユーザセッションで取得できるシステムリソースに制限を設定できるもの。
なおuid=0のユーザも影響を受ける。
またデフォルトに制限は構成ファイル/etc/security/limits.conf、次にディレクトリ/etc/security/limit.dの各ファイルが読み取られる。
# ======================================
## ユーザが作成可能なファイルサイズの制限
# ======================================
# ``/etc/security/limits.conf``の属性を編集
#<domain> <type> <item> <value>
*         soft   fsize  5120
*         hard   fsize  10240
# 一般ユーザでログインしulimitを実行(値の反映の確認)
ulimit -H -f
ulimit -S -f制限可能なitemは以下の通り。
| リソース | 説明 | 
|---|---|
| as | 最大仮想メモリ空間(KB) | 
| core | 最大コアファイルサイズ(KB) | 
| cpu | 最大CPU時間(分) | 
| data | 最大データセグメントサイズ(KB) | 
| fsize | 最大ファイルサイズ(KB) | 
| maxlogins | 最大ログイン数(root以外) | 
| memlock | ロック可能な最大メモリサイズ | 
| nofile | プロセス当たりのオープン可能な最大ファイルディスクリプタ数 | 
| nproc | 最大プロセス数 | 
| stack | 最大スタックサイズ(KB) | 
7.3.2. cgroupsによるリソース管理
Cgroup
CgroupはRedHat系の機能でシステム上で実行されているユーザー定義のタスク (プロセス) グループ間で、CPU 時間、システム、メモリ、ネットワーク帯域幅、またはこれらのリソースの組み合わせなどのリソースを割り当てることができる仕組みのこと。
一言で言うとカーネル内の特定のサブシステムを制御するためのメカニズムといえる。
Cgroups V1(RHEL8以前)の仕組み
CgroupsはKubernetes、Docker等のコンテナ技術でも使用されている。
Cgroupにおいてデバイス、CPU,メモリ(RAM)、ネットワークアクセスなどのサブシステムはコントローラと呼ぶ。
コントローラのタイプ(Cpu,blkio,memoryなど)はツリー上に細分化され、各枝や葉には独自の重み/制限がある。 コントローラのグループは複数のプロセスが関連付けられているため、リソースしよるいつが細かくなっており微調整が容易となっている。

cgroup はリソースタイプごとに作成され、相互に関連付けはない。 つまり、すべてのコントローラにグループを関連付けることはできるが、グループは独立して扱われる。
Cgroupのコントローラ
Cgroupのコントローラのタイプは以下の通り。
| コントローラ | 用途 | 
|---|---|
| cpu | CPUアクセスのスケジューリング | 
| cpuset | CPUおよびメモリノードの割り当て | 
| cpuacct | タスクが消費するCPUリソースに関するレポートの作成 | 
| memory | メモリリソースのレポート作成やメモリ使用量の上限設定 | 
| devices | デバイスへのアクセス制御 | 
| freezer | プロセスの一時停止または再開 | 
| net cls | cgroupから発信されるパケットをタグ付け管理 | 
| blkio | ブロックデバイスに対するI/Oアクセスの制御/監視 | 
| net prio | ネットワークトラフィックの優先度を設定 | 
cgroupsの状態確認
/proc/cgroups
コンピュータ上で有効なコントロールグループが確認できる。
cat /proc/cgroups/sys/fs/group
/sys/fs/groupはcgroupのコントローラ(サブシステム)が管理されている擬似ファイルシステムのこと。
sysfs経由でも確認できる。
ls -l  /sys/fs/groupcgroupsの管理ユーティリティ
cgmanagerとlibcgroupユーティリティはsystemdがcgroups管理の標準となる以前に、ユーザープロセスやシステム全体でcgroupsを管理するために使用されていたもの。
- libcgroupユーティリティ- cgroupsを手動で作成、設定、プロセスをグループに追加するためのツール群(cgcreate, cgset, cgexec, cgclassifyなど)を提供します。
 
- cgmanager- 以前のUbuntu/Debian系システムなどで使用されていたcgroup管理のデーモンです。
 
cgroup associationの加工
cgroup associationの加工は特定のプロセスを既存のcgroup(または新しく作成したcgroup)に関連付ける(移動させる)ことを指す。
- cgexec- 新しいcgroupでコマンドを実行する
- cgexec -g cpu:mygroup stress -c 2
 
- cgclassify- 実行中のプロセスを指定したcgroupに移動させる
- cgclassify -g memory:limited_mem 12345(PID 12345を移動)
 
- echo(手動操作)- プロセスID(PID)を手動でcgroupファイルに書き込む
- echo $$ > /sys/fs/cgroup/cpu/mygroup/tasks
 
7.3.3. systemdによるリソース制御
systemdリソース制御の理解
systemdはネイティブにcgroupsを使用し、サービス、ソケット、マウント、ユーザーセッションなどをユニットとして管理することでリソース制御を抽象化する。
- systemdにおけるcgroupsの利用:- systemdは、すべてのプロセスを自動的にcgroup階層内に配置します。これにより、すべてのプロセスがリソース管理の対象となる。
 
- スライス (Slice) を含むsystemdリソース制御の理解:- Slice (.slice): cgroup階層の最上位ノードを定義し、リソースの大きな割り当てに使われます(例: system.slice, user.slice)。
- Scope (.scope): 外部プロセス(例: ユーザーが手動で実行したシェルやプログラム)をcgroupsに割り当てるために使用されます。
- Service (.service): サービスプロセス(例: Apache, SSHD)をcgroupsに割り当てるために使用され、最も一般的なリソース制御の対象です。
 
systemdユニットのリソース制限の設定
リソース制限の設定は、ユニットファイルの[Service]セクションに、リソース制御ディレクティブを記述することで行います。
| ディレクティブ | 目的 | コマンド例 | 
|---|---|---|
| MemoryMax= | サービスが使用できるメモリの最大量を制限します。 | MemoryMax=512M | 
| CPUQuota= | サービスが利用できるCPU時間の割合を制限します。 | CPUQuota=20% | 
| CPUAffinity= | サービスを実行するCPUコアを特定のセットに固定します。 | CPUAffinity=0 1 | 
| IOWeight= | I/Oアクセスに対する優先度(重み)を設定します。 | IOWeight=500 | 
systemdによるcgroupsの監視
systemd-cglsコマンドで制御グループの階層を表示ができる。systemd-cgtopコマンドではのリソース消費をリアルタイムで監視できる。
systemd-cgls
systemd-cgtop