FireLensにおける、以下のタスクメモリ不足エラーを徹底解説します。
The total amount of memory allocated at the task level must be greater than the amount of memory allocated for all containers in addition to the memory buffer limit for the FireLens log driver.
⚡TL;DR
-
原因 :
- タスク全体のメモリが、「コンテナのメモリ合計 + FireLens ログドライバのバッファ(log-driver-buffer-limit)」より小さい
- タスク定義の作成時にこのエラーが出る場合、コンテナのメモリ合計 = タスク全体のメモリとなっている可能性が高い
-
対処 :
- タスクメモリを増やす
- コンテナメモリを減らす
🔰エラーメッセージの意味を解説
The total amount of memory allocated at the task level must be greater than the amount of memory allocated for all containers in addition to the memory buffer limit for the FireLens log driver.
このメッセージを翻訳すると、以下のようになります。
タスクレベルで割り当てられるメモリの総量は、FireLensログドライバのメモリバッファ制限に加えて、すべてのコンテナに割り当てられるメモリ量よりも大きくなければなりません。
つまりタスク定義におけるタスクレベルの memory が、
-
各コンテナの
memoryの合計(ハードリミット) -
FireLensログドライバのメモリバッファ(
log-driver-buffer-limitで指定)
の合計値を下回っていることを示しています。
一方でAWS公式ドキュメントには、タスク・コンテナ・ログドライバのメモリの関係性について、次のような記載があります。
タスクレベルで割り当てられるメモリの合計量は、ログドライバーのメモリバッファに加えて、すべてのコンテナに割り当てられたメモリ量よりも大きくなければなりません。
すなわち、タスクレベルの合計メモリは、コンテナのメモリ総量+ログドライバのバッファより大きくなければならないのです。
📝FireLensの「メモリバッファ」とは?
そもそも、FireLensログドライバの「メモリバッファ」とは何でしょうか?
FireLens(awsfirelens)は ECS におけるログルーターのひとつで、コンテナのログを外部(例:Kinesis Firehose、CloudWatch Logs、S3など)へ転送する機能を持ちます。
このFireLensは高スループットや転送遅延に備え、ログを一時的にメモリに貯める仕組み(バッファ) を持っており、これをメモリバッファと呼んでいるのです。
🔍FireLensバッファ設定の注意点
バッファのメモリ上限は、タスク定義の log-driver-buffer-limit で設定します。
このメモリは タスクメモリから確保 されるので、ログ転送用の サイドカー(Fluent Bit)コンテナの memory を増やしても意味がなく、タスク側にメモリの余裕を持たせる必要があります。
さらに設定の際、以下についても考慮する必要があります。
-
単位 : より厳密には、
log-driver-buffer-limitは「メモリにバッファリングされるログ行数の上限」を指定します。1
-
計算式 : バッファの消費メモリは「平均ログ行サイズ × バッファの行数」で決まります。使用されるメモリは平均ログ行サイズに依存します。なおデフォルトのログ行数は
1048576行です。 -
目安 : 公式ドキュメント1では、平均的なログサイズを 2 KiB/行としており、
4096行で最大 ~8 MiBの消費を目安としています。 - タスク定義の作成時に今回のエラーが発生した場合、そもそも 「タスクレベルのメモリ = コンテナのメモリ合計」 となっており、メモリバッファが全く確保できなくなっている可能性があります。
🚀エラーの解決方法
解決策1.タスクメモリを増やす(安定重視)
- Fargateプリセットの範囲でタスク
memoryを上げましょう - 特にスパイク(ログ量急増)時の安定性が増します
解決策2.コンテナ memory を最適化(コスト重視)
- メインアプリが実際に使用していないメモリがあるなら、OOMにならない範囲で ハードリミットを縮小しましょう
🚩実装例
タスク定義の実装例サンプルを共有します。
{
// タスクレベル(Fargateプリセット)
"cpu": "8192", // 8 vCPU
"memory": "32768", // 32 GB
"containerDefinitions": [
{
"name": "app",
"cpu": 7680, // 相対値(重み付け)
"memory": 30720, // 30GBのハードリミット(絶対値)
"logConfiguration": {
"logDriver": "awsfirelens",
"options": {
"Name": "firehose",
"region": "ap-northeast-1",
"delivery_stream": "my-stream",
"log-driver-buffer-limit": "4096"
// ← 行数(AWS公式は行数として説明)。
// 平均 2 KiB/行なら最大 ~8 MiB を消費。
// タスクメモリは、コンテナ合計 + このバッファを上回る必要あり。
}
}
},
{
"name": "log-router",
"image": "public.ecr.aws/aws-observability/aws-for-fluent-bit:stable",
"cpu": 512,
"memory": 1024, //1GBのハードリミット(絶対値)
"firelensConfiguration": { "type": "fluentbit" }
}
]
}
バッファで消費しうる最大メモリ(例:~8 MiB)を考慮し、タスク
memory(32 GB)がコンテナ合計(30+1 = 31GB)+バッファを明確に上回るように調整。
-
高スループットの Amazon ECS ログの設定 > タスク定義を作成する際は、値 (log-driver-buffer-limit) を指定することで、メモリにバッファリングされるログの行数を指定できます。 ↩ ↩2