Amazon Web Services ブログ
AWS Distro for OpenTelemetry Collector を使用したクロスアカウントの Amazon ECS メトリクス収集
この記事は、Using AWS Distro for OpenTelemetry Collector for cross-account metrics collection on Amazon ECS を翻訳したものです。
2020 年 11 月、AWS は AWS Distro for OpenTelemetry (ADOT) による OpenTelemetry のサポートを発表しました。これは AWS がサポートする Cloud Native Computing Foundation (CNCF) OpenTelemetry プロジェクトのセキュアかつプロダクションレディなディストリビューションです。ADOT を使用すると、相関性のあるアプリケーションメトリクスやトレースを Amazon Managed Service for Prometheus (AMP) やパートナーの監視ソリューションなど複数の AWS ソリューションに送信し、計測できます。
多くのお客様はアプリケーションを別々の AWS アカウントや別々の AWS リージョンで実行しつつ、アプリケーションの可観測性を一箇所で管理したいと考えています。以前の記事では、Amazon Elastic Kubernetes Service (Amazon EKS) を使用して複数アカウントにまたがってメトリクスを収集する方法を紹介しました。シナリオは似ていますが、今回は ADOT エージェントを使用して、AWS ネイティブなコンテナオーケストレーションプラットフォームである Amazon Elastic Container Service (Amazon ECS) で実行されているワークロードのアプリケーションおよびプラットフォームのメトリクスを AMP ワークスペースに収集します。
セットアップの概要
課題を解決するために次のような構成にします。
ワークロードを実行するアカウント(以下、ワークロードアカウント):
- Amazon ECS のタスクで使用する IAM ロールを作成
モニタリングを実行するセントラルのアカウント(以下、モニタリングアカウント):
- AMP ワークスペースを作成
- AMP へのクロスアカウントアクセスを許可する IAM ロールの作成
ワークロードアカウント:
- クロスアカウントの IAM ロールを引き受けるための Amazon ECS のタスクロールの作成
- アプリケーションと AWS Distro for OpenTelemetry エージェントのセットアップ
- Amazon ECS クラスターの作成とアプリケーションの実行
モニタリングアカウント:
- Amazon Managed Service for Grafana (AMG) によるメトリクスの可視化
全体のアーキテクチャは以下のようになります。
ワークロードアカウント: ECS のロールのセットアップ
ワークロードアカウントにログインし、のちに Amazon ECS のタスクで使用する IAM ロールを作成します。このロールはモニタリングを実行するモニタリングアカウントで信頼され、assume-role の権限を与えられます。
cat > task-assume-role.json <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "ecs-tasks.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOF
aws iam create-role --role-name ecs-xaccount-task-role \
--assume-role-policy-document file://task-assume-role.json \
--region eu-west-1
モニタリングアカウントのセットアップ
ワークロードアカウントにログインし、AWS CLI を使用した以下のコマンドで AMP ワークスペースを作成します。
aws amp create-workspace --alias ecs-xaccount-metrics-demo --region eu-west-1
もしくは AWS コンソールを使って AMP サービスに移動することもできます。
以下のコマンドで AMP ワークスペースへの書き込み権限を持つ IAM ロールを作成できます。複数のアカウントに権限を付与するには “AWS”
配列に適切な IAM ロールの ARN を入力します。
# ワークロードアカウントの ID を設定
WORKLOAD_ACCOUNT_ID=
cat > policy.json <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::$WORKLOAD_ACCOUNT_ID:role/ecs-xaccount-task-role"
]
},
"Action": "sts:AssumeRole",
"Condition": {}
}
]
}
EOF
# 注意: ワークロードアカウントに ecs-xaccount-task-role が存在しない場合に
# エラーが発生することがあります。
aws iam create-role \
--role-name ECS-AMP-Central-Role \
--assume-role-policy-document file://policy.json \
--query 'Role.RoleName' \
--output text
aws iam attach-role-policy --role-name ECS-AMP-Central-Role \
--policy-arn arn:aws:iam::aws:policy/AmazonPrometheusRemoteWriteAccess
ワークロードアカウント
注:このセクションの説明は、必要な数のワークロードアカウントに対して繰り返します。
ワークロードアカウントにログインして、先に作成したロールに assumeRole
権限を付与します。
# モニタリングアカウントの ID を設定
CENTRAL_ACCOUNT_ID=
cat > policy.json <<EOF
{
"Version":"2012-10-17",
"Statement":[
{
"Effect":"Allow",
"Action":[
"sts:AssumeRole"
],
"Resource":"arn:aws:iam::${CENTRAL_ACCOUNT_ID}:role/ECS-AMP-Central-Role"
}
]
}
EOF
POLICY_ARN=$(aws iam create-policy --policy-name xaccount-amp-write \
--policy-document file://policy.json | jq -r '.Policy.Arn')
aws iam attach-role-policy --role-name ecs-xaccount-task-role \
--policy-arn $POLICY_ARN
ワークロードの設定
次に、Prometheus のメトリクスを公開するサンプルアプリケーションを設定します。
- アプリケーションと ECS のメトリクスをスクレイピングするため
aws-otel-collector
を設定します。 - Docker イメージをビルドし、Amazon Elastic Container Registry (Amazon ECR) 上でホストします。
ecs-cli
を使用して、Amazon ECS クラスターの設定、作成、実行などを行います。
レイアウトは以下のように構成します。
├── aws-otel-collector
│ ├── Dockerfile
│ └── config.yaml
├── demo-app
│ ├── Dockerfile
│ └── main.go
├── docker-compose.yml
└── ecs-params.yml
Amazon ECS をセットアップするには、要件として Docker と ecs-cli が必要です。Linux の場合、ecs-cli
は以下のようにインストールできます。
sudo curl -Lo /usr/local/bin/ecs-cli https://amazon-ecs-cli.s3.amazonaws.com/ecs-cli-linux-amd64-latest
それでは、/metrics
の Prometheus エンドポイント を公開するサンプルアプリケーションを作成してみましょう。
mkdir demo-app
cd demo-app/
cat > main.go <<EOF
package main
import (
"github.com/prometheus/client_golang/prometheus/promhttp"
"net/http"
)
func main() {
http.Handle("/metrics", promhttp.Handler())
http.ListenAndServe(":8000", nil)
}
EOF
アプリケーション用の Dockerfile を作成します。
cat > Dockerfile <<EOF
FROM golang:1.15 as builder
WORKDIR /go/src/app
COPY . .
RUN go get .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .
FROM alpine:latest
WORKDIR /app
RUN apk --no-cache add ca-certificates
COPY --from=builder /go/src/app/app .
EXPOSE 8000
CMD ["./app"]
EOF
最後に、以下のスクリプトで ECR リポジトリを作成し、アプリケーションのコンテナイメージをビルドして Amazon ECR にプッシュします。
APP_REPOSITORY=$(aws ecr create-repository --repository demo-app --query repository.repositoryUri --output text)
docker build . -t app
aws ecr get-login-password --region eu-west-1 | docker login --username AWS --password-stdin $APP_REPOSITORY
docker tag demo-app:latest $APP_REPOSITORY
docker push $APP_REPOSITORY
cd -
それでは、AWS Distro for OpenTelemetry Collector の設定を行っていきます。ここでは Pipeline と呼ばれるデータ収集のためのカスタム設定を作成します。Pipeline ではデータの受信から始まり、処理や修正、最後にエクスポーターを経由して Collector を出るまでの、データが Collector 内でたどる経路を定義します。
ここでは、/metrics エンドポイントを持つアプリケーションからデータを収集し、ecs-metrics-receiver
を使用して ECS タスクメタデータエンドポイントから様々な ECS タスクメタデータをスクレイピングします。ecs-metrics-receiver やその他の設定オプションの詳細についてはドキュメントをご覧ください。
awsprometheusremotewrite
exporters の設定を使用して、監視用のアカウントで作成された AMP ワークスペースに、収集したメトリクスをエクスポートします。AMP の remote_write エンドポイントと、ロールを引き受けるための IAM ロール (ここでは ECS-AMP-Central-Role
) の両方を用意します。
変数の WORKSPACE_ID
および CENTRAL_ACCOUNT_ID
を編集し、以下のスクリプトを実行してパイプラインを作成します。
WORKSPACE_ID=
CENTRAL_ACCOUNT_ID=
mkdir aws-otel-collector
cd aws-otel-collector
cat > config.yaml <<EOF
receivers:
prometheus:
config:
global:
scrape_interval: 15s
scrape_timeout: 10s
scrape_configs:
- job_name: "prometheus-demo-app"
static_configs:
- targets: [ 0.0.0.0:8000 ]
awsecscontainermetrics:
collection_interval: 20s
processors:
filter:
metrics:
include:
match_type: strict
metric_names:
- ecs.task.memory.utilized
- ecs.task.memory.reserved
- ecs.task.cpu.utilized
- ecs.task.cpu.reserved
- ecs.task.network.rate.rx
- ecs.task.network.rate.tx
- ecs.task.storage.read_bytes
- ecs.task.storage.write_bytes
exporters:
awsprometheusremotewrite:
endpoint: https://aps-workspaces.eu-west-1.amazonaws.com/workspaces/$WORKSPACE_ID/api/v1/remote_write
aws_auth:
region: eu-west-1
service: "aps"
role_arn: arn:aws:iam::$CENTRAL_ACCOUNT_ID:role/ECS-AMP-Central-Role
logging:
loglevel: debug
service:
pipelines:
metrics:
receivers: [prometheus]
exporters: [logging, awsprometheusremotewrite]
metrics/ecs:
receivers: [awsecscontainermetrics]
processors: [filter]
exporters: [logging, awsprometheusremotewrite]
EOF
aws-otel-collector
の最新バージョンを使用して、カスタムの設定を持つコンテナイメージを Amazon ECR に作成します。
cat > Dockerfile <<EOF
FROM public.ecr.aws/aws-observability/aws-otel-collector:latest
COPY config.yaml /etc/ecs/otel-config.yaml
CMD ["--config=/etc/ecs/otel-config.yaml"]
EOF
最後に、コンテナイメージをビルドしてプッシュします。
COLLECTOR_REPOSITORY=$(aws ecr create-repository --repository aws-otel-collector --query repository.repositoryUri --output text)
docker build . -t aws-otel-collector
aws ecr get-login-password --region eu-west-1 | docker login --username AWS --password-stdin $COLLECTOR_REPOSITORY
docker tag aws-otel-collector:latest $COLLECTOR_REPOSITORY
docker push $COLLECTOR_REPOSITORY
cd -
アプリケーションの実行: Amazon ECS のセットアップ
Amazon ECS はタスクを実行するための権限セットであるタスク実行ロールを必要とします。以下のスクリプトを実行して作成します。
cat > task-execution-assume-role.json <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "ecs-tasks.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOF
aws iam create-role --role-name ecs-xaccount-task-execution-role \
--assume-role-policy-document file://task-execution-assume-role.json \
--region eu-west-1
aws iam --region eu-west-1 attach-role-policy --role-name ecs-xaccount-task-execution-role \
--policy-arn arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy
WORKLOAD_ACCOUNT_ID
変数を設定し、以下のスクリプトを実行して docker-compose
ファイルを作成します。
WORKLOAD_ACCOUNT_ID=
cat > docker-compose.yml <<EOF
version: "3"
services:
aws-otel-collector:
image: $WORKLOAD_ACCOUNT_ID.dkr.ecr.eu-west-1.amazonaws.com/aws-otel-collector:latest
environment:
- AWS_REGION=eu-west-1
logging:
driver: awslogs
options:
awslogs-group: ecs-xaccount-metrics-demo
awslogs-region: eu-west-1
awslogs-stream-prefix: aws-otel-collector
prometheus-demo-app:
image: $WORKLOAD_ACCOUNT_ID.dkr.ecr.eu-west-1.amazonaws.com/demo-app
ports:
- "8000:8000"
depends_on:
- aws-otel-collector
logging:
driver: awslogs
options:
awslogs-group: ecs-xaccount-metrics-demo
awslogs-region: eu-west-1
awslogs-stream-prefix: demo-app
EOF
ecs-cli
を使って Amazon ECS クラスターを作成します。
ecs-cli configure --cluster ecs-xaccount-metrics-demo \
--default-launch-type FARGATE \
--config-name ecs-xaccount-metrics-demo \
--region eu-west-1
ecs-cli up --cluster-config ecs-xaccount-metrics-demo
数分後、必要な関連リソースをすべて備えた ECS クラスターが作成されます。前述のコマンドから VPC_ID
を設定し、その VPC に関連付けられたデフォルトのセキュリティグループを取得します。
VPC_ID=
aws ec2 describe-security-groups --filters Name=vpc-id,Values=$VPC_ID \
--region eu-west-1 \
--query SecurityGroups[0].GroupId \
--output text
ecs-cli
が必要とする ecs-params.yml
ファイルを編集し、前のコマンドで出力されたサブネット ID とセキュリティグループに置き換えます。
version: 1
task_definition:
ecs_network_mode: awsvpc
task_role_arn: ecs-xaccount-task-role
task_execution_role: ecs-xaccount-task-execution-role
task_size:
mem_limit: 0.5GB
cpu_limit: 256
run_params:
network_configuration:
awsvpc_configuration:
subnets:
- "subnet-"
- "subnet-"
security_groups:
- "sg-"
assign_public_ip: ENABLED
最後に、以下のスクリプトを実行してアプリケーションをデプロイします。
ecs-cli compose --project-name ecs-xaccount-metrics-demo \
service up \
--cluster-config ecs-xaccount-metrics-demo \
--create-log-groups
数分後、Amazon ECS サービスが起動して実行されるはずです。Amazon CloudWatch Logs コンソールで aws-otel-collector
のログを、ロググループ ecs-xaccount-metrics-demo
で確認できます。
モニタリングアカウント: メトリクスの可視化
モニタリングアカウントに戻って、Amazon Managed Service for Grafana (AMG) のワークスペースを使ってメトリクスを可視化してみましょう。AMG の設定についてはドキュメントを参照してください。
アプリケーションのエンドポイントからのメトリクスを見ることができます。
Amazon ECS クラスターのメトリクス:
後片付け
ワークロードアカウント
WORKLOAD_ACCOUNT_ID=
# ECS サービスの停止と削除
ecs-cli compose --project-name ecs-xaccount-metrics-demo service down --cluster-config ecs-xaccount-metrics-demo
# ECS クラスターの削除
ecs-cli down --cluster-config ecs-xaccount-metrics-demo
# タスクロールの削除
aws iam detach-role-policy --role-name ecs-xaccount-task-role --policy-arn arn:aws:iam::$WORKLOAD_ACCOUNT_ID:policy/xaccount-amp-write
aws iam delete-policy --policy-arn arn:aws:iam::$WORKLOAD_ACCOUNT_ID:policy/xaccount-amp-write
aws iam delete-role --role-name ecs-xaccount-task-role
# タスク実行ロールの削除
aws iam detach-role-policy --role-name ecs-xaccount-task-execution-role --policy-arn arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy
aws iam delete-role --role-name ecs-xaccount-task-execution-role
モニタリングアカウント
WORKSPACE_ID=
# IAM ロールの削除
aws iam detach-role-policy --role-name ECS-AMP-Central-Role --policy-arn arn:aws:iam::aws:policy/AmazonPrometheusRemoteWriteAccess
aws iam delete-role --role-name ECS-AMP-Central-Role
# ワークスペースの削除
aws amp delete-workspace --workspace-id $WORKSPACE_ID
まとめ
この記事では、AWS Distro for OpenTelemetry (ADOT) エージェントを使用して、Amazon ECS 上で動作するワークロードのアプリケーションおよびプラットフォームのメトリクスを収集する方法を説明しました。
ADOT は Amazon EKS、Amazon Elastic Compute Cloud (Amazon EC2)、またはオンプレミスなどの他のプラットフォームでも使用できます。さらに ADOT を使用して分散型トレース情報を収集し、複数の異なるワークロードアカウントがメトリクスを AMP や他のプラットフォームに一元的に送信することができます。また必要に応じて VPC エンドポイントや VPC ピアリングによるプライベート接続を設定することも可能です。
詳しくは ADOT、AMP、AMGのサイトをご覧ください。
翻訳はソリューションアーキテクト加治が担当しました。原文はこちらです。