libcgroup無しで、cgroupによるプロセスへのCPU割り当て制限

LinuxカーネルにはCPUやメモリといったリソースをプロセス単位で制限できるcgroupという機能があります。


cgroupの使い方を紹介する多くの記事ではaptやyumでlibcgroupをインストールしていますが、
組み込みなどでは、apt/yumを使えず、ライブラリの追加が容易ではない環境もあります。


そこで、libcgroupを使わずにcgroupによるCPU割り当て制限を試してみました。

使い方

cgroupも/procや/sys同様に、カーネルが生成するファイルへのアクセスで操作できます。


大まかな使い方は以下のとおりです。

  1. cgroupをmount(cgroupを操作するためのファイルが生成される)
  2. mount先のディレクトリ直下にディレクトリを作成することで、リソース制限を行うグループ(これをcgroupと呼ぶ)を作成できる
  3. 作成したディレクトリ直下にも自動的にファイルが生成されているので、それらのファイルへパラメータを書き込むことでリソースを制限できる

※ cgroupを使うために必要なカーネルコンフィギュレーションカーネルのビルド方法については割愛します。

プロセスへのCPU割り当てを10%までに制限してみる

まずは、cgroupをmountします。

# mkdir -p /cgroup  <== mount先のディレクトリを作成
# mount -t cgroup cgroup /cgroup  <== mount


(追記 2016/12/15)
cgroupのマウントポイントとしては/sys/fs/cgroupが一般的なようです。
(少なくとも、Debian Jessieでは/sys/fs/cgroupへマウントしています。)


そして、次にリソース制限を行うグループ(cgroup)を作成します。
操作としてはマウント先のディレクトリ直下にディレクトリを作成するだけです。

# mkdir /cgroup/test

※ lsすると/cgroup/直下と同じファイルがtest/にも自動的に生成されていることがわかります。


cgroupの初期設定として、cgroup内のプロセスがアクセス可能なCPU(cpuset.cpus)とメモリ(cpuset.mems)を設定します。
親(/cgroup/直下)の設定を確認し、そのまま同じ設定を行います。

# cat /cgroup/cpuset.cpus
0
# cat /cgroup/cpuset.mems
0
# echo 0 > /cgroup/test/cpuset.cpus
# echo 0 > /cgroup/test/cpuset.mems


そして、cgroupへのCPUの割り当て制限を行います。
ここでは10%までに制限しています。

# cat /cgroup/test/cpu.cfs_period_us  <== CPUリソースの割り当てを行う周期(マイクロ秒)
100000
# echo 10000 > /cgroup/test/cpu.cfs_quota_us  <== cfs_period_usの10%を設定


最後に、制限を行いたいプロセスをcgroupのtasksへ追加します。
ここでは、PID 6799のプロセスをcgroupへ追加しています。

# echo 6799 > /cgroup/test/tasks

※ 以降、test/tasksへ同様にプロセスを追加していくと、tasksのプロセス合計のCPU使用率が10%までとなるよう制限されます


CPUリソースが制限されている様子はtop、htopなどで確認すると分かりやすいです。

おまけ: cgroupを一時停止(FROZEN)したり、再開(THAWED)したり

freezer.stateを使用すると、cgroupに属するプロセスを一時停止したり、再開したりできます。


■ 一時停止させる

# echo FROZEN > /cgroup/test/freezer.state


■ 再開させる

# echo THAWED > /cgroup/test/freezer.state

参考

cgroupをマウントした先の各ファイルについては、redhatのマニュアルが参考になります。