ざつくり本記事について説明するとcloudwatchとPrometheusエクスポータの連携についてです。
AWS ECSを監視する際にCloudWatch エージェントを使うことが多いと思うが、
CloudWatch エージェントで取得できるメトリクスは限られている。
CloudWatchエージェントで取得できるメトリクスはこちら。
そこで、Prometheusのエクスポーターを使ってCloudWatchにメトリクスを送ることにより、CloudWatchエージェントでは取得できないメトリクスについて取得・監視することが可能となる。
以下のような挙動になります。
- CloudWatchエージェントが監視対象のサーバを検出
- CloudWatchエージェントが監視対象サーバのメトリクスを取得
- 監視されるサーバにはPromethusエクスポーターを入れておく必要あり
- CloudWatchエージェントが取得したメトリクスをCloudWatchに送る
Prometheusとは??という方は以下の記事をご参照ください
Prometheusとはーシステム監視で利用できるPrometheusについてざっくり理解する
どんなAWSサービスを使うの?
- ECS-Fargate
- Cloud watch
Prometheus エクスポーターを使うとどんな感じになるの?
前準備:ECS-FargateにCloudWatchエージェントとPrometheusのエクスポータを入れておく
実際の動作:CloudWatchエージェントがPrometheusのエクスポータを叩き、結果をCloudWatchへ送る
ここら辺の話。
文字だけだとわかりづらいので、試しにapacheエクスポーターを使って実際の動作を確かめてみます。
apacheエクスポーターを使って実際に動作を確認
Dokerイメージの作成
以下のものをコンテナにインストールしてapacheエクスポーターの動きを見ていきます。
- apache
- CloudWatch agent
- Supervisord
- Prometheus exporter(apache exporter)
supervisordの設定ファイルの作成
「supervisord.conf」というファイル名で以下の内容のファイルを作成します
[supervisord] user = root nodaemon=true [program:apachectl] command=/usr/sbin/apache2ctl -DFOREGROUND [program:amazon-cloudwatch-agent] command=/opt/aws/amazon-cloudwatch-agent/bin/start-amazon-cloudwatch-agent [program:prometheus-apache-exporter] command=/usr/local/apache_exporter-0.7.0/apache_exporter
Dockerfileでインストールするものを起動するような設定となっています。
CloudWatchエージェントの設定ファイルの作成
「amazon-cloudwatch-agent.json」というファイル名で以下の内容のファイルを作成します
{
"logs": {
"metrics_collected": {
"prometheus": {
"prometheus_config_path": "/opt/aws/amazon-cloudwatch-agent/bin/prometheus.yaml",
"ecs_service_discovery": {
"sd_frequency": "1m",
"sd_result_file": "/tmp/cwagent_ecs_auto_sd.yaml",
"task_definition_list": [
{
"sd_metrics_ports": "9117",
"sd_task_definition_arn_pattern": ".*:task-definition/.*prometheus.*",
"sd_metrics_path": "/metrics"
}
]
},
"emf_processor": {
"metric_declaration": [
{
"source_labels": ["container_name"],
"label_matcher": "^cloudwatch-agent-prometheus$",
"dimensions": [["ClusterName"]],
"metric_selectors": [
"^apache_accesses_total$"
]
}
]
}
}
},
"force_flush_interval": 5
}
}
task_definition_list内の条件に合致するメトリクス取得対象を自動検出して「/tmp/cwagent_ecs_auto_sd.yaml」に吐き出す。
metric_declaration内の条件でCloudWatchにメトリクスを送る
Prometheusの設定
「prometheus.yaml」というファイル名で以下の内容のファイルを作成します
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: cwagent-ecs-file-sd-config
sample_limit: 10000
file_sd_configs:
- files: [ "/tmp/cwagent_ecs_auto_sd.yaml" ]
「/tmp/cwagent_ecs_auto_sd.yaml」内の情報で15秒間隔でメトリクスを取得するよってこと
Dockerfileの中身
「Dockerfile」というファイル名で以下の内容のファイルを作成します
FROM ubuntu ENV DEBIAN_FRONTEND noninteractive # curlインストール RUN apt-get update \ && apt-get install -y curl # Apacheインストール RUN apt-get install -y apache2 # CloudWatchエージェントインストール RUN curl -Lo amazon-cloudwatch-agent.deb https://s3.amazonaws.com/amazoncloudwatch-agent/ubuntu/amd64/latest/amazon-cloudwatch-agent.deb RUN dpkg -i -E ./amazon-cloudwatch-agent.deb COPY amazon-cloudwatch-agent.json /opt/aws/amazon-cloudwatch-agent/bin/default_linux_config.json ENV RUN_IN_CONTAINER=True # Supervisorインストール RUN apt-get install -y supervisor COPY ./supervisord.conf /etc/ #prometheus関連 COPY ./prometheus.yaml /opt/aws/amazon-cloudwatch-agent/bin/prometheus.yaml RUN curl -Lo apache_exporter-0.7.0.linux-amd64.tar.gz https://github.com/Lusitaniae/apache_exporter/releases/download/v0.7.0/apache_exporter-0.7.0.linux-amd64.tar.gz RUN tar zxvf apache_exporter-0.7.0.linux-amd64.tar.gz RUN mv -i apache_exporter-0.7.0.linux-amd64 /usr/local/apache_exporter-0.7.0 WORKDIR /usr/local/ RUN ln -s apache_exporter-0.7.0 apache_exporter EXPOSE 80 9117 # 起動 CMD /usr/bin/supervisord -c /etc/supervisord.conf
「RUN_IN_CONTAINER=True」を記載しないとコンテナでCloudWatchエージェントが動かないので要注意です。
Dockerイメージのビルド
Dockerイメージを以下のコマンドでビルドします。
docker build -t prometheustest/prometheustest:latest .
Amazon Elastic Container Registryへイメージをプッシュ
作成したイメージはAmazon Elastic Container Registryへイメージをプッシュしておきます
コンテナの起動
ロールの作成
以下のポリシーを持ったロールを作成する
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"ecs:DescribeTasks",
"ecs:ListTasks",
"ecs:DescribeContainerInstances"
],
"Resource": "*",
"Effect": "Allow"
},
{
"Effect": "Allow",
"Action": [
"cloudwatch:PutMetricData",
"ec2:DescribeVolumes",
"ec2:DescribeTags",
"logs:PutLogEvents",
"logs:DescribeLogStreams",
"logs:DescribeLogGroups",
"logs:CreateLogStream",
"logs:CreateLogGroup"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"ssm:GetParameter"
],
"Resource": "arn:aws:ssm:*:*:parameter/AmazonCloudWatch-*"
}
]
}コンテナ起動
- ECSコンソール画面から「クラスターの作成」ボタンを押下してクラスターを作成する。設定値は以下を参照。
- クラスター名:prometheus-test
- 上記以外はデフォルトのまま
- ECSコンソール画面からタスク定義を選択後に「新しいタスク定義の作成」ボタンを押下してタスク定義を作成する。設定値は以下を参照。
- タスク定義ファミリー:ecs-prometheus-test
- コンテナ:イメージURIにElastic Container RegistryのURIを設定
- タスクロール:先ほど「ロール作成」で作成したロールを指定
- タスク実行ロール:先ほど「ロール作成」で作成したロールを指定
- 上記以外はデフォルトのまま
- ECSコンソール画面から作成したクラスターを選択し、タスクタブを選択し、「新しいタスクの実行」ボタンを押下して、コンテナを起動する
- タスク定義:先ほど作成したタスク定義
- 必要なタスク:1
- セキュリティグループ:ポート「9117」を許可
- 上記以外はデフォルトのまま
Prometheus エクスポーターでCloudWatchにメトリクスを送った結果

複数のコンテナが立ち上がってる場合、「/tmp/cwagent_ecs_auto_sd.yaml」に複数コンテナの情報が書き込まれ、立ち上がってる分だけのコンテナの情報を収集するので、CloudWatchエージェント用のコンテナを立てるのが普通?
ちなみに、、自身のコンテナの情報だけをCloudWatchへ送る方法もある。この場合、CloudWatchエージェント用のコンテナは不要。やり方は↓↓↓↓↓↓↓↓↓↓↓
Prometheus エクスポーターでコンテナローカルのメトリクス 取得ver.
コンテナローカルのメトリクス 取得ver.
コンテナの自動検出機能を使わないと↓こんな感じ↓になる
amazon-cloudwatch-agent.json(コンテナローカルのメトリクス 取得ver.)
{
"logs": {
"metrics_collected": {
"prometheus": {
"prometheus_config_path": "/opt/aws/amazon-cloudwatch-agent/bin/prometheus.yaml",
"emf_processor": {
"metric_declaration": [
{
"source_labels": ["ClusterName"],
"label_matcher": "*",
"dimensions": [["ClusterName","job"]],
"metric_selectors": [
"^apache_accesses_total$"
]
}
]
}
}
},
"force_flush_interval": 5
}
}
prometheus.yaml(コンテナローカルのメトリクス 取得ver.)
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: 'apache'
static_configs:
- targets: ['localhost:9117']


