cgroup の値を元に Docker Container に適用された Swap領域 の制限を確認する方法

Written by @ryysud

Oct 9, 2018 22:50 · 1684 words · 4 minutes read #docker #linux

TL;DR

Docker Host から Docker Container の Swap領域 の制限を確認する方法

/sys/fs/cgroup/memory/docker/<Long Container ID>/memory.stat の hierarchical_memory_limit と hierarchical_memsw_limit の値を取得して、hierarchical_memsw_limit - hierarchical_memory_limit を計算する。

Docker Container の内部から Swap領域 の制限を確認する方法

/sys/fs/cgroup/memory/memory.stat の hierarchical_memory_limit と hierarchical_memsw_limit の値を取得して、hierarchical_memsw_limit - hierarchical_memory_limit を計算する。

検証に利用する Docker Host

CPU が 2core、Memory が 4GB の CentOS 7.5 上に Docker CE をインストールして、そのホスト上で諸々のコマンド実行を行っていきます。なお、利用する Docker のバージョンは 18.06.1-ce となります。

$ cat /etc/redhat-release
CentOS Linux release 7.5.1804 (Core)

$ docker --version
Docker version 18.06.1-ce, build e68fc7a

※ Docker CE のインストール方法は 公式ドキュメント を参考に実施

モチベーション

Docker Container に適用されている Swap領域 の制限を確認したくて docker stats を実行してみたのですが、以下の実行結果からわかるように、メモリ制限は確認できても、Swap領域 の制限が確認できないことがわかりました。「じゃあどのように確認すれば良いのだろう?」と気になり調べ始めたのが、この記事を書こうと思ったきっかけです。

$ docker run --name dev-nginx -d -p 8080:80 nginx
$ docker stats --no-stream dev-nginx
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT   MEM %               NET I/O             BLOCK I/O           PIDS
d11830545c14        dev-nginx           0.00%               1.352MiB / 3.7GiB   0.04%               1.02kB / 0B         0B / 0B             2

ちなみに docker stats –help を叩いてみても、目ぼしいオプションはありませんでした…。

$ docker stats --help

Usage:	docker stats [OPTIONS] [CONTAINER...]

Display a live stream of container(s) resource usage statistics

Options:
  -a, --all             Show all containers (default shows just running)
      --format string   Pretty-print images using a Go template
      --no-stream       Disable streaming stats and only pull the first result
      --no-trunc        Do not truncate output

cgroup による Docker Container のリソース制限

Docker Container や LXC(Linux Containers)を始めとしたコンテナ技術は、cgroup(control group)という Linux Kernel の機能を用いて、コンテナのリソースの制限を行っています。
※ 今回は cgroup の詳細な説明は割愛します

なので、cgroup によるリソース制限の情報を取得することができれば、Swap領域 の制限を確認することが可能となるわけです。

Docker Host から Docker Container の Swap領域 の制限を確認する方法

/sys/fs/cgroup/memory/docker/<Long Container ID>/memory.stat に各 Docker Container 毎の Swap領域 の制限を含むメモリ関連の制限情報が格納されています。

memory.stat の hierarchical_memory_limit の値がメモリ制限で、hierarchical_memsw_limit が メモリ制限 + Swap領域の制限 となっているので、hierarchical_memsw_limit - hierarchical_memory_limit を計算することで Swap領域 の制限を算出することが可能となります。

Docker Container の内部から Swap領域 の制限を確認する方法

/sys/fs/cgroup/memory/memory.stat に Swap領域 の制限を含むメモリ関連の制限情報が格納されています。
※ Swap領域 の制限の算出方法は同上なので割愛。

実際に Docker Host と Docker Container の両方から Swap領域 の制限を確認していく

まずは メモリ と Swap領域 に制限をかける形で Docker Container を起動する

メモリ制限を 1GB、Swap領域の制限を 1GB で Nginx コンテナを起動します。

# --memory-swap には メモリ制限 + Swap領域の制限 となる値を指定する仕様のため 2G を指定
$ docker run -d --name dev-nginx --memory 1G --memory-swap 2G -p 8080:80 nginx

docker stats を実行してみると、メモリ制限 1GB が効いていることがわかります。

$ docker stats --no-stream dev-nginx
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT   MEM %               NET I/O             BLOCK I/O           PIDS
b17b295e8e94        dev-nginx           0.00%               2.883MiB / 1GiB     0.28%               648B / 0B           0B / 0B             2

Docker Host から Docker Container の Swap領域 の制限を確認する

まずは Nginx コンテナの Long Container ID を調べます。

$ docker inspect --format="{{.Id}}" dev-nginx
b17b295e8e946be90b72014b366ef6e2e6f0de7e1ddd5961a13fceac06a2bc46

Docker Host の /sys/fs/cgroup/memory/docker/<Long Container ID>/memory.stat の hierarchical_memory_limit と hierarchical_memsw_limit の値を確認します。

$ cat /sys/fs/cgroup/memory/docker/b17b295e8e946be90b72014b366ef6e2e6f0de7e1ddd5961a13fceac06a2bc46/memory.stat | egrep 'hierarchical_memory_limit|hierarchical_memsw_limit'
hierarchical_memory_limit 1073741824
hierarchical_memsw_limit 2147483648

# hierarchical_memory_limit と hierarchical_memsw_limit は bytes なので GB に換算
$ echo "$((1073741824/1024/1024/1024))GB"
1GB

$ echo "$((2147483648/1024/1024/1024))GB"
2GB

hierarchical_memsw_limit - hierarchical_memory_limit = 2GB - 1GB = 1GB となり、Swap領域 の制限は Docker Container 起動時に指定したとおりで 1GB が適用されていることがわかります。

Docker Container の内部から Swap領域 の制限を確認する

Docker Container の /sys/fs/cgroup/memory/memory.stat の hierarchical_memory_limit と hierarchical_memsw_limit の値を確認します。

$ docker exec dev-nginx cat /sys/fs/cgroup/memory/memory.stat | egrep 'hierarchical_memory_limit|hierarchical_memsw_limit'
hierarchical_memory_limit 1073741824
hierarchical_memsw_limit 2147483648

$ echo "$((1073741824/1024/1024/1024))GB"
1GB

$ echo "$((2147483648/1024/1024/1024))GB"
2GB

hierarchical_memsw_limit - hierarchical_memory_limit = 2GB - 1GB = 1GB となり、Swap領域 の制限は Docker Container 起動時に指定したとおりで 1GB が適用されていることがわかります。

おわりに

hierarchical_memory_limit と hierarchical_memsw_limit を何度も typo して途中で心が折れそうになりましたが、 今回のゴールに掲げていた “Docker Container に適用された Swap領域 の制限を確認する方法” を把握することが出来たので非常に満足です。

雰囲気でしかコンテナを理解してないマンを、早いとこ脱却したい想いが大きいので、今度時間があるときにでも、今回は割愛した cgroup などのコンテナ技術を支える Linux Kernel の機能をより詳細に調べていけたらと思います (`・ω・´) !!!