はじめに
ECS 上に Prometheus、Thanos、snmp-exporter を 1 つのタスクとして起動します。
-
prometheus: メトリクスを収集する -
thanos-sidecar: Prometheus のデータを S3 にアップロードし、Thanos Query から参照できるようにする -
thanos-store: S3 上の Thanos ブロックを参照する -
thanos-query: Prometheus と Thanos Store を横断してクエリする -
snmp-exporter: SNMP 対応機器からメトリクスを取得する
この記事では、AWS マネジメントコンソールで入力できる形を優先して手順を書きます。CLI や CDK は使いません。
なお、この構成では EFS は使いません。設定ファイルは S3 Files ボリュームからマウントします。
構成
SNMP機器
|
| UDP/161
v
ECS Task
|
|-- prometheus:9090
| | scrape
| v
|-- snmp-exporter:9116
|
|-- thanos-sidecar:10901,10902
|
| upload blocks
v
S3 Bucket
|
|-- thanos-store:10911,10912
|
|-- thanos-query:9091,10921
設定ファイル: S3 Filesからマウント
同じ ECS タスク内のコンテナは awsvpc ネットワークモードで localhost 通信できます。そのため、Prometheus から snmp-exporter と Thanos Sidecar へは localhost で接続します。
前提
- 既存の VPC、Public または Private Subnet がある
- ECS でタスクを起動する
- 設定ファイル配置先として S3 Files を使う
- Thanos のオブジェクトストレージとして S3 を使う
- この記事では Thanos Query UI だけを ALB 経由で確認する構成にする
作成するリソース
| 種別 | 名前の例 | 用途 |
|---|---|---|
| S3 バケット | thanos-metrics-bucket |
Thanos のブロック保存先 |
| S3 Files | fs-xxxxxxxxxxxxxxxxx |
Prometheus、Thanos、snmp-exporter の設定ファイル配置 |
| IAM Role | ecsTaskExecutionRole |
ECS がイメージ取得やログ出力を行うためのロール |
| IAM Role | ecsTaskRoleThanos |
コンテナが S3 と S3 Files を利用するためのロール |
| CloudWatch Logs | /ecs/prometheus-thanos |
コンテナログ |
| ECS Cluster | monitoring-cluster |
ECS サービスの実行先 |
| ECS Task Definition | prometheus-thanos |
コンテナ定義 |
| ECS Service | prometheus-thanos-service |
タスクの常時起動 |
1. S3 バケットを作成する
AWS マネジメントコンソールで S3 を開きます。
-
バケットを作成を選択 -
バケット名に任意の名前を入力- 例:
thanos-metrics-bucket
- 例:
-
AWS リージョンは ECS を起動するリージョンと同じにする -
パブリックアクセスをすべてブロックは有効のまま -
バケットのバージョニングは有効にする- S3 Files は同期のために S3 Versioning が必須
-
デフォルトの暗号化は有効-
Amazon S3 マネージドキー (SSE-S3)でよい
-
-
バケットを作成を選択
この記事では以降、次の値を使います。
S3_BUCKET_NAME=thanos-metrics-bucket
AWS_REGION=ap-northeast-1
自分の環境に合わせて読み替えてください。
2. S3 Files を用意する
この構成では EFS ではなく、ECS タスク定義の s3filesVolumeConfiguration を使って設定ファイルをコンテナにマウントします。
S3 コンソールで File systems を開き、S3 Files ファイルシステムを作成します。
作成後、ファイルシステム ARN を控えます。
S3_FILES_ARN=arn:aws:s3files:ap-northeast-1:123456789012:file-system/fs-xxxxxxxxxxxxxxxxx
タスク定義 prometheus-thanos では、同じ S3 Files を root directory ごとに分けてマウントします。
| ボリューム名 | root directory | コンテナ側パス | 用途 |
|---|---|---|---|
prometheus-config |
/prometheus |
/etc/prometheus |
prometheus.yml |
thanos-config |
/thanos |
/etc/thanos |
objstore.yml |
snmp-exporter-config |
/snmp-exporter |
/etc/snmp_exporter |
snmp.yml |
S3 Files は、ECS タスクと同じ VPC から到達できる必要があります。S3 Files のマウントターゲット、Subnet、Security Group を ECS タスクの配置先と合わせてください。
2.1 設定ファイルを配置する
S3 Files の backing bucket 側に、以下のファイルを配置します。
/prometheus/prometheus.yml
global:
scrape_interval: 30s
evaluation_interval: 30s
scrape_configs:
- job_name: prometheus
static_configs:
- targets:
- 127.0.0.1:9090
- job_name: snmp
metrics_path: /snmp
params:
module:
- if_mib
static_configs:
- targets:
- 192.0.2.10
relabel_configs:
- source_labels: [__address__]
target_label: __param_target
- source_labels: [__param_target]
target_label: instance
- target_label: __address__
replacement: 127.0.0.1:9116
192.0.2.10 は SNMP 対象機器の IP アドレスに置き換えてください。
/thanos/objstore.yml
type: S3
config:
bucket: thanos-metrics-bucket
endpoint: s3.ap-northeast-1.amazonaws.com
region: ap-northeast-1
aws_sdk_auth: true
アクセスキーはファイルに書きません。ECS タスクロールで S3 にアクセスします。
/snmp-exporter/snmp.yml
実機のコミュニティ名や SNMPv3 認証に合わせて変更してください。
auths:
public_v2:
version: 2
community: public
modules:
if_mib:
walk:
- 1.3.6.1.2.1.2
- 1.3.6.1.2.1.31.1.1
auth:
community: public
3. Security Group を作成する
3.1 ECS タスク用 Security Group
EC2 コンソールから セキュリティグループ を開き、以下を作成します。
名前: sg-ecs-prometheus-thanos
説明: ECS prometheus-thanos task security group
VPC: ECSを起動するVPC
インバウンドルールの例です。
| タイプ | プロトコル | ポート | ソース | 用途 |
|---|---|---|---|---|
| カスタム TCP | TCP | 9091 | 自分のIP、VPN CIDR、またはALBのSecurity Group | Thanos Query UI |
| カスタム TCP | TCP | 10902 | 管理用CIDR | Thanos Sidecar HTTP |
| カスタム TCP | TCP | 10912 | 管理用CIDR | Thanos Store HTTP |
Prometheus の 9090、snmp-exporter の 9116、Thanos gRPC の 10901、10911、10921 は同一タスク内から localhost でアクセスするため、外部公開は不要です。Prometheus UI を一時的に確認したい場合だけ、内部ネットワークや踏み台経由で到達できるようにします。
アウトバウンドルールは以下のようにします。
| タイプ | プロトコル | ポート | 宛先 | 用途 |
|---|---|---|---|---|
| HTTPS | TCP | 443 |
0.0.0.0/0 または VPC Endpoint |
ECR、S3、CloudWatch Logs |
| カスタム UDP | UDP | 161 | SNMP機器のIP/CIDR | SNMP取得 |
| NFS | TCP | 2049 | S3 Files のSecurity Group | 設定ファイルマウント |
Private Subnet で NAT Gateway を使わない場合は、ECR、S3、CloudWatch Logs の VPC Endpoint を用意してください。
3.2 S3 Files 用 Security Group
S3 Files のマウントターゲットに設定する Security Group では、ECS タスク用 Security Group から TCP 2049 の通信を許可します。
4. IAM ロールを作成する
4.1 ECS タスク実行ロール
IAM コンソールで ロールを作成 を選択します。
信頼されたエンティティタイプ: AWS のサービス
ユースケース: Elastic Container Service
ユースケース詳細: Elastic Container Service Task
許可ポリシーに以下を付与します。
AmazonECSTaskExecutionRolePolicy
ロール名は以下にします。
ecsTaskExecutionRole
4.2 ECS タスクロール
同じく IAM でロールを作成します。
信頼されたエンティティタイプ: AWS のサービス
ユースケース: Elastic Container Service
ユースケース詳細: Elastic Container Service Task
ロール名: ecsTaskRoleThanos
インラインポリシーとして以下を追加します。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowThanosS3Access",
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject"
],
"Resource": [
"arn:aws:s3:::thanos-metrics-bucket",
"arn:aws:s3:::thanos-metrics-bucket/*"
]
}
]
}
thanos-metrics-bucket は自分の S3 バケット名に置き換えてください。
5. CloudWatch Logs のロググループを作成する
CloudWatch コンソールで ロググループ を開きます。
-
ロググループを作成を選択 -
ロググループ名に以下を入力
/ecs/prometheus-thanos
- 保持期間を選択
- 例:
30日
- 例:
-
作成を選択
6. ECS クラスターを作成する
ECS コンソールで クラスター を開きます。
-
クラスターの作成を選択 -
クラスター名にmonitoring-clusterを入力 -
インフラストラクチャはクラスターで使う capacity provider に合わせて選択 -
作成を選択
7. ECS タスク定義を作成する
ECS コンソールで タスク定義 を開きます。
-
新しいタスク定義の作成を選択 -
新しい ECS タスク定義エクスペリエンスで作成する -
インフラストラクチャの要件、ストレージ、コンテナを以下の値で入力する
7.1 基本設定
| 画面項目 | 入力値 |
|---|---|
| タスク定義ファミリー | prometheus-thanos |
| タスク定義の互換性 | AWS Fargate |
| オペレーティングシステム/アーキテクチャ | Linux/X86_64 |
| ネットワークモード | awsvpc |
| タスクサイズ CPU | 1 vCPU |
| タスクサイズ メモリ | 2 GB |
| タスクロール | ecsTaskRoleThanos |
| タスク実行ロール | ecsTaskExecutionRole |
7.2 ボリューム
ストレージ で以下のボリュームを追加します。S3 Files は ファイルシステム ARN を手入力するのではなく、画面の ファイルシステム プルダウンで作成済みの fs-... を選択します。
| ボリューム名 | 設定タイプ | ボリュームタイプ | ファイルシステム | アクセスポイント | ルートディレクトリ |
|---|---|---|---|---|---|
prometheus-data |
タスク定義の作成時に設定 |
バインドマウント |
なし | なし | なし |
prometheus-config |
タスク定義の作成時に設定 |
S3 Files |
fs-xxxxxxxxxxxxxxxxx |
選択しない | /prometheus |
thanos-config |
タスク定義の作成時に設定 |
S3 Files |
fs-xxxxxxxxxxxxxxxxx |
選択しない | /thanos |
snmp-exporter-config |
タスク定義の作成時に設定 |
S3 Files |
fs-xxxxxxxxxxxxxxxxx |
選択しない | /snmp-exporter |
fs-xxxxxxxxxxxxxxxxx は、作成した S3 Files のファイルシステム ID に置き換えてください。アクセスポイントを使わない場合は、アクセスポイント は空のままにします。
7.3 コンテナ: prometheus
| 画面項目 | 入力値 |
|---|---|
| 名前 | prometheus |
| イメージ URI | 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/prometheus:v3.11.3 |
| 必須コンテナ | 有効 |
| コンテナポート | 9090 |
| プロトコル | TCP |
| ポート名 | prometheus-9090-tcp |
| アプリケーションプロトコル | HTTP |
| コマンド | --config.file=/etc/prometheus/prometheus.yml,--storage.tsdb.path=/prometheus,--storage.tsdb.retention.time=24h,--storage.tsdb.min-block-duration=2h,--storage.tsdb.max-block-duration=2h,--web.enable-lifecycle |
| ログドライバー | awslogs |
| ロググループ | /ecs/prometheus-thanos |
| リージョン | ap-northeast-1 |
| ストリームプレフィックス | ecs |
| ロググループ自動作成 | 有効 |
マウントポイントは以下を追加します。
| ソースボリューム | コンテナパス | 読み取り専用 |
|---|---|---|
prometheus-config |
/etc/prometheus |
無効 |
prometheus-data |
/prometheus |
無効 |
7.4 コンテナ: thanos-sidecar
| 画面項目 | 入力値 |
|---|---|
| 名前 | thanos-sidecar |
| イメージ URI | 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/thanos:v0.41.0 |
| 必須コンテナ | 有効 |
| コンテナポート 1 |
10901 / TCP / thanos-sidecar-10901-tcp
|
| コンテナポート 2 |
10902 / TCP / thanos-sidecar-10902-tcp
|
| コマンド | sidecar,--tsdb.path=/prometheus,--prometheus.url=http://127.0.0.1:9090,--objstore.config-file=/etc/thanos/objstore.yml,--http-address=0.0.0.0:10902,--grpc-address=0.0.0.0:10901 |
| ログドライバー | awslogs |
| ロググループ | /ecs/prometheus-thanos |
| リージョン | ap-northeast-1 |
| ストリームプレフィックス | ecs |
| ロググループ自動作成 | 有効 |
マウントポイントは以下を追加します。
| ソースボリューム | コンテナパス | 読み取り専用 |
|---|---|---|
thanos-config |
/etc/thanos |
無効 |
prometheus-data |
/prometheus |
無効 |
7.5 コンテナ: thanos-store
| 画面項目 | 入力値 |
|---|---|
| 名前 | thanos-store |
| イメージ URI | 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/thanos:v0.41.0 |
| 必須コンテナ | 有効 |
| コンテナポート 1 |
10911 / TCP / thanos-store-10911-tcp
|
| コンテナポート 2 |
10912 / TCP / thanos-store-10912-tcp
|
| コマンド | store,--objstore.config-file=/etc/thanos/objstore.yml,--data-dir=/tmp/thanos/store,--http-address=0.0.0.0:10912,--grpc-address=0.0.0.0:10911 |
| ログドライバー | awslogs |
| ロググループ | /ecs/prometheus-thanos |
| リージョン | ap-northeast-1 |
| ストリームプレフィックス | ecs |
| ロググループ自動作成 | 有効 |
マウントポイントは以下を追加します。
| ソースボリューム | コンテナパス | 読み取り専用 |
|---|---|---|
thanos-config |
/etc/thanos |
無効 |
7.6 コンテナ: thanos-query
| 画面項目 | 入力値 |
|---|---|
| 名前 | thanos-query |
| イメージ URI | 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/thanos:v0.41.0 |
| 必須コンテナ | 有効 |
| コンテナポート 1 |
9091 / TCP / thanos-query-9091-tcp / HTTP
|
| コンテナポート 2 |
10921 / TCP / thanos-query-10921-tcp
|
| コマンド | query,--http-address=0.0.0.0:9091,--grpc-address=0.0.0.0:10921,--endpoint=127.0.0.1:10901,--endpoint=127.0.0.1:10911 |
| ログドライバー | awslogs |
| ロググループ | /ecs/prometheus-thanos |
| リージョン | ap-northeast-1 |
| ストリームプレフィックス | ecs |
| ロググループ自動作成 | 有効 |
7.7 コンテナ: snmp-exporter
| 画面項目 | 入力値 |
|---|---|
| 名前 | snmp-exporter |
| イメージ URI | 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/snmp-exporter:v0.30.1 |
| 必須コンテナ | 有効 |
| コンテナポート | 9116 |
| プロトコル | TCP |
| ポート名 | snmp-exporter-9116-tcp |
| コマンド | --config.file=/etc/snmp_exporter/snmp.yml |
マウントポイントは以下を追加します。
| ソースボリューム | コンテナパス | 読み取り専用 |
|---|---|---|
snmp-exporter-config |
/etc/snmp_exporter |
無効 |
7.8 変更が必要な値
| 項目 | 変更例 |
|---|---|
| AWS アカウント ID |
123456789012 を自分のアカウント ID に置き換える |
| ECR イメージ URI | 自分の ECR リポジトリ URI に置き換える |
| S3 Files ARN | 作成した S3 Files の ARN に置き換える |
| リージョン |
ap-northeast-1 を利用リージョンに置き換える |
/thanos/objstore.yml |
Thanos 用 S3 バケット名、リージョンを変更する |
/prometheus/prometheus.yml |
SNMP 機器の IP アドレスを変更する |
SNMP 機器が複数ある場合は、Prometheus 設定の targets を増やします。
static_configs:
- targets:
- 192.0.2.10
- 192.0.2.11
- 192.0.2.12
8. ECS サービスを作成する
ECS コンソールで クラスター から monitoring-cluster を開きます。
-
サービスタブを開く -
作成を選択 -
コンピューティングオプションはキャパシティープロバイダー戦略 - キャパシティープロバイダーはクラスターで利用しているものを選択
- 例:
my-cluster-capacity-provider
- 例:
-
ベースは0、ウェイトは1 -
アプリケーションタイプはサービス -
ファミリーはprometheus-thanos -
リビジョンは最新 -
サービス名はprometheus-thanos-service -
必要なタスクは1 -
デプロイオプションはデフォルトでよい
ネットワーク設定は以下のようにします。
VPC: クラスターとS3 Filesに到達できるVPC
サブネット: S3 Files に到達できるSubnet
セキュリティグループ: sg-ecs-prometheus-thanos
パブリックIP: 無効
ロードバランサーは Thanos Query の 9091 をターゲットグループに紐づけます。
ターゲットグループ: tg-thanos-query
コンテナ: thanos-query
コンテナポート: 9091
Prometheus の 9090 は、このサービス設定ではロードバランサーに紐づけていません。Thanos Query から Thanos Sidecar と Thanos Store へは同一タスク内の 127.0.0.1 で接続します。
最後に 作成 を選択します。
9. 起動確認
ECS サービスの画面で タスク タブを開き、タスクが 実行中 になっていることを確認します。
9.1 コンテナログを確認
CloudWatch Logs の /ecs/prometheus-thanos を開きます。
以下のログストリームが出ていれば起動しています。
ecs/prometheus/<task-id>
ecs/thanos-sidecar/<task-id>
ecs/thanos-store/<task-id>
ecs/thanos-query/<task-id>
Prometheus 側で設定エラーがある場合は、prometheus.yml の YAML インデントや SNMP ターゲットの IP を確認します。
9.2 Prometheus の scrape 状態を確認
このサービス設定では、ロードバランサーに公開しているのは Thanos Query の 9091 だけです。Prometheus の 9090 は ALB に紐づけていないため、ブラウザから直接確認する場合は、内部ネットワークからアクセスできる経路を用意します。
http://<タスクのPrivate IP>:9090
Prometheus にアクセスできる場合は、Status -> Targets を開き、以下が UP になっていることを確認します。
prometheus
snmp
9.3 snmp-exporter を確認
Prometheus のクエリ画面で以下を実行します。
up{job="snmp"}
1 が返れば Prometheus から snmp-exporter 経由で SNMP ターゲットを取得できています。
インターフェース系のメトリクス例です。
ifOperStatus
ifHCInOctets
ifHCOutOctets
9.4 Thanos Sidecar を確認
Thanos Sidecar の HTTP ポート 10902 は ALB に紐づけていません。内部ネットワークから到達できる場合のみ、health endpoint を確認します。
http://<タスクのPrivate IP>:10902/-/healthy
以下のような応答であれば正常です。
OK
しばらく待つと Prometheus のブロックが S3 にアップロードされます。S3 バケットの中に以下のようなオブジェクトが作成されていることを確認します。
01Jxxxxxxxxxxxxxxxxxxxxxxxxx/meta.json
01Jxxxxxxxxxxxxxxxxxxxxxxxxx/chunks/000001
01Jxxxxxxxxxxxxxxxxxxxxxxxxx/index
Prometheus のブロック生成は即時ではありません。この記事の設定では 2h ブロックにしているため、S3 反映まで時間がかかります。すぐ確認したい場合は短時間だけ検証用の設定に変えるか、Prometheus の Admin API でスナップショット確認を行います。
9.5 Thanos Query を確認
Thanos Query UI にアクセスします。
http://<ALB DNS名>
Stores 画面で以下が見えていれば、Query から Sidecar と Store に接続できています。
127.0.0.1:10901
127.0.0.1:10911
10. 運用時の注意点
Prometheus のデータ永続化
このタスク定義では EFS を使っていません。prometheus-data はタスク内の一時ボリュームです。
そのため、タスク停止前に Thanos Sidecar が S3 へアップロードしていない Prometheus ブロックは失われる可能性があります。Prometheus のローカル TSDB を永続化したい場合は、prometheus-data を EFS などの永続ボリュームに変更する設計を検討してください。
Thanos Sidecar とブロックサイズ
Thanos Sidecar でアップロードする場合、Prometheus のブロック期間は min-block-duration と max-block-duration を同じ値にする構成がよく使われます。この記事では以下にしています。
--storage.tsdb.min-block-duration=2h
--storage.tsdb.max-block-duration=2h
SNMP コミュニティ名
snmp-exporter は /etc/snmp_exporter/snmp.yml を参照します。実際の機器でコミュニティ名や認証方式を変更する場合は、S3 Files 側の snmp.yml をカスタムします。
本番では以下のどちらかを選びます。
- カスタム
snmp.ymlを含めた独自コンテナイメージを作る - S3 Files に
snmp.ymlを配置して snmp-exporter コンテナにマウントする
マネジメントコンソールだけで完結させる場合は、独自イメージを ECR に push して ECS の image に指定する方法が管理しやすいです。
S3 権限
Thanos Sidecar は S3 にブロックを書き込むため、ECS タスクロールに S3 権限が必要です。アクセスキーをコンテナ環境変数に入れる必要はありません。ECS タスクロールを使う方が安全です。
11. 参考
- Creating an Amazon ECS task definition using the console
- Amazon ECS task networking for tasks hosted on Fargate
- Specify an Amazon S3 Files volume in your Amazon ECS task definition
- Configuring S3 Files for Amazon ECS
- Amazon ECS container logs for EC2 and Fargate launch types
まとめ
ECS で Prometheus、Thanos、snmp-exporter を同じタスクにまとめると、コンテナ間通信を localhost で扱えるため構成がシンプルになります。
設定ファイルは S3 Files、Thanos の長期保存は S3 を使います。EFS は使わない構成なので、Prometheus のローカル TSDB を永続化したい場合は、別途 EFS 化する設計変更が必要です。