はじめに
AWS Firgate タスクのログについて、どのように管理して行くか検討したい点はいくつかあります。
- 保存先をどこにするか
- CloudWatch Logs, S3, 外部...
- どの程度の期間保存するか
- アラート通知をどうするか
概ね、以下のような形にはしたいですが、料金や要件等によって変わってくるところもあるかなと思います。
- S3: 出力される全てのログを保存し、長期間保存する (場合によっては Glacier へ保存する)
- 外部監視ツール
- CloudWatch Logs: アラームを出したいログ、Insightで見たい内容、または直近1ヶ月分等の短い期間のログ全量または一部
ログ送信先
ログの量が増え、保存期間が長くなるほど CloudWatch Logs よりは S3 に保存する方がコスト面では有利かと思います。
-
収集 (データの取り込み): 0.50USD/GB \
保存 (アーカイブ): 0.03USD/GB \
分析 (Logs Insights のクエリ): スキャンしたデータ 1 GB あたり 0.005USD \
検出およびマスク (データ保護): スキャンされたデータ 1 GB あたり 0.12USD \
分析 (Live Tail): 0.01 USD/分 \
-
S3 標準 - 頻繁にアクセスするデータに一般的に使用される、あらゆるタイプのデータの汎用ストレージ
最初の 50 TB/月 0.025USD/GB \
次の 450 TB/月 0.024USD/GB \
500 TB/月以上 0.023USD/GB \
インターネットから Amazon S3 へのデータ転送受信 (イン) \
すべてのデータ受信 0.00USD/GB
Amazon S3 からインターネットへのデータ転送送信 (アウト) \
最初の 10 TB/月 0.114USD/GB \
次の 40 TB/月 0.089USD/GB \
次の 100 TB/月 0.086USD/GB \
150 TB/月以上 0.084USD/GB \
PUT、COPY、POST、LIST リクエスト (1,000 リクエストあたり) GET、SELECT、他のすべてのリクエスト (1,000 リクエストあたり) ライフサイクル移行リクエスト (入) (1,000 件のリクエストあたり) データ取り出しリクエスト (1,000 リクエストあたり) データ取り出し (GB あたり) \
S3 標準 0.0047USD 0.00037USD 該当なし 該当なし 該当なし
リアルタイムに確認したい場合は CloudWatch Logs の方がやりやすいかもしれません。
ログ保存に使うツール
Fargate または ECS だと、ログの送信先を複数にする場合は、サイドカーコンテナで firelens を準備して、 firelens から複数の場所へ送信する場合が多いと思います。 単独なら awslogs ログドライバーを使って CloudWatch Logs へ出力し、そこから何かしらで別な場所へ取り込む形になると思います。
Fluentbit を使って S3 にログを送る場合、 firehose プラグインを使って firehose -> S3 とする方法と、 S3 プラグインを使って S3 へ直接ログを送る方法があるかと思います。
S3プラグインを使うと一発でS3へログを出力できて便利ですが、Fluentbitがリアルタイムにログデータを送るので、firehose をかました方が良いかもしれません。 ここではS3プラグインを使って直接S3へログを書き込む形にしています。
FireLens
FireLens は、Fluent Bit または Fluentd と組み合わせて動作する、ECS タスクログを転送するためのツールであるようです。 Fluent Bit または Fluentd をログルーターのサイドカーコンテナとして起動させておき、ECS タスクのログを標準出力と標準エラー出力を、AWS FireLens ログルーターのサイドカーコンテナへ転送し、ログを受け取ったログルーターコンテナが Fluent Bit または Fluentd の設定に従って、 CloudWatch logsやS3、DataDog といったAWS内外のサービスへログを出力してくれます。 そのため、アプリケーション側でログ出力以外に特別な対応は必要ありません。
FireLens ではログルーターの OSS である Fluent Bit または Fluentd を選択できるようですが、AWSではより軽量である Fluent Bit が推奨されています。 AWS for Fluent Bit のコンテナイメージも公開されています。
設定例
Fluentbit を使って AWS Fargate のログを CloudWatch Logs, S3 へ送ってみます。 使うのは CloudWatch Logs プラグインと S3 プラグインです。
環境
Fluentbit 設定ファイル
extra.conf を以下のような内容で記述します。ログ全量をCloudWatch LogsとS3へ出力するようにしています。必要に応じてフィルターを設定します。
[OUTPUT] Name cloudwatch_logs Match * region ap-northeast-1 log_group_name /ecs/${ENV}-sandbox-ecs-fargate-service/task/app log_stream_prefix fluentbit- log_key log [OUTPUT] Name s3 Match * region ap-northeast-1 bucket test-bucket total_file_size 1M upload_timeout 1m use_put_object On
Fluentbit Docker ファイル
以下のような形にします。
FROM public.ecr.aws/aws-observability/aws-for-fluent-bit:2.32.0 COPY ./extra.conf /fluent-bit/etc/extra.conf
タスクロール
Fargete タスクが S3 と CloudWatch Logs へアクセスできるように必要な権限を定義したタスクロールを作成します。 以下のようなタスクロールを作成します。結構雑ですがより厳密にやる場合はResourseセクションをきちんと指定するなどが必要です。
{ "Version": "2012-10-17", "Statement": [ { "Sid": "CloudWatchLogsPermissions", "Effect": "Allow", "Action": [ "logs:PutLogEvents", "logs:CreateLogStream", "logs:CreateLogGroup", "logs:DescribeLogStreams" ], "Resource": "*" }, { "Sid": "S3Permission", "Effect": "Allow", "Action": [ "s3:GetObject", "s3:GetBucketLocation", "s3:PutObject" ], "Resource": "*" } ] }
タスク定義
タスク定義を以下のような形します。
主には以下のような項目の設定が必要になると思います。
- メインのコンテナ(ここでは app)の
logConfiguration
で"logDriver": "awsfirelens"
を設定します。 - サイドカーとなるコンテナ(ここでは log-router )で
firelensConfiguration
を設定します。 - 環境変数の項目では、
extra.conf
で必要なものを記述します。ここでは ${ENV} のみとしています
{ "containerDefinitions": [ { "command": [], "cpu": 0, "essential": true, "image": "nginx", "logConfiguration": { "logDriver": "awsfirelens" }, "name": "web", "portMappings": [ { "name": "nginx-80-tcp", "containerPort": 80, "hostPort": 80, "protocol": "tcp", "appProtocol": "http" } ], }, { "cpu": 0, "essential": true, "firelensConfiguration": { "options": { "config-file-type": "file", "config-file-value": "/fluent-bit/etc/extra.conf", "enable-ecs-log-metadata": "true" }, "type": "fluentbit" }, "image": "123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/log-router:latest", "memoryReservation": 50, "name": "log-router", "environment": [ { "name": "ENV", "value": "dev" } ] "user": "0" } ], "family": "dev-sandbox-ecs-fargate-taskdef", "taskRoleArn": "arn:aws:iam::123456789012:role/dev-sandbox-ecs-task-role", "executionRoleArn": "arn:aws:iam::123456789012:role/dev-sandbox-ecs-task-exec-role", "networkMode": "awsvpc" }
ビルド&デプロイ
メインのコンテナとサイドカーコンテナをECRへプッシュし、Fargateへデプロイします。 ここでは詳細なやり方は割愛します。
確認
CloudWatch Logs と S3 へログが出ていることを確認します。
まとめ
AWS Firgate タスクのログ管理について、S3と CloudWatch Logsへ保存する場合と、それをやる場合のサンプルについて書きました。
参考
- Amazon ECS ログを AWS サービスまたは AWS Partner に送信する - Amazon Elastic Container Service
- Amazon ECS の Fluent Bit イメージリポジトリの AWS - Amazon Elastic Container Service
- 詳解 FireLens – Amazon ECS タスクで高度なログルーティングを実現する機能を深く知る | Amazon Web Services ブログ
- AWS Fargate container logs collection and analysis with AWS FireLens and Sumo Logic | AWS Open Source Blog
- GitHub - aws/aws-for-fluent-bit: The source of the amazon/aws-for-fluent-bit container image
- GitHub - aws-samples/amazon-ecs-firelens-examples: Sample logging architectures for FireLens on Amazon ECS and AWS Fargate.
- 詳解 FireLens – Amazon ECS タスクで高度なログルーティングを実現する機能を深く知る | Amazon Web Services ブログ