ECSのタスク単位のリソースをDatadogでモニタリングする

CloudWatchでは、ECSのクラスタインスタンス単位やサービス単位でのメトリクスはサポートされているのですが、タスク単位のメトリクスがサポートされていません。今回は、docker-dd-agentを用いて、Datadogでタスク単位のリソース状況をモニタリングできるようにしました。

構成としては、各クラスタインスタンスに docker-dd-agent タスクが1つ常駐し、そのタスクがクラスタインスタンスの内部の情報を収集し、Datadogに送信するという方式になります。

公式の手順は以下にあります。

Datadog-AWS ECS Integration

前提

前提として、ECSは構築済みで、DatadogとAWSのIntegrationがされている状態とします。

1.Task Difinitionを作成する

まずはじめに、ECSに docker-dd-agent の Task Difinition を作成します。

dd-agent-ecs.json をダウンロードします。ダウンロードした dd-agent-ecs.jsontaskDefinition.containerDefinitions.environment[] を以下の通り変更・追加します。

  • API_KEY(変更): Datadog の Integrations > APIs で作成した API Key を設定します。
  • NON_LOCAL_TRAFFIC(追加): false を設定します。1
  • TAGS(追加): 必要に応じてタグを追加します。必要なければ設定しなくても問題ありません。

dd-agent-ecs.json の編集が完了したら、AWS CLIにて Task Difinition を作成します。

aws ecs register-task-definition --cli-input-json file://dd-agent-ecs.json

2.IAM Policyを追加する

次に、ECSのクラスタインスタンスのRoleに必要なPolicyを追加します。これは、次のステップで行う クラスタインスタンスの起動時に、自身のインスタンスに docker-dd-agent タスクを起動する ために必要なPolicyです。

ECSのクラスタインスタンスのRoleに、以下のPolicyを追加します。

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ecs:RegisterContainerInstance",
"ecs:DeregisterContainerInstance",
"ecs:DiscoverPollEndpoint",
"ecs:Submit*",
"ecs:Poll",
"ecs:StartTask",
"ecs:StartTelemetrySession"
],
"Resource": [
"*"
]
}
]
}

3.ユーザデータにスクリプトを追加する

公式の手順では、一番シンプルな例として、いちからEC2を作成する手順が紹介されています。通常はECSのクラスタインスタンスはAutoScalingが設定されていると思いますので、AutoScalingの起動設定のユーザーデータに設定すると良いでしょう。

以下のスクリプトをユーザーデータに追加します。

#!/bin/bash
cluster="cluster_name"
task_def="dd-agent-task"
echo ECS_CLUSTER=$cluster >> /etc/ecs/ecs.config
start ecs
yum install -y aws-cli jq
instance_arn=$(curl -s http://localhost:51678/v1/metadata | jq -r '. | .ContainerInstanceArn' | awk -F/ '{print $NF}' )
az=$(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone)
region=${az:0:${#az} - 1}
echo "cluster=$cluster az=$az region=$region aws ecs start-task --cluster \
$cluster --task-definition $task_def --container-instances $instance_arn --region $region" >> /etc/rc.local

必要な情報をクラスタインスタンス内部のmetadataから収集し、aws ecs start-taskコマンドを組み立て、/etc/rc.localに追記しています。これにより、インスタンスの起動完了後に自身のインスタンスに docker-dd-agent タスクを起動させます。

4.Datadogの設定

ここまで設定を終えると、Datadogに docker.* のメトリックが追加されます。aws.ecs.service.*ではないのでご注意ください。

参照できるメトリックの一覧です。

docker.containers.running
docker.containers.running.total
docker.containers.stopped
docker.containers.stopped.total
docker.cpu.system
docker.cpu.throttled
docker.cpu.usage
docker.cpu.user
docker.io.read_bytes
docker.io.write_bytes
docker.mem.cache
docker.mem.in_use
docker.mem.limit
docker.mem.rss
docker.mem.soft_limit
docker.mem.sw_in_use
docker.mem.sw_limit
docker.mem.swap
docker.net.bytes_rcvd
docker.net.bytes_sent

Datadogのメトリクスの設定例です。

タスク単位でメモリ使用率が参照できていることがわかります。


[2017/12/15] 追記

Datadogのモニタリング機能の1つに、ライブコンテナ モニタリングという機能があることを知りました。dd-agentから送られるメトリクスを、この画面で一覧できるようです。すごいです。

アクセス方法が少しわかりにくかったんですが、Datadogコンソールの左メニューから、Infrastructure > Containers で開けます。

終わりに

これでタスク単位でリソース状況をモニタリングできるようになりました。ところで最近発表されたAWS Fargateを使うと、タスク単位のメトリクスはどう取れるのでしょうか。追って調査したいと思います。


  1. この項目は公式の手順にはありませんが、docker-dd-agentのサンプルではfalseが設定されています。ローカルアドレス向け以外(他のコンテナ)のネットワークトラフィックも収集したい場合は、falseにすると良いようです。デフォルトはtrueです。