この記事は
Amazon EKSで稼働するfluent-bitから同EKSクラスタで稼働するPodのログをCloudWatch LogsとData Firehoseへ転送する設定について記します。
2ヶ所にログ転送を行う場合に大事な部分についても併せて記します。
環境
Amazon EKS 1.27
fluent-bit(aws-for-fluent-bit 2.31.12)
Amazon Data Firehose
CloudWatch Logs
fluent-bit.conf
まずは最低限の設定を記載し解説していきます。
[SERVICE]
Flush 1
Daemon Off
Log_Level info
Parsers_File parsers.conf
[INPUT]
Name tail
Path /var/log/containers/*.log
Parser cri
Tag kube.*
Mem_Buf_Limit 5MB
[FILTER]
Name kubernetes
Match kube.*
[FILTER]
Name rewrite_tag
Match kube.*
rule $log (.*ERROR.*|.*FATAL.*) to-firehose false
[OUTPUT]
Name cloudwatch_logs
Match kube.*
region ap-northeast-1
log_group_name /eks/$(kubernetes['namespace_name'])/$(kubernetes['pod_name'])
log_stream_name $(kubernetes['namespace_name'])/$(kubernetes['container_name'])
auto_create_group On
retry_limit false
[OUTPUT]
Name kinesis_firehose
Match to-firehose
region ap-northeast-1
delivery_stream firehose.stream.name
parsers.conf
バージョン1.24以降のEKSクラスタはdockerではなくcontainerdを使うのでログパーサーはcriを利用します。
parsers.confに含まれているのでそちらを利用します。
[PARSER]
# http://rubular.com/r/tjUt3Awgg4
Name cri
Format regex
Regex ^(?<time>[^ ]+) (?<stream>stdout|stderr) (?<logtag>[^ ]*) (?<message>.*)$
Time_Key time
Time_Format %Y-%m-%dT%H:%M:%S.%L%z
Time_Keep On
Kubernetes フィルター
Kubernetesフィルターを通すことで、次のようなメタデータをログに含められます。
- Pod Name
- Namespace
- Container Name
- Container ID
もう一つ嬉しいことがあって、fluent-bit.confのCloudWatch Logsへ転送するセクションでメタデータを変数のように呼び出すことができるようになります。CloudWatch Logsのロググループ名やログストリーム名にNamespaceやPod Nameを付与することで動的な名前のリソースを作成できます。
rewrite_tag フィルター
rewrite_tagフィルターでは任意の文字列が含まれる場合など条件に合致したらタグを変更できます。
criパーサーを通ったログのメッセージは$message
に格納されています。$message
のメッセージ文字列にERRORまたはFATALが含まれていたら、タグをto-firehose
に変更します。
rule $message (.*ERROR.*|.*FATAL.*) to-firehose false
CloudWatch LogsとFirehoseへの転送
[OUTPUT]
Name cloudwatch_logs
Match kube.*
region ap-northeast-1
log_group_name /eks/$(kubernetes['namespace_name'])/$(kubernetes['pod_name'])
log_stream_name $(kubernetes['namespace_name'])/$(kubernetes['container_name'])
auto_create_group On
retry_limit false
[OUTPUT]
Name kinesis_firehose
Match to-firehose
region ap-northeast-1
delivery_stream firehose.stream.name
kubernetesフィルター
とrewrite_tagフィルター
を通って来たログに付与されたタグによってCloudWatch LogsかFirehoseに転送されます。
rewrite_tagフィルターでタグをto-firehose
に変更されている場合はkinesis_firehoseにマッチします。
そうでないタグを持つログはCloudwatch_logsにマッチします。
もう一つのパターンとしてrewrite_tagフィルターのtrue/false部分がtrueだった場合には、タグがkube.*
とto-firehose
の2種類のログがフィルターから出ていきます。
rule $message (.*ERROR.*|.*FATAL.*) to-firehose true
つまり、全てのログはCloudWatch Logsに転送され、メッセージ文字列にERRORまたはFATALを含むログだけFirehoseへ転送する動作に変わります。
ここで気を付けておきたいのは、rewrite_tagフィルターでログの複製が生まれることでその分のメモリリソースが消費されてしまう点です。fluent-bitのログやコンテナ内のリソース状況を確認し、枯渇しそうであればリソース割り当て量を増やす対応が必要です。
もしリソース枯渇が発生してしまった場合はログ転送の遅延だけでなく、Podを強制的に終了させるOOM Killer(Out of Memory)が発生します。
おわりに
ログの用途によって転送先を分けることで障害調査をしやすくすることもできますし、不要なログを省くこともできる便利な機能の紹介でした。
以上です。