2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

EKS -> Cloudwatchのログ転送を FluentD から Fluent Bit に移行する

Last updated at Posted at 2023-01-28

移行しました

サマリー

EKSのアプリケーションログをCloudwatchに転送するのに使っていたFluentDをFluent Bitに置き換えました。
この時に、公式ドキュメントだけでは痒い所に手が届かない情報しか載っていなかったので苦労した部分を共有します。

FluentDからFluent Bitへの移行が推奨されています

数年前にEKSクラスタ上で動かすアプリケーションのログを、FluentDを使ってCloudwatchに集約できるようにしました。その時の記事は↓↓↓です。

この設定をしてから約3年半ずっとログはこれで取れていました。
ところが先日、EKSのKubernetesのバージョンを1.22から1.25まで上げたところ、ログがとれない状態に。
原因を調べている中で、今はもうFluentDを使うことが非推奨になっていることを知ります。
ログがとれない原因究明は時間の無駄になりそうなのでやめて、先にFluent Bitへの移行を進めることにしました。

Container Insights の FluentD のサポートは現在メンテナンスモードになっています。つまり、AWS はこれ以上 FluentD の更新を提供せず、近い将来に非推奨にする予定です。
(中略)
可能な限り Container Insights で FluentBit を使用するように移行することを強くお勧めします。Container Insights のログフォワーダとして FluentBit を使用すると、パフォーマンスが大幅に向上します。

(オプション) CloudWatch Logs へログを送信する DaemonSet として FluentD を設定する

Fluent Bitへの移行について

移行手順

基本的には公式ドキュメント

がベースになりますが、ちょっとこれだけだと融通がきかないです。

公式ドキュメントでは、Fluent Bit用の設定ファイルを直接適用するように書かれています。

次のいずれかのコマンドを実行して、Fluent Bit daemonset をクラスターにダウンロードしてデプロイします。

しかし、このファイルをそのまま適用すると不便なところがあります。そこで、いきなり適用するのではなく手を入れることにします。

ドキュメントには「より Fluentd に似ている Fluent Bit の設定」という候補があるのですが、少なくとも私の環境では全く似ていなかったので、「Fluent Bit 最適化設定」の方を使いました。

まずは、次のファイルをダウンロードしましょう。

ログのパース方法を変える

デフォルトでは、ログは「CRI形式」で出力されます。
これはAWSの配っているサンプルの設定では、単なるテキストとして集約されます。

before.png

なのでこれをパースして、構造化されたデータにします。

after.png

parsers.confを設定している部分に

[PARSER]
    Name        cri
    Format      regex
    Regex       ^(?<time>[^ ]+) (?<stream>stdout|stderr) (?<logtag>[^ ]*) (?<log>.*)$
    Time_Key    time
    Time_Format %Y-%m-%dT%H:%M:%S.%L%z

というのを足します。

そして、application-log.confを設定している部分で、dockerを利用している部分を全てcriに置き換えます。

Parser              docker

Parser              cri

に。

参考リンク:
https://progret.hatenadiary.com/entry/2022/04/24/102737

ログストリーム名を変える

「Fluent Bit 最適化設定」では、デフォルトで

kubernetes-nodeName-application.var.log.containers.kubernetes-podName_kubernetes-namespace_kubernetes-container-name-kubernetes-containerID

という名前になります。

私の希望としては、Podを跨いで同じアプリケーションのログは同じログストリームに集約したいです。エラーログを確認したいときにコンテナのIDごとにログストリームが分かれていると探すのが大変だからです。(本来ならElasticsearchとかで集約すべきなんでしょうか?)

    [OUTPUT]
        Name                cloudwatch_logs
        Match               application.*
        region              ${AWS_REGION}
        log_group_name      /aws/containerinsights/${CLUSTER_NAME}/application
        log_stream_prefix   ${HOST_NAME}-
        log_stream_template $kubernetes['labels'] ['app'].$kubernetes['namespace_name'] // ここ!
        auto_create_group   true
        extra_user_agent    container-insights

答えとしては、log_stream_templateというのを指定します。
ただし、フォールバック用にlog_stream_nameまたはlog_stream_prefixの指定を残しておく必要はあります。

log_stream_templateは、Record Accessorという書き方をすることになります。

ドキュメント中には記載がないのですが、ハイフンの使用には制限があるようです。
本来なら、アプリ名-環境名でログを集約したかったのですが、アプリ名.環境名としました。

まとめ

そして最後に、

kubectl apply -f fluent-bit.yaml

で設定を適用すれば、望むログストリーム名でパースされたログがFluent BitによってCloudwatchに転送されます。

あとは、FluentDのDaemonSetを消しましょう。


お仕事のご相談はこちらから

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?