今年も年末を迎えて,
昨年のこの時期に書いた第16回は,
今年同じことをやっても新鮮味にはかけると思いますが,
Linux Advent Calendarということで,
cgroup
この連載では,
その際に説明したように,
カーネルのバージョン2.
その後,
新しい機能のリリースはなくても,
それが4.
cgroupによるプロセス数の制限
コンテナごとに起動できるプロセスの数を制限したいという要求は,
cgroupでも,
筆者が主催しているコンテナ型仮想化の情報交換会の第2回では,
私は,
pidsサブシステムを有効にしたカーネルの作成
それでは早速pidsサブシステムを使ってみましょう。今回の記事の実行例はPlamo 6.
pidsサブシステムを使うには,CONFIG_を有効にする必要があります。make menuconfigなどで設定する場所は他のcgroupサブシステムと同じ場所です。
General setup --->
Control Group support --->
[*] PIDs cgroup subsystem新しく作ったカーネルで起動すると,/proc/にpidsという行が現れています。
$ cat /proc/cgroups | grep pids pids 12 5 1
マウントとグループの作成
pidsサブシステムを使う際にマウントを行う方法は,-oオプションでpidsを指定します。
たとえば以下のように行います。
$ sudo mkdir -p /sys/fs/cgroup/pids $ sudo mount -t cgroup -o pids none /sys/fs/cgroup/pids
このマウントした/
$ ls /sys/fs/cgroup/pids/ cgroup.clone_children cgroup.sane_behavior notify_on_release release_agent cgroup.procs pids.current tasks
ここにtest01というグループを作成してみましょう。
$ sudo mkdir /sys/fs/cgroup/pids/test01 $ ls /sys/fs/cgroup/pids/test01 cgroup.clone_children notify_on_release pids.max cgroup.procs pids.current tasks
pids.とpids.が,
pidsサブシステム用ファイル
pidsサブシステム独自で使用するファイルは以上の 2 つです。ファイル名ですぐに役割が分かったのではないでしょうか。
| ファイル名 | ファイルの役割 |
|---|---|
| pids. |
グループ内の現在のプロセス数 |
| pids. |
グループ内で許可するプロセス数 |
それぞれのファイルが,test01グループで見てみます。
$ cat /sys/fs/cgroup/pids/test01/pids.current 0 $ cat /sys/fs/cgroup/pids/test01/pids.max max
グループを作成した直後ですから,pids.は当然0になりますね。制限なしとするにはpids.にmaxと書きます。初期値は制限なしでmaxです。
制限を追加する
制限値を設定する方法は通常のcgroupの使い方と同じです。制限値として2を設定してみましょう。
$ echo 2 | sudo tee /sys/fs/cgroup/pids/test01/pids.max 2 $ cat /sys/fs/cgroup/pids/test01/pids.max 2
ファイルの内容は,
現在のシェルをグループに追加してみましょう。
$ echo $$ | sudo tee /sys/fs/cgroup/pids/test01/tasks 5600 $ cat /sys/fs/cgroup/pids/test01/pids.current 2
pids.の内容は,catで2になっています。
ここでパイプでつないでコマンドを実行してみましょう。
$ ( /bin/echo "Gihyo" | cat ) bash: fork: retry: No child processes bash: fork: retry: No child processes bash: fork: retry: No child processes bash: fork: retry: No child processes bash: fork: Resource temporarily unavailable Terminated
シェルを登録してひとつ消費した状態で2つ実行しようとしたので,
階層構造
第3回でcgroupの特徴として階層構造が取れることを紹介しました。
それでは多層の場合に,
先ほどのtest01グループの下層にtest02グループを作成します。test01は2を設定しておき,test02は作成したままで特に制限をかけないままにしておきます。
$ sudo mkdir /sys/fs/cgroup/pids/test01/test02 $ cat /sys/fs/cgroup/pids/test01/pids.max 2 $ cat /sys/fs/cgroup/pids/test01/test02/pids.max max
test02にプロセスを追加して,test01とtest02のpids.を確認してみます。
$ echo $$ | sudo tee /sys/fs/cgroup/pids/test01/test02/tasks 26500 $ cat /sys/fs/cgroup/pids/test01/tasks $ cat /sys/fs/cgroup/pids/test01/test02/tasks 26500 26582 $ cat /sys/fs/cgroup/pids/test01/pids.current 2 $ cat /sys/fs/cgroup/pids/test01/test02/pids.current 2
test01のtasksは空ですので,test01グループにはプロセスは登録されていない状態です。test02のtasksには追加したシェルのPIDとcatのPIDが表示されています。つまりcatを実行した瞬間は,test02には2つプロセスが存在する状態ですね。
pids.を見てみると,test01,test02ともに2となっています。これは,
ここで先ほどと同様にpids.を超えるプロセスを生成してみます。
$ ( /bin/echo "Gihyo" | cat ) bash: fork: retry: No child processes bash: fork: retry: No child processes bash: fork: retry: No child processes bash: fork: retry: No child processes bash: fork: Resource temporarily unavailable Terminated
プロセスは生成できませんね。つまり階層構造を持つグループの場合,