ざつくり本記事について説明すると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']