[アップデート] ECS/Fargateでログ出力先をカスタマイズできる「FireLens」機能がリリースされました
みなさん、こんにちは!
AWS事業本部の青柳@福岡オフィスです。
ECS/Fargateタスクのログ出力先をカスタマイズ(ルーティング)できる「FireLens」機能が AWS Containers Roadmap の リポジトリ でプレビューされていましたが、先日、正式リリースされました。
まだドキュメントが日本語化されていませんが、英語版ドキュメントの内容に沿って試してみました。 Custom Log Routing - Amazon ECS
従来の「CloudWatch Logs」へのログ出力
まず、従来の「CloudWatch Logs」へのログ出力を行ってみます。
全体の構成は下図のようになります。
ECSクラスターやALBの設定については省略します。(既に準備されているものとします)
アプリケーションコンテナ(今回はApache HTTP Server)を1つ含むタスク定義JSONファイルを以下のように記述します。
{ "family": "example-task-definition-20191001", "taskRoleArn": "arn:aws:iam::123456789012:role/ecsTaskRole", "executionRoleArn": "arn:aws:iam::123456789012:role/ecsTaskExecutionRole", "networkMode": "awsvpc", "containerDefinitions": [ { "name": "web-app", "image": "httpd:2.4", "portMappings": [ { "containerPort": 80, "hostPort": 80, "protocol": "tcp" } ], "essential": true, "entryPoint": [ "sh", "-c" ], "command": [ "/bin/sh -c \"echo 'FireLens Example' > /usr/local/apache2/htdocs/index.html && httpd-foreground\"" ], "logConfiguration": { "logDriver": "awslogs", "options": { "awslogs-group": "/ecs/firelens-example", "awslogs-region": "ap-northeast-1", "awslogs-stream-prefix": "ecs" } } } ], "requiresCompatibilities": [ "FARGATE" ], "cpu": "256", "memory": "512" }
logConfiguration
にログ出力の設定を記述します。
logDriver
に awslogs
を指定することで、ログ出力先をCloudWatch Logsに設定することができます。
タスク定義JSONファイルを使ってタスク定義を作成します。
$ aws ecs register-task-definition --cli-input-json file://example-task-definition.json
GUI (マネジメントコンソール) で設定する場合は以下のようになります。
このタスク定義を使ってサービスを作成し、タスクを起動すると、CloudWatch Logsにログが出力されることが確認できました。
「FireLens」を使ったログ出力
「FireLens」を使う場合の構成は下図のようになります。
CloudWatch Logへのログ出力のようにアプリケーションコンテナから直接ログをログ出力先に送信するのではなく、タスク内に「FireLensコンテナ」を追加して、FireLensコンテナ経由でログを送信する仕組みです。(いわゆる「サイドカー」構成ですね)
なお、上図ではログをKinesis Data Firehose経由でS3バケットへ出力していますが、これは一例で、FireLensは他にもCloudWatch LogやFluentdなどへのログ出力に対応しています。(今回は上図の通りKinesis Data Firehose経由でS3バケットへのログ出力を行います)
ログの出力先を準備する
ログの出力先となるKinesis Data FirehoseおよびS3バケットを作成します。(特別な設定は必要ないため手順は割愛します)
また、FireLensコンテナがKinesis Data Firehoseへストリームを送れるよう、タスクロールにアクセス権限を設定します。
(タスク実行ロールではなくタスクロールの方ですので注意してください)
タスクロール ecsTaskRole
に以下のポリシーを設定します。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "firehose:PutRecordBatch", "Resource": "*" } ] }
タスク定義を更新する
前項のタスク定義JSONファイルをコピーして、以下のように修正します。
{ "family": "example-task-definition-20191001", "taskRoleArn": "arn:aws:iam::123456789012:role/ecsTaskRole", "executionRoleArn": "arn:aws:iam::123456789012:role/ecsTaskExecutionRole", "networkMode": "awsvpc", "containerDefinitions": [ { "name": "web-app", "image": "httpd:2.4", "portMappings": [ { "containerPort": 80, "hostPort": 80, "protocol": "tcp" } ], "essential": true, "entryPoint": [ "sh", "-c" ], "command": [ "/bin/sh -c \"echo 'FireLens Example' > /usr/local/apache2/htdocs/index.html && httpd-foreground\"" ], "logConfiguration": { "logDriver":"awsfirelens", "options": { "Name": "firehose", "region": "ap-northeast-1", "delivery_stream": "firelens-example-stream" } } }, { "name": "log-router", "image": "906394416424.dkr.ecr.ap-northeast-1.amazonaws.com/aws-for-fluent-bit:latest", "essential": true, "firelensConfiguration": { "type": "fluentbit" }, "logConfiguration": { "logDriver": "awslogs", "options": { "awslogs-group": "/ecs/firelens-example", "awslogs-region": "ap-northeast-1", "awslogs-stream-prefix": "firelens" } } } ], "requiresCompatibilities": [ "FARGATE" ], "cpu": "256", "memory": "512" }
34~49行目の記述で、FireLensコンテナの定義を追加しています。
{ "name": "log-router", "image": "906394416424.dkr.ecr.ap-northeast-1.amazonaws.com/aws-for-fluent-bit:latest", "essential": true, "firelensConfiguration": { "type": "fluentbit" }, "logConfiguration": { "logDriver": "awslogs", "options": { "awslogs-group": "/ecs/firelens-example", "awslogs-region": "ap-northeast-1", "awslogs-stream-prefix": "firelens" } } }
FireLensのコンテナイメージは、AWSが提供しているものを使用します。
これは、軽量ログ収集ツールである「Fluent bit」に、AWSが開発したプラグイン(Fluent bitからCloudWatch LogやKinesis Data Firehoseへ連係するためのプラグイン)を同梱したものになっています。
FireLensコンテナイメージのURLはリージョン毎に異なりますので、下記リンクを参照してください。
https://docs.aws.amazon.com/en_us/AmazonECS/latest/userguide/using_firelens.html#firelens-using-fluentbit
なお、FireLensコンテナの定義にも logConfiguration
セクションがありますが、これはFireLensコンテナ自身の動作ログの出力先の設定になります。(CloudWatch Logsを指定しています)
続いて、既存のアプリケーションコンテナの定義について、ログ出力の設定を変更します。
"logConfiguration": { "logDriver":"awsfirelens", "options": { "Name": "firehose", "region": "ap-northeast-1", "delivery_stream": "firelens-example-stream" } }
26行目の logDriver
の指定を awsfirelens
に変更します。
また、28~30行目で、出力先を「firehose (=Kinesis Data Firehose)」にすること、および、Kinesis Data Firehoseに関する設定(リージョン、配信ストリーム名)を指定します。
タスク定義JSONファイルを修正しましたら、タスク定義の新しいリビジョンを作成します。
$ aws ecs register-task-definition --cli-input-json file://example-task-definition-v2.json
サービスの設定を更新し、タスク定義の新しいリビジョンでタスクを起動します。
(ログドライバーの選択肢に「FireLens」が出てこない) 今回の手順のようにタスク定義をJSONファイルを使って作成する必要があります。
ログが出力されることを確認する
ログの最終送信先であるS3バケットを確認してみましょう。
年・月・日・時のフォルダが作成され、フォルダ内にログが格納されたことが確認できました。
S3バケットに格納されたログは、AWS GlueやAmazon Athenaを使うとイイ感じに分析ができそうです。
おわりに
今回紹介したサンプルのみですと単にログ出力先をCloudWatchからKinesis Data Firehose/S3へ変更しただけということになりますが、FireLensには他にもいろいろな機能があります。
- 正規表現によるログフィルタリング
- 外部Fluentdへのログ転送
大量に動作するコンテナのログから必要なログのみを収集したり、1箇所に集めたログをツールで分析したり、ということに役立ちそうです。
AWSサービスへの対応がプラグインで提供されていたり、Fluent bitの設定をカスタマイズできたりと、今後の機能拡大にも期待です。