EKS FargateのFluentBitの組み込みログルータでCloudwatchLogsへ出力する際の課題
ありがたいことに、EKS FargateにはFluentBitが予め組み込まれており、ConfigMapを適用するだけでCloudwatchLogsやその他のターゲットへログ出力ができる。
しかしながら一つ残念な点として、filterにKubernetesの指定ができない。
以下ドキュメントに記載がある。(最新の内容は英語版で見るのが吉)
Fargate validates against the following supported filters: grep, parser, record_modifier, rewrite_tag, throttle, nest, and modify.
filterにKubernetesの指定ができないと、Podやコンテナの情報が拾えない。
これで何が困るかというと、CloudwatchLogsに出力するような場合、ログストリーム名の動的生成がやりにくくなる。
Container Insightsでは、DaemonSetとしてFluentdをデプロイして、その設定ファイル内に以下のようなフィルタを指定可能だった。
<filter **>
@type kubernetes_metadata
@id filter_kube_metadata_systemd
</filter>
こうすると、以下のような情報を拾うことができた。
"kubernetes": {
"container_name": "container_name",
"namespace_name": "namespace_name",
"pod_name": "container_name-65ccfb4d4c-4zdlf",
"container_image": "111111111111.dkr.ecr.ap-northeast-1.amazonaws.com/container_name-golang:tag",
"container_image_id": "docker-pullable://111111111111.dkr.ecr.ap-northeast-1.amazonaws.com/image_name@sha256:xxxxxxxxxxxxxxxxxxx",
"pod_id": "xxxxxxxx-496e-4864-ad51-f12b246275f4",
"host": "ip-xx-xx-xx-xx.ap-northeast-1.compute.internal",
"labels": {
"app": "container_name",
"env": "develop",
"pod-template-hash": "xxxxxxxxxxx"
},
"master_url": "https://172.20.0.1:443/api",
"namespace_id": "xxxxxxxxxx-4311-4263-91a8-76765fd44b32",
"namespace_labels": {
"env": "develop"
}
},
これらの情報から、ストリーム名を動的に作成可能であったのだが、これと同様のことがFargateに組み込まれているFluentBitではできないということになる。(2021/08/23現在)
ストリーム名は、なるべく簡潔でわかりやすく、かつ同じworkload(deploymentなど)のPodは同じストリームへ出力したいなど、結構柔軟に整備したいところ。
現状でこれをやろうとすると、アプリケーション側でアプリ名や環境名などを出力する必要がある。
新規構築なら問題ないけど、既存で沢山のworkloadを抱えている状態なので、もう少し何かスマートな解決策がないものか。
悩み中。
FluentBitのConfigMapを更新した場合、既存のPodに対して適用するためにはPodを再起動する必要がある。
反映されないなーって時は、rollout restartするべし。
Important
Amazon EKS Fargate logging doesn't support dynamic configuration of ConfigMaps. Any changes to ConfigMaps are applied to new pods only. Changes aren't applied to existing pods.
ストリーム名は、なるべく簡潔でわかりやすく、かつ同じworkload(deploymentなど)のPodは同じストリームへ出力したいなど、結構柔軟に整備したいところ。
もしかすると、この要件に固着しすぎているのかもしれないと思い始めた。
ConfigMapのOutputにて、log_stream_prefixをすると、以下のような形式のストリームが作成される。
<log_stream_prefix>kube.var.log.containers.<pod_name>_<namespace>_<container_name>-<container_id>.log
直近のログ閲覧時は最新のストリームを選択して、検索時にはログストリーム名で絞り込む、ということにもできる。
検索はContainerInsightsだと以下のようにしてできそうではある。
fields @timestamp, @message
| filter @logStream LIKE /<log_stream_prefix>kube.var.log.containers.<workload_name>*/
| sort @timestamp desc
| limit 20
とはいえ、検索時にコストがかかるのが気になるし、扱い方もやや直感的じゃないので、あまりAWSやCloudwatch Logsに明るくないアプリケーションエンジニアに扱ってもらう際のハードルもあるなあ。
このへんを見る限り、目下対応中の様子。
しばらく待ってみた方がいいかな。