K8sのログをfluent-bitでrsyslogに転送する際に、structured dataを含めて適切に設定されてるサンプルが見つからなかったのでメモです。
rsyslogの設定
rsyslogはOSにプリインストール済みのことが多いです。次のコマンドでrsyslogの状態を確認できます。
$ sudo service rsyslog status
Redirecting to /bin/systemctl status rsyslog.service
● rsyslog.service - System Logging Service
Loaded: loaded (/usr/lib/systemd/system/rsyslog.service; enabled; vendor preset: enabled)
Active: active (running) since Tue 2024-10-08 09:38:33 JST; 6min ago
Docs: man:rsyslogd(8)
https://www.rsyslog.com/doc/
Main PID: 526 (rsyslogd)
Tasks: 3 (limit: 128204)
Memory: 1.9M
CGroup: /system.slice/rsyslog.service
└─526 /usr/sbin/rsyslogd -n
Oct 08 09:38:33 syslog systemd[1]: Starting System Logging Service...
Oct 08 09:38:33 syslog rsyslogd[526]: [origin software="rsyslogd" swVersion="8.2102.0-15.el8" x-pid="526" x-info="https://www.rsyslog.com"] start
Oct 08 09:38:33 syslog rsyslogd[526]: imjournal: No statefile exists, /var/lib/rsyslog/imjournal.state will be created (ignore if this is first run): No such file or direc
tory [v8.2102.0-15.el8 try https://www.rsyslog.com/e/2040 ]
Oct 08 09:38:33 syslog systemd[1]: Started System Logging Service.
Oct 08 09:38:33 syslog rsyslogd[526]: imjournal: journal files changed, reloading... [v8.2102.0-15.el8 try https://www.rsyslog.com/e/0 ]
インストールされていない場合は、以下のコマンドでインストールできます。
sudo yum install rsyslog
rsyslogは以下のバージョンを試しました。
$ rsyslogd -v
rsyslogd 8.2102.0-15.el8 (aka 2021.02) compiled with:
PLATFORM: aarch64-redhat-linux-gnu
PLATFORM (lsb_release -d):
FEATURE_REGEXP: Yes
GSSAPI Kerberos 5 support: Yes
FEATURE_DEBUG (debug build, slow code): No
32bit Atomic operations supported: Yes
64bit Atomic operations supported: Yes
memory allocator: system default
Runtime Instrumentation (slow code): No
uuid support: Yes
systemd support: Yes
Config file: /etc/rsyslog.conf
PID file: /var/run/rsyslogd.pid
Number of Bits in RainerScript integers: 64
See https://www.rsyslog.com for more information.
/etc/rsyslog.confを開いて、次のコメントを外します。
module(load="imtcp") # needs to be done just once
input(type="imtcp" port="514")
また、rfc5424のSTRUCTURED-DATAを出力するために、次の設定を削除し、
# Use default timestamp format
module(load="builtin:omfile" Template="RSYSLOG_TraditionalFileFormat")
代わりに、次の設定を追記ます。
module(load="builtin:omfile" Template="RSYSLOG_SyslogProtocol23Format")
rsyslogを再起動します。
sudo service rsyslog restart
次のコマンドでログを追尾します。
sudo tail -f /var/log/messages
動作確認します。 別の端末からtelnetでrsyslogサーバーにアクセスして、rfc5424形式のログを送ります。
$ telnet <syslog server IP> 514
Trying *.*.*.*...
Connected to *.*.*.*.
Escape character is '^]'.
<14>1 2021-07-12T14:37:35.569848Z myhost myapp 1234 ID98 [uls@0 logtype="access" clustername="mycluster" namespace="mynamespace"] Sample app log message.
tailしていたrsyslog側にも同様に次のログが出力されていればOKです。
<14>1 2021-07-12T14:37:35.569848Z myhost myapp 1234 ID98 [uls@0 logtype="access" clustername="mycluster" namespace="mynamespace"] Sample app log message.
module(load="builtin:omfile" Template="RSYSLOG_TraditionalFileFormat")の設定が残ったままだと、次のような出力になります。
Jul 12 14:37:35 myhost myapp[1234] Sample app log message.
fluent-bitの設定
本質的でないですが、fluent-bitはTanzu (Carvel) Packageでインストールします。本記事でポイントとなるのはfluent-bit自体の設定であり、どの方法でインストールしても大差ありません。
Helmなどでインストールする場合でも同様な設定で転送できると思われます。
Note
Tanzu Packageをセットアップする方法はこちらの記事を参考にしてください。本記事では以下のrepositoryが設定済みの前提です。
tanzu package repository add tanzu-standard \
--url projects.registry.vmware.com/tkg/packages/standard/repo:v2024.8.21 \
--namespace tanzu-install --create-namespace
以下の設定ファイルを作成します。<syslog server IP>の箇所を書き換えてください。
cat <<'EOF' > fluent-bit-values.yaml
---
namespace: tanzu-system-logging
fluent_bit:
config:
service: |
[SERVICE]
Daemon Off
Flush 1
Log_Level info
Parsers_File parsers.conf
Health_Check On
HTTP_Server On
HTTP_Port 2020
HTTP_Listen 0.0.0.0
inputs: |
[INPUT]
Name tail
Path /var/log/containers/*.log
DB /var/log/flb_kube.db
parser cri
Tag kube.*
Mem_Buf_Limit 5MB
Skip_Long_Lines On
parsers: |
[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
filters: |
[FILTER]
Name kubernetes
Match kube.*
Kube_URL https://kubernetes.default.svc.cluster.local:443
Kube_CA_File /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
Kube_Token_File /var/run/secrets/kubernetes.io/serviceaccount/token
Kube_Tag_Prefix kube.var.log.containers.
Merge_Log On
Merge_Log_Key log_processed
Keep_Log Off
K8S-Logging.Parser On
K8S-Logging.Exclude On
[FILTER]
Name lua
Match *
call add_structured_data
code function add_structured_data(tag, timestamp, record) new_record = record new_record["k8s@8"] = {} new_record["k8s@8"]["node"] = record["kubernetes"]["host"] new_record["k8s@8"]["app"] = record["kubernetes"]["labels"]["app"] new_record["k8s@8"]["container_image"] = record["kubernetes"]["container_image"] return 1, timestamp, new_record end
[FILTER]
Name nest
Match *
Operation lift
Nested_Under kubernetes
outputs: |
[OUTPUT]
Name syslog
Match *
Host <syslog server IP>
Port 514
Mode tcp
Syslog_Format rfc5424
Syslog_Hostname_key namespace_name
Syslog_Appname_key pod_name
Syslog_Procid_key container_name
Syslog_Message_key message
Syslog_SD_key k8s@8
---
EOF
次のコマンドでfluent-bitをインストールします。
tanzu package install -n tanzu-install fluent-bit -p fluent-bit.tanzu.vmware.com -v 2.1.6+vmware.2-tkg.1 --values-file fluent-bit-values.yaml
rsyslog側に次のようなログが出力されればOKです。
<14>1 2024-10-08T01:10:01.231783Z harbor harbor-portal-d6c99f896-2v8zm portal - [k8s@8 node="kind-worker2" container_image="docker.io/goharbor/harbor-portal:v2.11.1" app="harbor"] 10.244.2.1 - - [08/Oct/2024:01:10:01 +0000] "GET / HTTP/1.1" 200 785 "-" "kube-probe/1.30"
<14>1 2024-10-08T01:10:02.539216Z harbor harbor-registry-59f445685-7ltfq registryctl - [k8s@8 node="kind-worker3" container_image="docker.io/goharbor/harbor-registryctl:v2.11.1" app="harbor"] 10.244.1.1 - - [08/Oct/2024:01:10:02 +0000] "GET /api/health HTTP/1.1" 200 9
<14>1 2024-10-08T01:10:04.894222Z harbor harbor-registry-59f445685-7ltfq registry - [k8s@8 node="kind-worker3" container_image="docker.io/goharbor/registry-photon:v2.11.1" app="harbor"] 10.244.1.1 - - [08/Oct/2024:01:10:04 +0000] "GET / HTTP/1.1" 200 0 "" "kube-probe/1.30"
<14>1 2024-10-08T01:10:05.741468Z kube-system kindnet-ltt8c kindnet-cni - [k8s@8 app="kindnet" node="kind-worker" container_image="docker.io/kindest/kindnetd:v20240813-c6f155d6"] I1008 01:10:05.741186 1 main.go:295] Handling node with IPs: map[192.168.228.4:{}]
<14>1 2024-10-08T01:10:05.741488Z kube-system kindnet-ltt8c kindnet-cni - [k8s@8 app="kindnet" node="kind-worker" container_image="docker.io/kindest/kindnetd:v20240813-c6f155d6"] I1008 01:10:05.741220 1 main.go:322] Node kind-control-plane has CIDR [10.244.0.0/24]
必要に応じでadd_structured_dataのコードを修正してください。
Tip
設定更新時に設定が反映されない場合は次のコマンドでfluent-bitを再起動してください。
kubectl rollout restart ds/fluent-bit -n tanzu-system-logging