⚡TL;DR
-
ECS on Fargateで永続ボリューム(EBS)に吐き出しているログファイルをCloudWatch Logsに転送するには、Fluent-Bitなどのサイドカーコンテナが必要となる - アプリログを標準出力するようにすれば、
awslogsドライバーで直接CloudWatch Logsに転送できるので、サイドカー分のコストが削減可能
🔰はじめに
Fargateは、サーバレスなコンテナ実行環境です。
サーバレスにはインフラ管理が不要といったメリットがありますが、一方で弊害もあります。
それは、「Fargateには、CloudWatchエージェントをインストールできない」という点です。
📃CloudWatch Logsへのログファイル転送
EC2タイプのECSでは、CloudWatchエージェントをインストールすることでログ転送を簡単に実現することが可能です。
しかしFargateでは、先述のとおりCloudWatchエージェントを利用することが出来ません。
これによりFargateでは、EBSなどの永続ボリュームに保存されたログファイルをCloudWatch Logsにリアルタイム転送したい場合、サイドカーコンテナ(Fluent-Bit)が必要となります。
🚗サイドカーコンテナを使う場合の設定
サイドカーコンテナを利用する場合、以下の設定を追加する必要があります。
-
Fluent Bitの設定ファイル
# fluent-bit.conf の実装例
[SERVICE]
Flush 5
Log_Level info
Daemon off
Parsers_File parsers.conf
[INPUT]
Name tail
Path /mnt/logs/*.log
Refresh_Interval 5
Rotate_Wait 30
Read_from_Head true
Tag app.filelog
[OUTPUT]
Name cloudwatch_logs
Match app.filelog
region ap-northeast-1
log_group_name /ecs/my-app/file-logs
log_stream_prefix app-
auto_create_group true
- サイドカーコンテナ用のタスク定義
// タスク定義の実装例
{
"name": "log-router",
"image": "amazon/aws-for-fluent-bit:latest",
"essential": false,
"cpu": 128,
"memory": 256,
"mountPoints": [
{
"sourceVolume": "log-volume",
"containerPath": "/mnt/logs",
"readOnly": true
}
],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/my-app/fluentbit",
"awslogs-region": "ap-northeast-1",
"awslogs-stream-prefix": "fluentbit"
}
}
}
上記タスク定義の通り、サイドカーコンテナを追加する場合は、vCPUやメモリが追加で必要になります。
ただしFargateでは、タスクのCPUやメモリを自由に設定することが出来ません。
そのため 「サイドカーに0.1vCPUだけ使いたい」という場合でも、タスクとしてはまとまった量(8vCPUなど)を増やさなければならない、といったことが起こりえます。
📃アプリログを標準出力する場合
サイドカーコンテナを使う場合では、追加コストが発生する可能性があります。そこでアプリログを標準出力し、サイドカーコンテナを使わずにCloudWatch Logsへログ転送するようにしました。
公式ドキュメントにもあるように、標準出力されたログはawslogsドライバーを利用することでCloudWatch Logsへ転送可能です。
デフォルトでは、キャプチャされるログは、コンテナをローカルで実行した場合にインタラクティブなターミナルで通常見ることができるコマンド出力を示しており、それは
STDOUTおよびSTDERRI/Oストリームです。awslogsログドライバーは、これらのログをDockerからCloudWatch Logsに単純に渡します。
🪛awslogsドライバーを利用する場合の設定
実際の変更箇所は、以下2点です。
- アプリ側で、ログをファイル出力から標準出力できるようにする
- タスク定義でサイドカーコンテナの設定を削除し、アプリコンテナで
awslogsドライバーを利用するようにする
// awslogsドライバーを利用したタスク定義の実装例
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/sample-app",
"awslogs-region": "ap-northeast-1",
"awslogs-stream-prefix": "ecs"
}
}
サイドカーコンテナを設定したときより、はるかに簡単に設定できるのが分かると思います。
おわりに
アプリログを標準出力するようにしておくことで、開発時の工数と運用コストの両面で、Fargateのコスト削減することが可能になります。