Oct 8, 2024
Oct 8, 2024
N/A Views
MD

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
Found a mistake? Update the entry.
Share this article: