created: 2022-11-04T01:34:45.357Z

RaspberryPi のログを fluent-bit で GCP に投げるようにする (ansibleで)

fluentd実践入門を読んで、なんでもいいから fluentd でログをルーティングしたくなったので、最小限の構成でラズパイのログを GCP/CloudLogging に投げるようにしてみた。

この2つで構成する。

  • RaspberryPi
  • 無料のGCEインスタンス

RaspberryPi 側

fluent-bit のインストール

tasks:
    - ansible.builtin.apt_key:
        url: https://packages.fluentbit.io/fluentbit.key
        state: present
    - ansible.builtin.apt_repository:
        repo: deb https://packages.fluentbit.io/raspbian/bullseye bullseye main
        state: present
    - ansible.builtin.apt:
        name: fluent-bit
    - ansible.builtin.template:
        src: etc/fluent-bit/fluent-bit.conf
        dest: /etc/fluent-bit/fluent-bit.conf
    notify: restart fluent-bit
    # config.dの下にtemplateしたい設定ファイルを置いておく
    - ansible.builtin.file:
        path: /etc/fluent-bit/config.d
        state: directory
    # tail したいファイルの設定を with_items で並べておく
    - ansible.builtin.template:
        src: "etc/fluent-bit/config.d/tail-template.conf"
        dest: "/etc/fluent-bit/config.d/{{ item.name }}.conf"
      with_items:
        - name: epgstation_EPGUpdater
          path: "/opt/docker-mirakurun-epgstation/epgstation/logs/EPGUpdater/*.log"
        - name: epgstation_Operator
          path: "/opt/docker-mirakurun-epgstation/epgstation/logs/Operator/*.log"
        - name: epgstation_Service
          path: "/opt/docker-mirakurun-epgstation/epgstation/logs/Service/*.log"
      notify: restart fluent-bit
    # pos_file 的な役割をするSQLiteファイルの置き場所
    - ansible.builtin.file:
        path: /dev/shm/fluent-bit/db
        state: directory
handlers:
    - name: restart fluent-bit
        ansible.builtin.systemd:
        name: fluent-bit
        state: restarted

設定ファイル

fluent-bit.conf はこんな感じ。

[SERVICE]
    daemon    Off  # use with systemd

[INPUT]
    Name systemd
    Tag  {{ hostname }}.systemd.*
    DB   /dev/shm/fluent-bit/db/systemd.db
    Read_From_Tail      On
    Strip_Underscores   On

[INPUT]
    Name   kmsg
    Tag    {{ hostname }}.kernel

@INCLUDE config.d/*.conf

[OUTPUT]
    Name    forward
    match   *
    Host    {{ aggregation_host }}

tail-template.conf の中身はこんな感じ。

[INPUT]
    Name    tail
    Tag     {{ hostname }}.{{ item.name }}.*
    Path    {{ item.path }}
    DB      /dev/shm/fluent-bit/db/{{ item.name }}.db

GCP のログ集約サーバ側

google-fluentd を使うと構造化ログなどをよしなにしてくれるようなので、td-agent ではなく google-fluentd を使う。

tasks:
    # google-fluentd
    - name: check if google-fluentd is installed
      stat: path=/opt/google-fluentd
      register: is_google_fluentd_exist
    - name: install google-fluentd
      ansible.builtin.shell: |
        curl -sSO https://dl.google.com/cloudagents/install-logging-agent.sh
        bash install-logging-agent.sh
      when: not is_google_fluentd_exist.stat.exists
    - name: replace google-fluentd-catch-all-config
      apt:
        name: google-fluentd-catch-all-config
        state: absent
    - name: with google-fluentd-catch-all-config-structured
      apt:
        name: google-fluentd-catch-all-config-structured
    - name: check if preserved config-file
      stat: path=/etc/google-fluentd/config.d.bk
      register: is_google_fluentd_configd_exist
    # デフォルトで使わない設定ファイルがいくつも読み込まれるのでどけておく  
    - name: "preserve default google-fluentd/config.d"
      ansible.builtin.shell:
        cmd: mv /etc/google-fluentd/config.d /etc/google-fluentd/config.d.bk
      when: not is_google_fluentd_configd_exist.stat.exists
    - name: prepare google-fluentd/config.d
      ansible.builtin.file:
        path: /etc/google-fluentd/config.d
        state: directory
    - name: "set google-fluentd/google-fluentd.conf"
      template:
        src: etc/google-fluentd/google-fluentd.conf
        dest: /etc/google-fluentd/google-fluentd.conf
      notify: restart google-fluentd
handlers:
    - name: restart google-fluentd
      systemd:
        name: google-fluentd.service
        enabled: yes
        state: reloaded

google-fluentd.conf は不要なデフォルト設定がたくさん書いてあったので、やや見通しがアレだったのでそれを消して、@type google_cloud の部分だけはほぼそのまま残した。

<source>
  @type forward
</source>

<match **>
    @type google_cloud
    buffer_type file
    buffer_path /var/log/google-fluentd/buffers
    # Set the chunk limit conservatively to avoid exceeding the recommended
    # chunk size of 10MB per write request. The API request size can be a few
    # times bigger than the raw log size.
    buffer_chunk_limit 256KB
    # Flush logs every 5 seconds, even if the buffer is not full.
    flush_interval 10s
    # Enforce some limit on the number of retries.
    disable_retry_limit false
    # After 3 retries, a given chunk will be discarded.
    retry_limit 3
    # Wait 10 seconds before the first retry. The wait interval will be doubled on
    # each following retry (20s, 40s...) until it hits the retry limit.
    retry_wait 10
    # Never wait longer than 5 minutes between retries. If the wait interval
    # reaches this limit, the exponentiation stops.
    # Given the default config, this limit should never be reached, but if
    # retry_limit and retry_wait are customized, this limit might take effect.
    max_retry_wait 300
    # Use multiple threads for processing.
    num_threads 8
    # Use the gRPC transport.
    use_grpc true
    # If a request is a mix of valid log entries and invalid ones, ingest the
    # valid ones and drop the invalid ones instead of dropping everything.
    partial_success true
    # Enable monitoring via Prometheus integration.
    enable_monitoring true
    monitoring_type opencensus
</match>

本来だと ラズパイ => GCE の通信は tls=true でやるのがセキュアなはずなのだが、当時なんか挙動バグってるかもみたいなissueを見つけたので、やりとりするのCPUの温度くらいだしまあいまのところ平文でよいかという設定になっている。

(その他) fluent-bit が軽い

fluent-bit は本当にメモリ消費量が低い。昔にラズパイで fluentd を動かした時はほとんどなにもプラグイン動かしてない状態で 100MB 以上メモリ食っていたのだが、fluent-bit は1MBも消費量が増えていない。

tail しているファイルが10個くらいなのでなんとも言えないが、CPUもほとんど使っていないように見える。

参考

基礎からの新しいストレージ入門 基本技術から設計・運用管理の実践まで
[ad] 基礎からの新しいストレージ入門 基本技術から設計・運用管理の実践まで
坂下 幸徳 (単行本)