はじめに
Dockerを始めとしたコンテナ型仮想化を、技術として捉えた際に出てくる用語に「Namespace」と「CGROUP」があります。
Dockerとは?
本記事ではCGROUPとはなんぞや?といった層を対象に、分かりやすく説明してみました。
このあたりを抑えてなくてもDockerを利用することは可能ですが、バックグラウンドの知識として知っておくと役立つこともあると思います。
CGROUUPとは?
CGROUPのCはControlを指します。
このグループでコントロールする対象はメモリやプロセス数の上限といったもので、つまりプロセスをグループ化し、そのグループに対してリソースを管理する機能がCGROUPです。
この技術は、同一マシンに複数コンテナを用意するDockerにおいて、全体のリソースが枯渇しないように各コンテナへのCPU時間の割り当て優先度やメモリ使用量などを調整するために利用されています。
例えばCGRROUPで管理するものに
- blkio
- cpuset
- device
- frezer
- hugetlb
- memory
- net_cls
などがありますが、
今回は実際にLinuxOS上でmemoryに関する設定値の確認方法を解説します。
コマンド実行環境
- Debian GNU/Linux 9 (stretch)
CGROUPに関する情報を確認する
CGROUPにて管理している情報一覧は以下ファイルで確認できます。
$ ls -l /proc/cgroups -r--r--r-- 1 root root 0 ... /proc/cgroups
中身を見ると
hierarchy | num_cgroupes | enabled |
という構造で値で上記で上げた項目が格納されています。
そして、実際の個々のプロセスがどのcgroupに属しているかは/proc/<プロセスID>/cgroup
で確認できます。
$ cat /proc/1/cgroup 10:blkio:/init.scope 9:pids:/init.scope 8:freezer:/ 7:perf_event:/ 6:net_cls,net_prio:/ 5:cpuset:/ 4:cpu,cpuacct:/init.scope 3:devices:/init.scope 2:memory:/init.scope 1:name=systemd:/init.scope
比較として現在のPIDで見てみると下記のような設定がされています。
$ cat /proc/$$/cgroup 10:blkio:/user.slice 9:pids:/user.slice/user-1000.slice/session-3447.scope 8:freezer:/ 7:perf_event:/ 6:net_cls,net_prio:/ 5:cpuset:/ 4:cpu,cpuacct:/user.slice 3:devices:/user.slice 2:memory:/user.slice 1:name=systemd:/user.slice/user-1000.slice/session-3447.scope
ここで、二つの設定値を比較すると、一部パスが異なっていることが分かりますが、今回は「メモリ」の値の制限を見に行くことにします。
上記設定値にてmemoryの情報欄を見ると/user.sliceという値が指定されています。
2:memory:/user.slice
このパスにこのプロセスIDに紐づくリソース割り当てが管理されています。
先ほどのパスは以下のディレクトリの下にある各項目からの相対パスです。
$ ls /sys/fs/cgroup blkio cpuacct cpuset freezer net_cls net_prio pids cpu cpu,cpuacct devices memory net_cls,net_prio perf_event systemd
memoryディレクトリの中に
$ ls /sys/fs/cgroup/memory/ cgroup.clone_children memory.limit_in_bytes ... init.scope memory.pressure_level ... memory.kmem.usage_in_bytes user.slice
user.sliceがありました。
つまり、このuser.sliceディレクトリに設定値が入っていることが分かります。
逆にプロセス番号1のcgroupの中には
2:memory:/init.scope
と記載があったので上記でいうinit.scopeの中に設定値が入っています。
user.sliceディレクトリの中には設定項目が格納されており
$ ls /sys/fs/cgroup/memory/user.slice/ cgroup.clone_children memory.limit_in_bytes cgroup.event_control memory.max_usage_in_bytes ....
例えばメモリの制限を扱うmemory.limit_in_bytesを中を見ると
$ cat /sys/fs/cgroup/memory/user.slice/memory.limit_in_bytes 9223372036854771712
設定値が格納されています。
終わりに
今回は実際のマシン上でCGROUPを司るファイルを確認しながら理解を深めました。
ここで例えばuser.sliceの代わりにtestといったディレクトリを作成し、cgroupの中を
2:memory:/test
と変更することでリソースの割り当てを変更することも可能です。
Dockerを作成する際にcpuやメモリの割り当てをオプションで指定できますが、その際にこれらの技術要素が裏で動いていることをイメージできれば十分かと思います。
以上、ご参考になれば幸いです。