FireLens(Fluent Bit)コンテナが Key has an empty value で起動できないときの原因と対処方法

FireLens(Fluent Bit)以外にもECSのタスク定義も疑ってみよう。
2021.07.20

FireLens(Fluent Bit)コンテナがKey has an empty valueのエラーで起動しない状況を調査する機会がありました。同エラー発生時の切り分けの参考用にまとめておきます。

検証環境

項目 バージョン
aws-for-fluent-bit 2.17.0
Fluent Bit 1.8.1
Fargate platform 1.4.0

以下のブログポストで紹介されているCloudFormationのテンプレートで構築した環境です。

状況

タスクを実行すると停止理由がTask failed to startで、アプリケーションコンテナ(webapp)と、FireLensコンテナ(log_router)共にSTOPPEDで起動できませんでした。

FireLensコンテナ自身のログ保存先は、log driverの設定をawslogsに設定してあるためCloudWatch Logsに保存されてます。CloudWatch LogsからFireLensコンテナの起動時のログを確認してみます。

Error Message

[ Error] Error in line 29: Key has an empty value

FireLensコンテナが起動に失敗するなんて、カスタムログルーティング用の設定ファイルにミスがあるのでは?と疑いたくなります。今回の検証環境ではカスタムログルーティングの設定はしていません。素のFireLensイメージ(aws-for-fluent-bit)なのに起動に失敗しています。

原因

Key has an empty valueとは、一体どこのKeyに対するValueが空と言っているのでしょうか。

アプリケーションコンテナのlog driverをawsfirelensに変更した後のオプションにKey=Name, Velue=""のことでした。管理コンソールから手動でタスク定義を作成し、log driverをawslogsからfirelensに変更すると、デフォルトの初期値としてNameキーが空のまま残ります。手動で設定する場合は気をつけないと見落とすかもしれません。

タスク定義をJSONでみると以下の箇所です。

            "logConfiguration": {
                "logDriver": "awsfirelens",
                "options": {
                    "Name": ""
                }
			},
...snip...
      "memoryReservation": null,
      "volumesFrom": [],
      "stopTimeout": null,
      "image": "public.ecr.aws/nginx/nginx:latest",

対処

空のNameキーを削除します。不要なキーを削除するこれだけです。

タスク定義をJSONからみるとこうなります。

            "environmentFiles": [],
            "logConfiguration": {
                "logDriver": "awsfirelens"
            },
            "entryPoint": [],

Nameキー以外が空だったら?

NameキーをTestに変更し、値は空にしてタスク定義を作成しタスクを実行してみます。

停止理由は見切れていますが、Nameキーが空ときとは異なり停止理由に説明があります。ちなみにlog_routerのコンテナは起動すらしていないため、CloudWatch Logsにログが一切記録されていませんでした。キー名の違いにより挙動が異なることはわかりました。

停止理由が見切れるためAWS CLIから確認してみます。停止したタスクIDが欲しいので停止したもの一覧を出力します。

aws ecs list-tasks \
    --cluster minimum-test-cluster \
	 --desired-status STOPPED

実行結果

{
    "taskArns": [
        "arn:aws:ecs:ap-northeast-1:123456789012:task/minimum-test-cluster/049feed3cea24451b2ae3803b8955b20",
        "arn:aws:ecs:ap-northeast-1:123456789012:task/minimum-test-cluster/0b35e9af59e14f47bb7351a02f0b0e67"
    ]
}

特定のタスクIDから停止理由のみフィルターしてメッセージを確認します。

aws ecs describe-tasks \
     --cluster minimum-test-cluster \
     --tasks arn:aws:ecs:ap-northeast-1:123456789012:task/minimum-test-cluster/049feed3cea24451b2ae3803b8955b20 \
	 --query 'tasks[0].stoppedReason'

結局メッセージ全文は確認できませんでした。

実行結果

"InternalError: unable to generate fireLens config file: unable to generate fireLens config content: unable to generate fluent config output section: unable to apply log options of container webapp to fireLens config: missing output key Name which is re..."

おわりに

Fluent Bitや、FireLensというよりはECS Fargateのタスク定義の問題だったのですが、エラーメッセージの内容だけで特定するのはなかなか難しいですね。