7.3. リソース制御

LinuxOSにはユーザが使用できるシステムリソース量を制限できる機能があり、制限にはulimitコマンドを用いる。

7.3.1. ユーザーおよびシェルのリソース制限(ulimit)

ulimitコマンド

シェルやシェルにより開始されるプロセスが使用できるリソースを制限できるコマンド。

ulimit -a
オプション説明
-a現在設定されている値を全て表示
-fシェルとその子によって書き込まれるファイルの最大サイズ
-t最大 CPU 時間 (秒単位)
-dデータセグメントの最大サイズ
-v仮想メモリの最大サイズ
-lSwapされないメモリの最大容量
-cコアファイルの最大サイズ
-u1 人のユーザーが使用できるプロセスの最大数
-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など)はツリー上に細分化され、各枝や葉には独自の重み/制限がある。 コントローラのグループは複数のプロセスが関連付けられているため、リソースしよるいつが細かくなっており微調整が容易となっている。

Cgropus

cgroup はリソースタイプごとに作成され、相互に関連付けはない。 つまり、すべてのコントローラにグループを関連付けることはできるが、グループは独立して扱われる

Cgroupのコントローラ

Cgroupのコントローラのタイプは以下の通り。

コントローラ用途
cpuCPUアクセスのスケジューリング
cpusetCPUおよびメモリノードの割り当て
cpuacctタスクが消費するCPUリソースに関するレポートの作成
memoryメモリリソースのレポート作成やメモリ使用量の上限設定
devicesデバイスへのアクセス制御
freezerプロセスの一時停止または再開
net clscgroupから発信されるパケットをタグ付け管理
blkioブロックデバイスに対するI/Oアクセスの制御/監視
net prioネットワークトラフィックの優先度を設定

cgroupsの状態確認

/proc/cgroups

コンピュータ上で有効なコントロールグループが確認できる。

cat /proc/cgroups

/sys/fs/group

/sys/fs/groupはcgroupのコントローラ(サブシステム)が管理されている擬似ファイルシステムのこと。
sysfs経由でも確認できる。

ls -l  /sys/fs/group

cgroupsの管理ユーティリティ

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