Firelensよくわからんくて吐きそうになったのでメモ。
Firelensはエンジン?にFluentdとFluentbit選べるらしいのだけど、後者のが軽くてよくてみんな使ってるらしいので、Fluentbitを使う。
Firelensは専用のコンテナをサイドカー構成で使う。
サイドカー構成はAWSでも推奨されているとのこと。
タスクが複数ある場合でも、1タスクにつき1サイドカーが推奨されているらしい。(AWSのサポートに聞いた)
[用語]
この記事で独自に使ってる用語
・メインコンテナ: 実際に動かしたいコンテナを指す。自分で作るやつの事
・Firelensコンテナ: サイドカーとして動かすFirelens用のコンテナを指す。
コンテナのログ設定について
以下はCloudFormationで作る時の設定の一部。
ContainerDefinitions:
# Main Container
- Name: !Sub ${ProjectName}-ecs-container
Image: !Ref EcrImage
(省略)
LogConfiguration:
LogDriver: awsfirelens
Options:
Name: s3
bucket: !Ref FirelensS3Bucket
(省略)
# Firelens Container
- Name: log_router
Image: 'public.ecr.aws/aws-observability/aws-for-fluent-bit:init-latest'
LogConfiguration:
LogDriver: awslogs
(省略)
ここでメインコンテナとFirelensコンテナにそれぞれLogConfigurationがいるのが最初ややこしかった。
メインコンテナはログ出力をFirelensに移譲して、Firelensコンテナに対し色々設定欠くんじゃないの?と。
結論から言えば、メインコンテナのLogConfigurationには、出力先が1か所なら、Firelensを通して出力する先を書けるらしい。
要するに便利機能。
上の例ではs3に出力するようにしているけど、後述するFirelensの設定ファイルを使用する方式ならば、これらのOptionsはいらないっぽい。
で、FirelensコンテナのLogConfigurationは、Firelensコンテナ自体のログの出力先。
Firelensの設定ファイルの場所
ECS+Fargate構成の場合、
・AWSが配布しているFirelensコンテナ用のイメージで、
・Firelens設定ファイルを使う場合、
必ず自前で設定ファイルを作り、所定の場所に置いたDockerイメージを作らなくてはいけない…というのはAWSのサポートに聞いた話なんですが、実はそんなことなくて。
public.ecr.aws/aws-observability/aws-for-fluent-bit:init-latest
というイメージを使えば、設定ファイルをS3における見たい。
こちらの設定については、以下で詳しく解説してくれてます。
https://dev.classmethod.jp/articles/external-firelens-config-for-fargate/
上記ではS3見に行くので、タスクロールに以下の権限が必要。
"s3:GetObject",
"s3:GetBucketLocation"
ただ、「Fluentbitの設定ファイルの中で、他の設定ファイルを参照したい」場合は、S3を参照できないので、自前でFirelensコンテナ用のDockerイメージを作らなければいけなそう。
なお、一応Firelensコンテナの以下のパスに、デフォルトの設定ファイルがあるのかな?
/fluent-bit/etc/fluent-bit.conf
Fluentbitの設定ファイルは複数あるとマージされる?のかな?
なので、上記リンクに従って追加の設定ファイルを指定すると、これにマージされるっぽい。
※なんかでマージって読んだ気がしたんすけど、物理的にはマージされないみたいです。「設定が追加される」と思っとけばよさそうです。
この辺りですでに吐きそう。
なんかFirelensコンテナで以下のエラー出てうまくいかなかった。
s3のバケットポリシーでタスクロール許可してないとダメだった。
初心者にはきついで…
[FluentBit Init Process] Cannot download [fluent-bit extra.conf] from s3, retrying...\n
[FluentBit Init Process] Cannot download [fluent-bit extra.conf] from s3\n
あと、CloudWatchにログ出力するなら、以下の権限も必要だった。
タスクロールかタスク実行ロールかは知らない。
logs:DescribeLogStreams
Firelensの設定ファイル
正確には、Fluentbitの設定ファイルですかね。
これが一番吐きました。
なんでか知らないけど、ネット見ても情報がない、オフィシャルのサイト見てもよくわからん…という事で。
上記サイトに図があるんですが、Fluentbitでは主に以下のように処理というか機能というかが分かれていて、それぞれを「プラグイン」と呼ぶのだそうな。
INPUT -> PARSE -> FILTER -> BUFFER -> ROUTER -> OUTPUT
プラグインと聞くと、なんかどっかからDLしてインストールとかしないといけないの?と思っちゃうんですが、とりあえずここではそうではないようですね。
とりあえず、Fluentbit(Firelensの中の人がカスタマイズしてるかも?)にはデフォルトの設定ファイルがあるので、INPUT、BUFFER、ROUTERは無視します。
個人的に
PARSE -> FILTER
が気に入らんのですが、PARSEで設定するPARSERは、INPUTやFILTERから使うもののようです。
タグ
FirelensでFluentbitデビューする全人類に知っておいてほしいんですが、Fluentbitでは「タグ」を目印に色々処理します。
Firelensでは、多分デフォルトの設定ファイルに[INPUT]の設定があって、その中で「*-firelens-*」形式でタグが降られているようです。
[FILTER]や[OUTPUT]ではこのタグをもとにあれしたりこれしたりするんですが、嫌な事に、Firelensを使っているとこのタグは目に見えるところに出てこないみたいなんですよね。
例えば、DockerでFluentbit動かしたりすると、コンソールに以下のように出るのですよ。
[0] log2: [[1721737572.870773537, {}], {"log"=>"test"}]
この例では「log2」というのがタグです。
ただ、FirelensでCloudwatchやらに出力したりすると、{"log"=>"test"}の部分しか見えません。
[FILTER]や[OUTPUT]では、処理を行う対象をMatchで指定するのですが、そのMatchではタグ(正規表現可)を指定することになります。
逆に言えば、例えば3種類のログが標準出力経由で送られて来て、それを異なる場所に送りたいときは、うまいことやって別々のタグをつける必要があるという事です。
Fluentbitでは、標準出力からログを拾おうが何しようが、JSON形式で送られてくるようです。
上の例のように、キーが「log」のところに実際のログが入ってきます。
Fluentbitがエラーを吐く場合、Firelensコンテナの定義に以下を追加すれば、デバッグログが見れる。
Environment:
- name: FLB_LOG_LEVEL
value: debug