🚗

DockerベースイメージのAmazon Linux 2023移行に伴い、cloudwatch-agentを利用してログを送信する

に公開

はじめに

弊社では、9月にPHPのバージョンを8.2->8.4にバージョンアップしました。

このPHPバージョンアップに伴い、ランサーズで利用しているDockerfileのベースイメージをAmazon Linux 2023にアップグレードする必要がありました。
Amazon Linux 2023では今までログ出力に利用していたawslogsパッケージが利用できないため、CloudWatch Agentを導入することとしました。
本記事では、このCloudWatch Agentの導入についてお話しさせていただきます。

(PHP 7.3->8.4 までバージョンアップをしていただいた、keiさんの記事はこちらから)

参考

AL2 で廃止され、AL2023 で削除された機能
https://docs.aws.amazon.com/ja_jp/linux/al2023/ug/deprecated-al2.html#deprecated-awslogs

前提

※ 記事の中でコードを記載させていただいておりますが、実際に変更した内容の抜粋となっているため
あくまで参考例にしていただけますと幸いです。

  • インフラの構成管理にはTerraformを利用
  • アプリケーションは、ECS on Fargateでホスト
  • コンテナイメージは、ECRで管理
  • リリース時に問題が起きた時のため、ECSにはデプロイサーキットブレーカーが設定済み

方針

  • cloudwatch-agentへのリソース配分を決定
  • FargateタスクのSidecarコンテナとして、cloudwwatch-agentコンテナを導入

手順

cloudwatch-agentへのリソース配分を決定

cloudwatch-agentコンテナを導入するにあたって、どれくらいのリソースを割り当てるべきか有用な情報が見つけられませんでした。

そこで、下記の手順で現状のリソースを把握しつつ進めることとしました。

  1. ECSタスクの各コンテナについて、リソース使用状況を可視化
  2. 推測でリソースを割り振り、検証環境でテスト
  3. 検証環境でテストした値をもとに、本番環境の設定を決定

ECSタスクの各コンテナについて、リソース使用状況を可視化

コンテナのCPU使用率・メモリ使用量を可視化するにあたっては、Datadogを利用しました。
可視化に仕様したメトリクスは下記の通りです。

  • CPU使用率: ecs.fargate.cpu.percent
  • メモリ使用量: ecs.fargate.mem.usage

また、Sidecarコンテナの各コンテナごとにCPU使用率・メモリ使用率の最大値をグラフ化し、
一覧表示できるdashboardを作成しました。
完成したDashboardを確認したところ、使用量に対してリソースが余っているコンテナがあったため、
そのコンテナのリソースをcloudwatch-agentに割り振る形で修正を行いました。

リソースの余剰やその他SideCarコンテナの設定値を参考に、下記のとおりリソース配分を行うこととしました。

  • cpu: 128
  • memory: 256MiB

ex. DatadogでのCPU使用率可視化の例

推測でリソースを割り振り、検証環境でテスト & 検証環境でテストした値をもとに、本番環境の設定を決定

検証したところ、概ね仮の設定値で進められそうでした。(検証内容は下記画像参照)

メモリに関しては、もう128MiBほど割り振っても問題なさそうですが、
下記の理由から仮の設定値のままで進めることとしました。

  • ピーク時のメトリクスであること(平均的には使用率がもっと低い)
  • メモリ使用率の増減が緩やかであること


実装

ECSタスク定義

主な変更内容は下記の通りです。

  • CloudWatch Agent稼働用のsidecarコンテナ追加
  • cloudwatch-agentコンテナがログを読み取れるよう、共有ボリュームを追加
    • 意図しない変更を防ぐため、cloudwatch-agentからのボリュームアクセスはReadOnlyに指定

ex.

[
    {
      "name": "app",
      "image": "xxxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/app:latest",
      "cpu": 1024,
      "memory": 2048,
      "mountPoints": [
        {
          "sourceVolume": "system-logs",
          "containerPath": "/var/log",
          "readOnly": false
        }
      ],
      "logConfiguration": {
        "logDriver": "awslogs",
        "options": {
          "awslogs-group": "/ecs/app",
          "awslogs-region": "ap-northeast-1",
          "awslogs-stream-prefix": "ecs"
        }
      },
      "ulimits": [
        {
          "name": "nofile",
          "softLimit": 1000000,
          "hardLimit": 1000000
        }
      ]
    },
    {
      "name": "cloudwatch-agent",
      "image": "xxxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/ecr-public/cloudwatch-agent/cloudwatch-agent:x.xxxxx.xxxxx",
      "cpu": 128,
      "memory": 256,
      "secrets": [
        {
          "name": "CW_CONFIG_CONTENT",
          "valueFrom": "${cw_config_content}"
        }
      ],
      "mountPoints": [
        {
          "sourceVolume": "system-logs",
          "containerPath": "/var/log",
          "readOnly": true
        }
      ],
      "logConfiguration": {
        "logDriver": "awslogs",
        "options": {
          "awslogs-group": "/ecs/cloudwatch-agent",
          "awslogs-region": "ap-northeast-1",
          "awslogs-stream-prefix": "ecs"
        }
      }
    }
  ]
  

CloudWatch設定ファイル

今回はログのみ収集するため、メトリクス収集の設定は入れていません。
また、費用削減のためVPCエンドポイント経由でのログ送信設定を行っています。

ex.

{
  "agent": {
    "logfile": "/opt/aws/amazon-cloudwatch-agent/logs/amazon-cloudwatch-agent.log",
    "debug": false
  },
  "logs": {
    "endpoint_override": "{your_vpc_endpoint_name}",
    "logs_collected": {
      "files": {
        "collect_list": [
          {
            "file_path": "/var/log/access.log",
            "log_group_name": "/lancers/access.log",
            "log_stream_name": "{local_hostname}",
            "timestamp_format": "%d/%b/%Y:%H:%M:%S %z",
            "timezone": "Local"
          }
    },
    "force_flush_interval": 5
  }
}

結果

  • 上記の設定を本番反映したところ、問題なくCloudWatch Logsにログが出力されました 🥳
  • 想像していたより少ないリソースで、CloudWatch Agentが導入できることに気づきました(下記画像参照)
    • 赤線がタスク定義で設定している値、青線が実際の使用量を表すグラフになります

終わりに

ここまでご覧いただきありがとうございました。

見落としがちですが、Pull Through Cacheの設定が漏れると費用面でのインパクトが大きくなる可能性があるため、忘れず設定するようにしましょう!
(私は見事に失念して余計な費用を発生させてしまいましたので、皆さんは同じ轍を踏まないよう願っております🙏)

ランサーズ株式会社

Discussion