FireLens(Fluent Bit)のカスタムログルーティングで「cannot increase buffer: current=4096 requested=36864 max=4096」が出力したときの対策

2021.09.16

Fluent Bitからkinesis_firehoseプラグインを利用し、Kinesis Data Firehose経由でS3バケットへログを保存しています。Fluent Bitを起動しているFireLnesのログに以下の警告メッセージが出力されたときの原因と対策を紹介します。

メッセージ

[ warn] [http_client] cannot increase buffer: current=4096 requested=36864 max=4096

原因

  • Fluent Bit v1.8.0 - 1.8.6(※) と、Firehose用のプラグイン(kinesis_firehose)の組み合わせによる問題の可能性が高い
  • aws-for-fluent-bitのバージョンが2.19.1(2021/9/16時点最新)のFluent Bitのバージョンは1.8.6

※ 同じ1.8.6でも今回の問題に対するパッチが含まれていない時期が存在する

対策

aws-for-fluent-bit 2.19.1と、Firehose用の新プラグイン(kinesis_firehose)の組み合わせはこの問題の対象となる。

暫定対応

  • プラグイン(firehose)を利用して回避
    • 動作検証したところ同警告メッセージは確認されなかった
  • aws-for-fluent-bit:stableを利用して回避
    • Fluent Bit のバージョンは 1.7.9(2021/9/16時点)
    • 新プラグインkinesis_frehose)でも同警告メッセージは確認されなかった

今後

aws-for-fluent-bitが2.19.1以降になると、最新のFluent BitのソースコードからビルドしたFluent Bitが使われるため解消する見込み。 アップデート確認次第、確認して追記します。

補足

警告メッセージが頻発した後、Fluent Bitコンテナは以下のログを残して落ちることもあります。多くの場合はタスク定義でessentialtrueにしているため、ログルータのFluent Bitコンテナが落ちると同時にアプリケーションコンテナも落ちる動きをします。つまり、この警告メッセージによりタスクが停止する可能性があります。

[engine] caught signal (SIGSEGV)

状況

AWS Fargateで起動しているアプリケーションコンテナのカスタムログルーティングにFireLensを利用しています。FireLensで起動するログルーティング用のコンテナはFluent Bit(aws-for-fluent-bit)を利用し、Flunet Bitの設定でCloudWatch Logsと、Kinesis Data Firehoseへログを振り分けて保存する構成をとっています。

ログルータのFluent Bitと、エラー再現設定

Dockerfile

FROM public.ecr.aws/aws-observability/aws-for-fluent-bit:2.19.1
COPY ./extra.conf /fluent-bit/etc/extra.conf

Flueshは意図的に120秒にしています。ログの送信間隔を遅くし、ログを長く溜め込むことで今回のエラーを再現が容易にできそうという目論みです。

extra.conf

[SERVICE]
    Flush 120
    Grace 30

[FILTER]
    Name grep
    Match webapp-firelens*
    Exclude log ^(?=.*ELB-HealthChecker\/2\.0).*$

[OUTPUT]
    Name cloudwatch
    Match webapp-firelens*
    region ap-northeast-1
    log_group_name /$(ecs_cluster)
    log_stream_name App/$(ecs_task_id)
    auto_create_group true

[OUTPUT]
    Name kinesis_firehose
    Match webapp-firelens*
    region ap-northeast-1
    delivery_stream sample4-dev-delivery-stream

負荷をかけるとエラーを再現できました。

[ warn] [http_client] cannot increase buffer: current=4096 requested=36864 max=4096

FireLensコンテナのログを確認すると警告メッセージが頻発しています。

情報収集

2021年9月10日に原因調査していました。1か月以上前にFluent BitのIssuesに本件のバグレポートが上がっていました。

運良く2日前にパッチがマージされていました。マージはされましたがFluent Bitのバージョンに変わりはなく1.8.6のままであることを確認できました。

早々に解決できたと思いきや

まだ問題があった

FireLensで利用しているFluent BitはオリジナルのFluent Bitではなくaws-for-fluent-bitを使用しています。

aws-for-fluent-bitとは

Amazon Linux2をベースイメージにFluent Bitと、CloudWatch Logsや、Kinesis Data Firehoseなどの使うであろうプラグインを同梱してくれたイメージです。AWSから提供されています。

イメージ入手先

イメージはECR Public Galleryか、Docker Hubから入手可能です。現時点のaws-for-fluent-bitの最新バージョンはv2.19.1です。

Fluent Bitのバージョンは

aws-for-fluent-bit v2.19.1 イメージのFluent Bitのバージョンを何か知りたいです。ECR Public Gallery、Docker Hubにはビルド済みのイメージがアップロードされています。ビルド元となったDockerfileを確認したところFluent Bitは1.8.6が指定されていることがわかりました。

今直面している問題に対するパッチがあたったFluent Bitのバージョンも 1.8.6です。

まだ気になる点があります。

Fluent Bitがソースコードからビルドされたのはいつ?

aws-for-fluent-bit v2.19.1 内のFluent Bitはいつの時点でのソースコードからビルドされたバージョンなのでしょうか。

  • Fluent Bit v1.8.6にパッチがマージされたのは2日前
  • aws-for-fluent-bit v2.19.1がアップロードされたのは7日前

aws-for-fluent-bitのDockerfileを確認するとFluent Bitのソースコードをcloneしています。ということは、7日前時点のソースコードからビルドされたFluent Bit 1.8.6 です。つまり、お目当てのパッチが含まれていないFluent Bit v1.8.6 が動くイメージであることがわかりました。

Dockerfile

# Fluent Bit version; update these for each release
ENV FLB_VERSION 1.8.6
...snip...
RUN git clone https://github.com/fluent/fluent-bit.git /tmp/fluent-bit-$FLB_VERSION/

暫定対応

旧プラグインを利用

Fluent BitからKinesis Data Firehoseへログを送信するためにプラグインを利用しています。現在、Goで書かれた旧プラグイン(firehose)と、Cで書き直されパフォーマンスが向上した新プラグイン(kinesis_firehose)の2種類存在しています。

今回の問題を抱えているのは新プラグイン(kinesis_firehose)とされています。旧プラグイン(firehose)を指定して動作検証して問題なければ旧プラグインを利用するのも有効な回避手段です。私の環境で旧プラグインを切り替えて検証したところ、今回問題の警告メッセージの出力は確認されませんでした。

CloudWatch logsプラグインは新・旧でFluent Bitの設定ファイルに修正が必要になるケースを確認しています。個人の検証範囲ではFirehoseプラグインは現時点では設定ファイルの修正が必要になるケースは確認しておりません。現時点では旧プラグインの利用が手っ取り早い回避方法だと考えています。

よくある質問

旧プラグインのサポートは?などのよくある質問はREADMEを参照ください。

Stableタグのイメージ利用

aws-for-fluent-bitのstableタグはどうでしょうか。Fluent Bitのバージョンは1.7.9でした。今回のバグの対象外とされているバージョンです。

負荷をかけるとエラーは見られますが今回のエラー再現しません。Fluent Bit 1.7 と 1.8 の間にどのようなアップデートがあったのかは把握していないのですが、後方互換性のない機能を使ってない限りはダウングレードも選択肢としてはありではないでしょうか。こちらも動作検証は必要です。

Dockerfile

FROM public.ecr.aws/aws-observability/aws-for-fluent-bit:stable
COPY ./extra.conf /fluent-bit/etc/extra.conf

extra.conf

[SERVICE]
    Flush 120
    Grace 30

[FILTER]
    Name grep
    Match webapp-firelens*
    Exclude log ^(?=.*ELB-HealthChecker\/2\.0).*$

[OUTPUT]
    Name cloudwatch
    Match webapp-firelens*
    region ap-northeast-1
    log_group_name /$(ecs_cluster)
    log_stream_name App/$(ecs_task_id)
    auto_create_group true

[OUTPUT]
    Name kinesis_firehose
    Match webapp-firelens*
    region ap-northeast-1
    delivery_stream sample4-dev-delivery-stream

自前でビルドする

aws-for-fluent-bitのDockerfileを自分でビルドして利用すれば、最新のFluent Bitのソースコードをcloneしビルドするため解消する可能性があります。ただ、自前でベースイメージから管理したくはないため採用しませんでした。近いうちにaws-for-fluent-bitの更新も入ると思っての判断です。

おわりに

aws-for-fluent-bitのアップデートがきて、求めているFluent Bit 1.8.6か、それ以上のバージョンであればきれいに解決できる見込みでいます。またアップデート確認後、追って検証し追記します。暫定対応策の紹介でした。

参考