使用 Amazon Managed Service for Prometheus 从 ECS 中收集应用程序度量

这是KINTO Technologies Advent Calendar 2021 – Qiita的第11篇文章。

我在KTC担任PlatformGroup的DevOps支持工作。主要负责为应用程序开发人员和运维人员提供CICD工具的引入支持、改进和标准化等服务。

我已经添加了一个关于如何在2022年7月4日按任务获取指标的方法。
我们已经在2023年11月28日对awsprometheusremotewrite进行了更新,以适应非推荐版本(v0.21.0~)。

首先

亚马逊提供的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も連携するので、とっつく分には楽だと思います。知らんけど

形成

advent-2021-構成図.png

设置

增加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查询的用户。

 

我使用了这个仪表板。
如果能成功设置数据源等,就会显示如此,可以确认数据已经成功传送。

image.png

附录(在本地运行)

不是使用侧边车,而是分别独立运行应用容器。

    • ローカルで項目などがうまく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を追加

以这种方式呈现。

更新仪表盘

image.png

通过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
image.png
image.png

我认为通过这样做,我们可以根据每个服务(应用程序)的方法/状态/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”等项目的策划和开发,并正在招募工程师。

 

广告
将在 10 秒后关闭
bannerAds