(O+P)ut

アウトプット



(O+P)ut

エンジニアのアウトプット

【Docker入門】CGROUPによるプロセスリソースの管理

スポンサーリンク

はじめに

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やメモリの割り当てをオプションで指定できますが、その際にこれらの技術要素が裏で動いていることをイメージできれば十分かと思います。

以上、ご参考になれば幸いです。