使用 Amazon Managed Service for Prometheus 从 ECS 中收集应用程序度量
这是KINTO Technologies Advent Calendar 2021 – Qiita的第11篇文章。
我在KTC担任PlatformGroup的DevOps支持工作。主要负责为应用程序开发人员和运维人员提供CICD工具的引入支持、改进和标准化等服务。
首先
亚马逊提供的Prometheus托管服务(AMP)已经宣布并正式发布。
AMP仅支持RemoteWrite,不支持爬取功能。根据AWS文档,建议使用CloudWatch代理或AWS OpenTelemetry Collector分发版。
考虑到不仅限于Java,我们计划使用后者的收集器来进行指标收集。
请注意,CloudWatch代理似乎仅支持JVM。
前提
ECS只需一个中文选项:
弹性计算服务
-
- クラスタとサービス、タスク定義が構築されていること
-
- Fargateを想定しています。EC2を使う場合は一部を読み替えてください
- アプリケーションはSpringBoot(Actuator)を使用したJavaアプリケーションの想定です
AMP(亚马逊 Prometheus 托管服务)
-
- 長いので、PrometheusもしくはAMPと今後は記載します
-
- ワークスペースや各種権限が既に構築・設定されていること
-
- インターフェース型のVPCエンドポイントを作成すると内部通信にできますが、省略
-
- Grafanaを使った可視化についても詳細は省略しますが、Prometheusにデータがあるかどうか?という確認のため、ローカルで起動します
- AWS Grafanaだと権限とか気にしなくていいしCloudWatchとかX-Rayも連携するので、とっつく分には楽だと思います。知らんけど
形成

设置
增加IAM配置
给任务执行角色(taskRoleArn)授予对AMP的RemoteWrite权限。
"aps:RemoteWrite"
根据需要,将通过资源对AMP工作区进行限制。
进行Config设置
在ECS的实际环境中,根据文档,我们将参数存储在ParameterStore中,并从TaskDefinition中进行调用,因此我们将按照这个方式进行。
如果使用Fargate,则adotCollector的Config示例如上所示。
如果是EC2,则在相同目录中有适用于EC2的示例。
##
## AWS OTEL COLLECTOR CONFIG FOR ECS TASK
##
receivers:
prometheus:
config:
global:
scrape_interval: 30s
scrape_timeout: 20s
scrape_configs:
- job_name: {{ApplicationName}}
metrics_path: "/actuator/prometheus"
static_configs:
- targets: [ 0.0.0.0:8081 ]
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:
prometheusremotewrite:
## ENDPOINTはAWS AMPの「エンドポイント - リモート書き込み URL」をそのまま使用する。
endpoint: {{endpoint}}
resource_to_telemetry_conversion:
enabled: true
auth:
authenticator: sigv4auth
logging:
loglevel: debug
extensions:
health_check:
sigv4auth:
service:
extensions: [health_check, sigv4auth]
pipelines:
metrics:
receivers: [prometheus]
exporters: [logging, prometheusremotewrite]
metrics/ecs:
receivers: [awsecscontainermetrics]
processors: [filter]
exporters: [logging, prometheusremotewrite]
-
- Endpoint
-
- ApplicationName
- スクレイピングの間隔
请根据需要适时调整,因为这是个别值。job_name是分配给Grafana搜索时的ApplicationName,每个应用程序都单独分配会更易于理解。
将上述的Yaml文件保存到ParameterStore的/common/ADOT_CUSTOM_CONFIG中。
更新任务定义
使用Fargate的情况下,ECS任务定义的JSON示例如上所示。如果使用EC2,同一目录下也有针对EC2的示例。在ContainerDefinitions部分中
{
"name": "aws-otel-collector",
"image": "public.ecr.aws/aws-observability/aws-otel-collector:latest",
"essential": true,
"secrets": [{
"name": "AOT_CONFIG_CONTENT",
"valueFrom": "arn:aws:ssm:***:***:parameter/common/ADOT_CUSTOM_CONFIG"
}],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/ecs-aws-otel-sidecar-collector",
"awslogs-region": "ap-northeast-1",
"awslogs-stream-prefix": "ecs",
"awslogs-create-group": "True"
}
}
"memory": 96,
"memoryReservation": 96,
"cpu": 128
}
在此之后追加并将Collector更改为使用Sidecar启动。
-
- CloudWatchのロググループ
-
- プリフェックス
-
- ParameterStoreのパス
-
- AWS REGION
-
- などは適時書き換えてください。
- CollectorのCPU、メモリについては追加設定で制限しました。
部署任务定义
KTC正在使用GithubActions来实现CICD,但在这里我会忽略掉。
我们会升级任务定义版本并确保它正确启动。
由于AdotCollector的配置错误、ParameterStore的权限错误或者输错导致Collector容器崩溃,所以整个任务会失败,请注意。
在Grafana上查看数据
我会在本地运行Grafana。
关于权限问题将被省略,我们将使用一个能够执行各种aps查询的用户。
我使用了这个仪表板。
如果能成功设置数据源等,就会显示如此,可以确认数据已经成功传送。

附录(在本地运行)
不是使用侧边车,而是分别独立运行应用容器。
-
- ローカルで項目などがうまくAMPに登録できるか、可視化のPoCなどをするのに、ECSまで作ると手間
- アプリケーション向けにワークショップをしたい
所以我做好了准备。
目录结构设想如下。
.
├── README.md
├── docker
│ └── otel
│ └── otel-local-docker-config.yaml
└── docker-compose.yaml
将本地内容推送到AMP。
Docker-Compose-用中文进行本地化简:容器编排
# AWS OtelCollector
collector:
image: public.ecr.aws/aws-observability/aws-otel-collector:v0.13.0
container_name: aws-otel-collector
command: ["--config=/etc/otel-agent-config.yaml"]
## AMPへPUSHできる権限のあるユーザID/SECRETを記載する。
## 環境変数から呼び出す
environment:
AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID}
AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY}
AWS_SESSION_TOKEN: ${AWS_SESSION_TOKEN}
AWS_REGION: ap-northeast-1
## OpenTelemetoryCollectorのConfigを設定する。
volumes:
- ./docker/otel/otel-local-docker-config.yaml:/etc/otel-agent-config.yaml
- ~/.aws:/root/.aws
ports:
- 55680:55680
- 8889:8888
请将上述内容添加到与应用程序相同的docker-compose.yaml文件中。请根据需要修改配置文件的路径和地区。
配置
##
## AWS OTEL COLLECTOR CONFIG FOR LOCAL DOCKER/JAR APP
##
receivers:
prometheus:
config:
global:
scrape_interval: 30s
scrape_timeout: 10s
scrape_configs:
- job_name: {{ApplicationName}}
metrics_path: "/actuator/prometheus"
static_configs:
- targets: [ app:8081 ]
awsecscontainermetrics:
collection_interval: 20s
processors:
batch:
exporters:
prometheusremotewrite:
## ENDPOINTはAWS AMPの「エンドポイント - リモート書き込み URL」をそのまま使用する
endpoint: {{endpoint}}
resource_to_telemetry_conversion:
enabled: true
auth:
authenticator: sigv4auth
logging:
loglevel: debug
extensions:
health_check:
sigv4auth:
service:
extensions: [health_check, sigv4auth]
pipelines:
metrics:
receivers: [prometheus]
exporters: [logging, prometheusremotewrite]
请根据docker-compose文件中的应用程序容器名,对targets的应用进行适时修正。
2022年7月4日附录:附录(将ECS的任务分为每个指标)
如果在ECS上运行任务,只需将ApplicationName设置为SpringBoot等,即使在集群内启动了多个服务,也可以在一定程度上将聚合结果分割并进行确认。
但如果想要查看任务级别的问题,就需要考虑一些其他因素。
我们的SRE负责人与AWS支持团队进行了交流,确认可以通过Collector的配置来实现任务的分割,并将其追加上去。
升级OtelCollector的版本
在这篇文章中,我们将最新版本标记为latest,但在实际运用中,当本文被发布时,我们使用的是v0.16.0版本。然而,在后续的任务定义中,我们使用的配置已经在v0.18.0版本及以上进行了确认,因此我们升级到了v0.18.0版本。
在v0.15.1版本中存在一个错误,无法正常工作,但在最新的v0.18.0版本中进行了确认,可以正常工作。
更新OtelConfig。
##
## AWS OTEL COLLECTOR CONFIG FOR ECS TASK
##
receivers:
prometheus:
config:
global:
scrape_interval: 30s
scrape_timeout: 20s
scrape_configs:
- job_name: {{ApplicationName}}
metrics_path: "/actuator/prometheus"
static_configs:
- targets: [ 0.0.0.0:8081 ]
awsecscontainermetrics:
collection_interval: 30s
processors:
resourcedetection:
detectors:
- env
- ecs
attributes:
- cloud.region
- aws.ecs.task.arn
- aws.ecs.task.family
- aws.ecs.task.revision
- aws.ecs.launchtype
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:
prometheusremotewrite:
endpoint: {{endpoint}}
resource_to_telemetry_conversion:
enabled: true
auth:
authenticator: sigv4auth
logging:
loglevel: warn
extensions:
health_check:
sigv4auth:
service:
telemetry:
logs:
level: info
extensions: [health_check]
pipelines:
metrics:
receivers: [prometheus]
processors: [resourcedetection]
exporters: [logging, prometheusremotewrite]
metrics/ecs:
receivers: [awsecscontainermetrics]
processors: [filter]
exporters: [logging, prometheusremotewrite]
我确认了与AWS支持的事情,结果就是这样了。具体细节我就略去了。
-
- resourcedetection processorを使用してタスクごとのメタデータをメトリクスに付与する
- awsprometheusremotewrite exporterにresource_to_telemetry_conversionを追加
以这种方式呈现。
更新仪表盘

通过ARN进行筛选
ECS任务相关的指标包括
-
- aws_ecs_cluster_name
-
- aws_ecs_launchtype
-
- aws_ecs_service_name
-
- aws_ecs_task_arn
-
- aws_ecs_task_family
-
- aws_ecs_task_id
-
- aws_ecs_task_known_status
-
- aws_ecs_task_revision / version
-
- cloud_account_id
- cloud_availability_zone
有人进来了。
在从 PrometheusExporter 获取的指标中,包含了使用上述配置中处理器分配的 AWS 相关标签。
-
- aws_ecs_launchtype
-
- aws_ecs_task_arn
-
- aws_ecs_task_family
-
- aws_ecs_task_revision
- cloud_region


我认为通过这样做,我们可以根据每个服务(应用程序)的方法/状态/URI进行统计。
伤心的事情 de
由于本地和AWS上的Grafana在实施警报的方式和设置方法上存在差异,因此当将AlertDashBoard作为标准创建并导入到WorkShop中时,警报就会消失。(使用的版本是相同的)
最后
因为RemoteWrite的形式,Prometheus服务主要用于数据存储,但也提供了配置和部署定义的示例,可以更轻松地收集指标。在考虑应用程序方面,需要考虑收集用的副容器等因素增加了。但是,与自行准备相比,我认为门槛较低。
将来期望能够有适用于批处理的PushGateway之类的工具。因为在SpringBoot中也有PushGateway库,通过使用它可能不需要引入副容器。
2023/11/28新增内容
ADOT(AWS Distro for OpenTelemetry)已经开始支持日志功能。
https://aws.amazon.com/jp/about-aws/whats-new/2023/11/logs-support-aws-distro-opentelemetry/
考虑到自动诊断功能,我认为上述配置可以更简化,也希望能进一步添加日志追踪等功能。如果实现了这一点,我会在另一篇文章中详细介绍。
参考资料 (公式) – 参考资料中所包含的公式
一般的的
我们公司目前正在进行丰田汽车的订阅计划“KINTO”等项目的策划和开发,并正在招募工程师。