DatadogでECSを監視する
AWSのECSで動かしているコンテナを、Datadogで監視する方法です。
こちらは、公式のマニュアル。
Amazon Elastic Container Service (ECS)
こちらは、公式の紹介ブログ。
Monitoring ECS with Datadog | Datadog
前提
- ECS Container Instanceが存在
- Datadogには、AWSのIntegrationをインストール済
作業
監視する方法ですが、DockerHubにて公開しているdatadog-agentのコンテナイメージを、ECS上で動かせということらしいです。
タスク定義作成
タスク定義作成用のjsonがDatadogマニュアルで公開されており参考になります。
https://docs.datadoghq.com/json/datadog-agent-ecs.json
下記のjsonのタスク定義にて、以下のデータを収集できるようになります。
- Data Collection
- ECSで用意されているメトリクスを収集してきてくれる
- Process Collection
- コンテナ上で動作しているプロセス一覧を収集してきてくれる
環境変数 DD_API_KEY
に、利用するDatadogのAPI KEYを登録しておきます。
{ "containerDefinitions": [ { "name": "datadog-agent", "image": "datadog/agent:latest", "cpu": 10, "memory": 256, "essential": true, "mountPoints": [ { "containerPath": "/var/run/docker.sock", "sourceVolume": "docker_sock", "readOnly": true }, { "containerPath": "/host/sys/fs/cgroup", "sourceVolume": "cgroup", "readOnly": true }, { "containerPath": "/host/proc", "sourceVolume": "proc", "readOnly": true }, { "containerPath": "/etc/passwd", "sourceVolume": "passwd", "readOnly": true } ], "environment": [ { "name": "DD_API_KEY", "value": "<APIKEY>" }, { "name": "DD_SITE", "value": "datadoghq.com" }, { "name": "DD_PROCESS_AGENT_ENABLED", "value": "true" } ] } ], "volumes": [ { "host": { "sourcePath": "/var/run/docker.sock" }, "name": "docker_sock" }, { "host": { "sourcePath": "/proc/" }, "name": "proc" }, { "host": { "sourcePath": "/sys/fs/cgroup/" }, "name": "cgroup" }, { "host": { "sourcePath": "/etc/passwd" }, "name": "passwd" } ], "family": "datadog-agent-task" }
上記のjsonでは Log Collection
の設定は実施していません。ECSでもログをCloudwatch Logsに連携できるようになったので、CloudwarhcLogsのログをDatadogで連携することで、監視を実現します。
IAMユーザの用意
ECS Task Roleで、以下のIAMポリシーを許可する必要があります。
- ecs:ListClusters
- ecs:ListContainerInstances
- ecs:DescribeContainerInstances
サービス定義作成
作成したタスク定義を、各Container Instance上で起動させます。サービスタイプを DAEMON
とすることで、各Container Instance上で1台ずつ動いてくれるようになります。
以上の作業を実施することで、Datadog上に各種メトリクスとコンテナ上のプロセス情報を収集できるようになります。
CloudFormation
上記をまとめて実行してくれるCloudFormationを置いておきます。
cloudformation/ecs-datadog-agent at master · goodbyegangster/cloudformation · GitHub
参考
そもそも、Datadog Agentはどうやって他のContainerの情報を収集しているのか分からなかったので、調べてみました。
Datadog Agentのタスク定義では、以下のECS Container Instance(Docker Host)上のパスをマウントしているので、それぞれがどういった役割を持っているのか調べてみます。
- DataCollection
- /var/run/docker.sock
- /sys/fs/cgroup/
- /proc/
- ProcessCollection
- /etc/passwd
/var/run/docker.sock
ファイル名からして、Docker用に用意されているソケットであることは分かりますね。恐らくこのソケットで用意されたAPI経由で、色々な情報をDatadog Agentが拾ってきているのだろうと予想できます。
Docker-machineにsshログインして、実際にdocker.sockのAPIを叩いてみると、情報を取得できます。docker.sockのソケットの裏側では、HTTPサーバが待っているそうなので、こんな感じでアクセスできます。
docker@default:~$ curl --unix-socket /var/run/docker.sock http://docker/containers/json [ { "Id": "f6975b30286b3af66f4f8f97dc90a37d3dc6be22aae6a04c87c0936b247ebe65", "Names": [ "/test" ], "Image": "redis:latest", (略) } ]
/sys/fs/cgroup/
そもそもこいつは、
cgroupは2006年9月にGoogleのエンジニアによって最初のパッチが投稿され,2.6.24カーネルで最初のマージがなされた機能です。
cgroupは"Control Group"の略です。プロセスをグループ化して,そのグループ内に存在するプロセスに対して共通の管理を行うために使います。たとえば,ホストOSが持つCPUやメモリなどのリソースに対して,グループごとに制限をかけることができます。
コンテナはプロセスを隔離空間に入れることによって作成しますので,コンテナ内に入っているプロセスの集合に対してまとめてリソース制限をかける必要のある場面は多く,このような場面にcgroupが使えます。cgroupを使って,あるコンテナがホストOSの持つ有限なリソースを使いつくして,ホストOS上のプロセスや他のコンテナに影響を与えないようにできます。
第3回 Linuxカーネルのコンテナ機能[2] ─cgroupとは?(その1):LXCで学ぶコンテナ入門 -軽量仮想化環境を実現する技術|gihyo.jp … 技術評論社
実際にdocker-machine上のcgroup配下を調べてみると、コンテナ単位でcpuやmemoryのスタッツ情報を拾ってこれます。
docker@default:~$ cat /sys/fs/cgroup/memory/docker/f6975b30286b3af66f4f8f97dc90a37d3dc6be22aae6a04c87c0936b247ebe65/memory.stat cache 7368704 rss 1146880 rss_huge 0 shmem 0 mapped_file 3223552 dirty 0 writeback 0 swap 0 pgpgin 4692 pgpgout 2613 pgfault 1726 pgmajfault 61 inactive_anon 0 active_anon 1146880 inactive_file 4612096 active_file 2756608 unevictable 0 hierarchical_memory_limit 9223372036854771712 hierarchical_memsw_limit 9223372036854771712 total_cache 7368704 total_rss 1146880 total_rss_huge 0 total_shmem 0 total_mapped_file 3223552 total_dirty 0 total_writeback 0 total_swap 0 total_pgpgin 4692 total_pgpgout 2613 total_pgfault 1726 total_pgmajfault 61 total_inactive_anon 0 total_active_anon 1146880 total_inactive_file 4612096 total_active_file 2756608 total_unevictable 0
/proc/
DockerとはコンテナにてLinuxカーネルを共有する技術である、という事なので、Docker-machine上の /proc
を見に行けば、そこにはコンテナ上のリソース情報があり、そこから何でも拾ってこれるよね、という話だと思っています。
コンテナのPIDは、以下のコマンドにて確認できます。
docker@default:~$ docker ps -q | xargs -n1 docker top UID PID PPID C STIME TTY TIME CMD 999 3093 3072 0 22:25 ? 00:00:04 redis-server *:6379
このPIDディレクトリ配下のstatを見に行くと、該当コンテナでのプロセス情報を取得できます。
docker@default:~$ cat /proc/3093/stat 3093 (redis-server) S 3072 3093 3093 0 -1 4210944 1197 313 44 17 203 220 0 0 20 0 4 0 531327 51494912 1039 18446744073709551615 1 1 0 0 0 0 0 4097 17610 0 0 0 17 0 0 0 5 0 0 0 0 0 0 0 0 0 0
/etc/passwd
OSのパスワードファイル。DatadogのProcessCollectionにて、どうしてパスワードファイルを参照する必要あるのか、Datadog Agentのソースコード見てみないと予想もできず、僕には分からなかったです。