ようへいの日々精進XP

よかろうもん

Docker コンテナのメトリクス監視について雑にメモる

追記(2015/08/14)

Docker 1.8 のリリースに含まれていた追加仕様 により dd-agent からホスト側 cgroup のマウントポイントが見えない状態が発生していたようだ。

github.com

既に上記にて対応済みとなっているが、まだ dd-agent の最新版には反映されていないので注意が必要。すぐに対応が必要な場合には以下のように最新の docker.py を取得して独自にコンテナをビルドする必要があると思われる。

$ git diff Dockerfile
diff --git a/Dockerfile b/Dockerfile
index 17f11f5..d4a1343 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -26,7 +26,12 @@ RUN mv /etc/dd-agent/datadog.conf.example /etc/dd-agent/datadog.conf \
  && sed -i "/user=dd-agent/d" /etc/dd-agent/supervisor.conf \
  && sed -i 's/AGENTUSER="dd-agent"/AGENTUSER="root"/g' /etc/init.d/datadog-agent \
  && chmod +x /etc/init.d/datadog-agent \
- && rm /etc/dd-agent/conf.d/network.yaml.default
+ && rm /etc/dd-agent/conf.d/network.yaml.default 
+
+# 7. Replace the old docker.py
+RUN cd /opt/datadog-agent/agent/checks.d/ \
+ && mv docker.py docker.py.old
+COPY checks.d/docker.py /opt/datadog-agent/agent/checks.d/docker.py
 
 # Add Docker check
 COPY conf.d/docker.yaml /etc/dd-agent/conf.d/docker.yaml

はじめに

Datadog とか Mackerel 等で Docker コンテナのメトリクス監視について調べていたら、何となくしか知らなかったことや「へえ」と思うことがあったりしたので雑にメモっていきたい。


参考

あと、以下の資料。

speakerdeck.com

英語はわかんないけど簡潔に纏まっていて良かった。


メトリクス監視パターン

  • コンテナホスト(ECS 的にはコンテナインスタンス)側に監視エージェントをインストールする
  • モニタ用コンテナを実行させる
  • docker stats を利用する(私的な New!!

上記の三パターンの中から docker stats とモニタ用コンテナについてメモる。


docker stats

Docker 1.5 から追加された機能docker stats という稼働中のコンテナリソースを top コマンドのような出力でリアルタイムに表示してくれるオプションを発見。今まで知らずにすいません...。

$ docker stats ${コンテナ名} ${コンテナ名}...

コマンドを実行すると以下のようにコンテナの CPU 使用率、メモリの使用量、ネットワーク I/O がリアルタイムに出力される。

f:id:inokara:20150804114311p:plain

また、コマンドオプションで --no-stream=true を渡すと docker stats 実行時点の結果が出力されてコマンドは終了する。

$ docker stats --no-stream=true dd-agent mackerel-agent
CONTAINER           CPU %               MEM USAGE/LIMIT     MEM %               NET I/O
dd-agent            11.49%              78.09 MB/3.955 GB   1.97%               2.479 MB/1.097 MB
mackerel-agent      0.22%               22.22 MB/3.955 GB   0.56%               255 kB/281.1 kB

これだけでも十分な気がしてきている...。

ちなみに...参考にしたドキュメントにて、

The docker stats reference page has more details about the docker stats command.

と書かれているので docker stats のリンクを踏んでもページが存在していないのはちょっと残念。

(追記)

Docker 1.8 がリリースされたことにより(だと思う)ドキュメントが追加されていた。

尚、

Note: If you want more detailed information about a container’s resource usage, use the API endpoint.

とあるので、詳細な情報が欲しい場合は API を叩く方が良いようだ。

モニタ用コンテナ

Agent が起動するコンテナでお手軽に

Datadog でも Mackrel でも各々のエージェントが docker run 時に起動するようなコンテナが配布されていてそれを使う。

Datadog Agent は以下のコンテナを利用する。

https://registry.hub.docker.com/u/datadog/docker-dd-agent/registry.hub.docker.com

コンテナ起動の方法は以下の通り。

# Amazon Linux はこちら
docker run -d \
  --name dd-agent \
  -h `hostname` \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v /proc/mounts:/host/proc/mounts:ro \
  -v /cgroup/:/host/sys/fs/cgroup:ro \
  -e API_KEY=${datadog-API-key} \
datadog/docker-dd-agent

# Ubuntu や CentOS 等はこちら
docker run -d \
  --name dd-agent \
  -h `hostname` \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v /proc/mounts:/host/proc/mounts:ro \
  -v /sys/fs/cgroup/:/host/sys/fs/cgroup:ro \
  -e API_KEY=${datadog-API-key} \
datadog/docker-dd-agent

OS によって cgroup のマウントポイントが異なるので注意する。

f:id:inokara:20150804122647p:plain

Mackerel Agent は以下のコンテナを利用する。

https://registry.hub.docker.com/u/mackerel/mackerel-agent/registry.hub.docker.com

コンテナ起動の方法は以下の通り。

docker run \
  -h `hostname` \
  --name=mackerel-agent \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v /var/lib/mackerel-agent/:/var/lib/mackerel-agent/ \
  -v /proc/mounts:/host/proc/mounts:ro \
  -v /sys/fs/cgroup/:/host/sys/fs/cgroup:ro \
  -e 'apikey=${mackerel-API-key}' \
mackerel/mackerel-agent

f:id:inokara:20150804122713p:plain

どちらとも API キーを用意しておいて -env オプションを利用してコンテナ起動時に API キーを渡すだけでコンテナとコンテナホストのモニタリングが始まる。

CPU やメモリ等は cgroup を利用する

以下のようにモニタ用コンテナ起動時に -env オプション以外に -v のボリュームオプションを利用してコンテナホストの /proc/mounts/sys/fs/cgroup/ 等をコンテナに起動しているのがミソ。また、/var/run/docker.sock もマウントしているのも醤油(ミソ→醤油の流れで)。

docker run -d \
  --name dd-agent \
  -h `hostname` \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v /proc/mounts:/host/proc/mounts:ro \
  -v /cgroup/:/host/sys/fs/cgroup:ro \
  -e API_KEY=${datadog-API-key} \
datadog/docker-dd-agent

まず /sys/fs/cgroup/ 以下の擬似ファイルを利用して CPU 使用率、メモリ使用量、ディスク I/O を監視出来るようになるようなので、Datadog Agent が動いているコンテナで確認してみる。

$ docker ps
CONTAINER ID        IMAGE                     COMMAND                CREATED             STATUS              PORTS               NAMES
6c5cb65060ab        datadog/docker-dd-agent   "/entrypoint.sh supe   12 hours ago        Up About an hour    8125/udp            dd-agent            
9c451a6a8b87        inokappa/mackerel-agent   "/startup.sh"          13 hours ago        Up About an hour                        mackerel-agen

CPU の使用率(消費されている CPU 時間)は cpuacct.stat という擬似ファイルで確認することが出来るとのことなので docker exec コマンドを利用して確認してみると以下のように出力された。尚、単位はナノ秒

$ docker exec dd-agent cat /host/sys/fs/cgroup/cpuacct/docker/cpuacct.stat                                                                                                                    
user 8710
system 7462
$ docker exec mackerel-agent cat /host/sys/fs/cgroup/cpuacct/docker/cpuacct.stat
user 8712
system 7466

また、cpuacct についてはこちらも見ておきたい。(個人的)

メモリの使用量は memory.stat という擬似ファイルで確認することが出来るようなので、同じく docker exec コマンドを利用して確認してみる。

$ docker exec dd-agent cat /host/sys/fs/cgroup/memory/docker/memory.stat
cache 0
rss 0
rss_huge 0
mapped_file 0
writeback 0
pgpgin 0
pgpgout 0
pgfault 0
pgmajfault 0
inactive_anon 0
active_anon 0
inactive_file 0
active_file 0
unevictable 0
hierarchical_memory_limit 18446744073709551615
total_cache 19574784
total_rss 37076992
total_rss_huge 4194304
total_mapped_file 6025216
total_writeback 0
total_pgpgin 896870
total_pgpgout 884061
total_pgfault 3186375
total_pgmajfault 3673
total_inactive_anon 20594688
total_active_anon 16470016
total_inactive_file 6139904
total_active_file 13430784
total_unevictable 0
$ docker exec mackerel-agent cat /host/sys/fs/cgroup/memory/docker/memory.stat
cache 0
rss 0
rss_huge 0
mapped_file 0
writeback 0
pgpgin 0
pgpgout 0
pgfault 0
pgmajfault 0
inactive_anon 0
active_anon 0
inactive_file 0
active_file 0
unevictable 0
hierarchical_memory_limit 18446744073709551615
total_cache 17657856
total_rss 37072896
total_rss_huge 4194304
total_mapped_file 5988352
total_writeback 0
total_pgpgin 899612
total_pgpgout 887272
total_pgfault 3198688
total_pgmajfault 3678
total_inactive_anon 18567168
total_active_anon 18497536
total_inactive_file 7438336
total_active_file 10211328
total_unevictable 0

コンテナの数等は...

同じコンテナホスト(コンテナインスタンス)で起動しているコンテナの情報を取得する為に /var/run/docker.sock もモニタ用コンテナにマウントしており、例えば mackerel-agent が動いているコンテナの場合に docker コマンドが使えるので以下のように確認出来る。

$ docker ps
CONTAINER ID        IMAGE                     COMMAND                CREATED             STATUS              PORTS               NAMES
6c5cb65060ab        datadog/docker-dd-agent   "/entrypoint.sh supe   13 hours ago        Up 2 hours          8125/udp            dd-agent            
9c451a6a8b87        inokappa/mackerel-agent   "/startup.sh"          13 hours ago        Up 2 hours                              mackerel-agent      

$ docker exec mackerel-agent docker ps
CONTAINER ID        IMAGE                     COMMAND                CREATED             STATUS              PORTS               NAMES
6c5cb65060ab        datadog/docker-dd-agent   "/entrypoint.sh supe   13 hours ago        Up 2 hours          8125/udp            dd-agent            
9c451a6a8b87        inokappa/mackerel-agent   "/startup.sh"          13 hours ago        Up 2 hours                              mackerel-agent

また、dd-agent が動いているコンテナの場合には以下のように確認することが出来た。(※事前に socat をコンテナにインストールする必要があるので docker build した)

$ docker exec dd-agent ls -l /var/run/docker.sock
srw-rw---- 1 root 999 0 Aug  4 01:57 /var/run/docker.sock

$ docker exec dd-agent echo -e "GET /containers/json HTTP/1.1\r\n" | socat unix-connect:/var/run/docker.sock STDIO
HTTP/1.1 200 OK
Content-Type: application/json
Date: Tue, 04 Aug 2015 04:41:33 GMT
Content-Length: 528

[{"Id":"d21cba68d204ffc41b091b7d29b81f1b831b2b0f208413ccc19a90695ff0867b","Names":["/dd-agent"],"Image":"inokappa/dd-agent","Command":"/entrypoint.sh supervisord -n -c /etc/dd-agent/supervisor.conf","Created":1438663170,"Ports":[{"PrivatePort":8125,"Type":"udp"}],"Labels":{},"Status":"Up 2 minutes"},{"Id":"9c451a6a8b870084e3a0a5ab6823c578bee29af954053fa88b4389b35cc4a8a6","Names":["/mackerel-agent"],"Image":"inokappa/mackerel-agent","Command":"/startup.sh","Created":1438612590,"Ports":[],"Labels":{},"Status":"Up 2 hours"}]

おお。


最後に

解ったこと

  • モニタ用コンテナがどんな風に各コンテナのモニタリングを行っているのか
  • cgroup のマウントがキモとなる、メトリクスと各コンテナの情報と関連付ける必要がある場合には /var/run/docker.sockもマウントしておく必要がある
  • CPU は cpuacct.stat を算出して利用、メモリは memory.statを利用、I/O については blkio-controller を利用する
  • ネットワーク監視はどうするんだろう...

引き続き調べたいこと

  • cgroup そのものについて(不勉強過ぎました...)
  • docker stats ではネットワークも監視出来ているけどどんな風に監視しているのか

ということで、引き続きメモって行く予定。