前回は、
cgroupは2006年9月にGoogleのエンジニアによって最初のパッチが投稿され、
cgroupは"Control Group"の略です。プロセスをグループ化して、
前回説明したように、
名前空間機能と同様に、
cgroupがどのようなリソースに対して制限や管理を行えるのかという説明をする前に、
cgroupファイルシステム
cgroup機能を使ってプロセスをグループ化したものをcgroupと呼びます。cgroupはcgroupファイルシステム
では、
※ CentOS 6、
cgroupファイルシステムのマウント
cgroupfsは以下のようにマウントします。ここで"-o"で指定しているオプションは次回説明します。cgroupfsはどのディレクトリにでもマウント可能ですが、/sys/
以下にマウントするという風に決められています。
$ sudo mount -t tmpfs cgroup /sys/fs/cgroup (/sys/fs/cgroupをtmpfsでマウント) $ sudo mkdir /sys/fs/cgroup/cpu (cgroupマウント用のディレクトリ作成) $ sudo mount -t cgroup -o cpu cgroup /sys/fs/cgroup/cpu (cgroupfsのマウント)
この例では、
その後、/sys/
を作成しています。その後、mount
コマンドの-t
オプションにcgroup
を指定してcgroupfsをマウントしています。
マウントしたcgroupfsの中は普通のディレクトリのように見ることができます。ls
コマンドで見てみましょう。
$ ls /sys/fs/cgroup/cpu cgroup.clone_children cpu.cfs_period_us cpu.rt_runtime_us notify_on_release cgroup.event_control cpu.cfs_quota_us cpu.shares release_agent cgroup.procs cpu.rt_period_us cpu.stat tasks
マウントしただけでいろいろなファイルが自動的に作られていますね。この自動的に作られたファイルがcgroupの使用状況を見たり、
cgroupの作成
それではマウントしたcgroupfsを使ってプロセスをグループ化するためのcgroupを作ってみましょう。cgroupはcgroupfs上のディレクトリで表されます。作成は通常のファイルシステムと同じようにmkdir
コマンドで可能です。それではtest01
というcgroupを作ってみましょう。
$ cd /sys/fs/cgroup/cpu $ sudo mkdir test01 $ ls -F cgroup.clone_children cpu.cfs_quota_us cpu.stat test01/ cgroup.event_control cpu.rt_period_us notify_on_release cgroup.procs cpu.rt_runtime_us release_agent cpu.cfs_period_us cpu.shares tasks
test01
というディレクトリが作られています。
$ ls test01 cgroup.clone_children cpu.cfs_period_us cpu.rt_runtime_us notify_on_release cgroup.event_control cpu.cfs_quota_us cpu.shares tasks cgroup.procs cpu.rt_period_us cpu.stat
このディレクトリの中をのぞいてみると、
プロセスの登録
さて、tasks
ファイルです。
先ほど作成したtest01
cgroupを使って説明していきます。プロセスを登録する前に、test01
にあるtasks
ファイルの中身を見てみましょう。
$ cat /sys/fs/cgroup/cpu/test01/tasks $
このとおり、
プロセスを登録するには、tasks
ファイルにPIDを登録するだけです。登録方法は簡単で通常のファイルに書き込むように登録できます。ここでは現在のシェルを登録してみましょう。
$ echo $$ | sudo tee -a /sys/fs/cgroup/cpu/test01/tasks 17955
プロセスがcgroupに登録されたかどうかを確認するのは、tasks
ファイルの中身を確認して、
$ cat /sys/fs/cgroup/cpu/test01/tasks 17955 18092
先ほど登録したシェルのPIDが登録されているのがわかります。シェルのPIDの他にもう1つPIDが登録されていますね。これは確認に使ったcatのPIDです。このようにcgroupに登録したプロセスの子プロセスやその子孫も自動的に同じcgroupに登録されます。
プロセスの移動
次にcgroupに登録したプロセスを別のcgroupに移動させてみましょう。test02
というcgroupを作成します。そして、test02
に登録して、
$ sudo mkdir /sys/fs/cgroup/cpu/test02 (test02グループの作成) $ echo $$ | sudo tee -a /sys/fs/cgroup/cpu/test02/tasks (プロセスをtest02に登録) 17955 $ cat /sys/fs/cgroup/cpu/test02/tasks (test02グループに属するプロセスの確認) 17955 (確かに登録されている) 18728 $ cat /sys/fs/cgroup/cpu/test01/tasks (test01グループに属するプロセスの確認) $ (登録されているプロセスはない!)
このように新しく作成したtest02
グループに先ほどtest01
に登録したシェルのPIDを登録すると、test02
グループに登録されているのがわかります。その後test01
ディレクトリを確認してみると、tasks
ファイルの中身が空になっています。つまり、
cgroupの削除
この時点でtest01
に登録されたプロセスはなくなりました。tasks
ファイルの中が空になったcgroupは削除できます。削除も通常のディレクトリ操作と同じようにrmdir
コマンドで削除できます。
$ sudo rmdir /sys/fs/cgroup/cpu/test01 $ ls /sys/fs/cgroup/cpu/test01 ls: cannot access /sys/fs/cgroup/cpu/test01: No such file or directory
これでcgroupが削除できました。
ここまでの例で、
cgroupの階層構造
さて、
先にmount
コマンドを使って/sys/
にcgroupfsをマウントしました。このcgroupfsのトップディレクトリにも作成したcgroupと同じようにいろいろなファイルができていました。この/sys/
にあるtask
ファイルの中身を見てみましょう。
$ cat /sys/fs/cgroup/cpu/tasks 1 2 3 5 :(略)
PID 1を先頭に、
新たにcgroupを作成してプロセスを登録すると、/sys/
からはそのPIDが消えることになります。逆に、tasks
にPIDを登録して移動させます。削除というよりは、
さて、
先ほど作成したtest02
グループの下にtest03
グループを作ってみましょう。
$ sudo mkdir /sys/fs/cgroup/cpu/test02/test03 $ ls /sys/fs/cgroup/cpu/test02/test03 cgroup.clone_children cpu.cfs_period_us cpu.rt_runtime_us notify_on_release cgroup.event_control cpu.cfs_quota_us cpu.shares tasks cgroup.procs cpu.rt_period_us cpu.stat
今までと全く同じようにディレクトリが作成され、
ここまで見てきたように、
この階層構造を使ってプロセスをグループ化して管理できます。たとえば、

この図では、
この例のようにcgroupの親子関係の間では、
cgroupが管理するどのようなリソースでも階層構造を使用できます。しかし、
以上のようにcgroupを操作することにより、
まとめ
以上のようにcgroupを操作することにより、
さて、
- cgroupはcgroupfsという特別なファイルシステムで管理する
- cgroup はディレクトリで表される
- cgroupfsをマウントするとデフォルトでは全てのプロセスがトップディレクトリのグループにデフォルトで登録される
- 子プロセスはデフォルトでは親のプロセスと同じcgroupに属する
- cgroupは階層構造を取り、
グループ間の親子関係を構成できる - システム上のプロセスは必ずcgroupfsのトップディレクトリ以下のcgroupのどれか1つだけに属する
ここまででプロセスをどうグループ化して管理するかの説明ができましたので、