fluentd收集docker容器並存為es索引


前言:

  這幾天研究了下fluentd,不得不說,整體上來說還是蠻復雜的,尤其配置文件難以找到一個標准的參考對象,所使用的功能需要不同的插件來支持,功能多樣化的同時也意味着配置的復雜,多次嘗試之后,算摸索到了一個可用的docker容器日志收集方案。接下來會簡單介紹下所應用的配置,啟動方式,以及找資料中碰到的疑惑問題。

td-agent與fluentd是什么關系:

td-agent是Fluentd的穩定發行版本,它的出現是因為Fluentd不易於安裝。本質上td-agent和Fluentd是一個東西。td-agent一般是作為應用直接安裝在linux系統上的。我只了解到這里,因為容器化的趨勢,學習它是沒有價值的,有興趣的話可以研究下。

td-agent如何安裝

適於於Redhat&Centos的安裝方式:

$ curl -L https://toolbelt.treasuredata.com/sh/install-redhat-td-agent3.sh | sh

fluentd的插件問題:

  fluentd中的功能大都需要插件來支持,即配置文件中每個配置,這意味着你想使用的功能都需要安裝額外的插件,你不能直接使用docker search來拉fluentd鏡像直接使用,需要對鏡像進行再制作。

  你可以選擇不同的日志收集方式,也可以選擇將fluentd收集到的日志存儲到不同的存儲組件中,當然,這些功能都需要安裝對應的組件的插件才能夠在配置文件中選擇,我使用的是容器化安裝的fluentd,將本機容器日志存儲在es索引中。最終用kibana來展示。

日志收集方案演示:

啟動fluentd容器:

首先,得拉取鏡像,我選擇的是下面這個鏡像
docker pull docker.io/fluent/fluentd
當然,配置文件需要手動修改,所以,啟動命令如下:
docker run -d -p 24224:24224 -v /data/fluent.conf:/fluentd/etc/fluent.conf --name="fluentd" docker.io/fluent/fluentd

fluent.conf是fluentd的配置文件,我的配方/data/fluent.conf是這樣的:

<source>
  type forward    #source表示日志源來自轉發,forward與http是默認安裝的組件,不需要額外的插件支持。
  port 24224    #在24224端口啟動forward接收轉發
  bind 0.0.0.0    #允許接收任意IP的轉發
</source>
 
<match *>
  @type copy    #match模塊表示日志再轉發
  <store>
    @type elasticsearch    #轉發日志到es,這需要安裝es的插件
    hosts 192.168.74.182:9200    #es的配置信息
    logstash_format true    #啟動轉發
    logstash_prefix my-test    #轉發到es的索引名稱
    logstash_dateformat %Y.%m    #按月來划分索引,可以刪除無用數據
    flush_interval 5s    #每5s刷新一次
  </store>
  <store>
    @type stdout    #搜索到數據后立即轉發到es
  </store>
</match>

ok,上面的配置文件是我測試多次,得到的可用文件

當然,你需要進入容器執行安裝es插件的命令:

docker exec -it fluentd bash
gem install fluent-plugin-elasticsearch
當然,安裝完了我們要重啟下容器
docker restart fluentd

到這一步,我們fluentd配置就告一段落了,es的安裝啟動可以參考下我之前的博客

啟動nginx測試容器:

docker run -d -p 80:80 --log-driver=fluentd --name="nginx" docker.io/nginx

nginx的啟動就沒有那么多的顧忌了,加上--log-driver=fluentd參數即可,當然,最好加上--log-opt fluentd-async-connect,因為前一個參數使nginx容器與fluentd容器綁定了。fluentd掛掉的話,nginx容器也會掛掉,這當然不是我們所希望的,所以,生產環境還是在容器啟動時加上asyc參數。最后,需要先啟動es,再啟動fluentd,再啟動nginx,因為它們是互相依賴的關系。

驗證:

查看fluentd的日志,我們就可以看到fluentd所收集到的日志:

  <source>
    type forward
    port 24224
    bind "0.0.0.0"
  </source>
  <match *>
    @type copy
    <store>
      @type "elasticsearch"
      hosts "192.168.74.182:9200"
      logstash_format true
      logstash_prefix "my-test"
      logstash_dateformat "%Y.%m"
      flush_interval 5s
      <buffer>
        flush_interval 5s
      </buffer>
    </store>
    <store>
      @type "stdout"
    </store>
  </match>
</ROOT>
2020-11-13 08:11:20 +0000 [info]: starting fluentd-1.3.2 pid=8 ruby="2.5.2"
2020-11-13 08:11:20 +0000 [info]: spawn command to main:  cmdline=["/usr/bin/ruby", "-Eascii-8bit:ascii-8bit", "/usr/bin/fluentd", "-c", "/fluentd/etc/fluent.conf", "-p", "/fluentd/plugins", "--under-supervisor"]
2020-11-13 08:11:21 +0000 [info]: gem 'fluent-plugin-elasticsearch' version '4.2.2'
2020-11-13 08:11:21 +0000 [info]: gem 'fluentd' version '1.3.2'
2020-11-13 08:11:21 +0000 [info]: adding match pattern="*" type="copy"
2020-11-13 08:11:21 +0000 [info]: #0 'flush_interval' is configured at out side of <buffer>. 'flush_mode' is set to 'interval' to keep existing behaviour
2020-11-13 08:11:21 +0000 [warn]: #0 Detected ES 7.x: `_doc` will be used as the document `_type`.
2020-11-13 08:11:21 +0000 [warn]: #0 'type' is deprecated parameter name. use '@type' instead.
2020-11-13 08:11:21 +0000 [info]: adding source type="forward"
2020-11-13 08:11:21 +0000 [info]: #0 starting fluentd worker pid=19 ppid=8 worker=0
2020-11-13 08:11:21 +0000 [info]: #0 listening port port=24224 bind="0.0.0.0"
2020-11-13 08:11:21 +0000 [info]: #0 fluentd worker is now running worker=0
2020-11-13 08:11:26.000000000 +0000 67b9cf765a25: {"log":"192.168.74.1 - - [13/Nov/2020:08:11:26 +0000] \"GET / HTTP/1.1\" 304 0 \"-\" \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.193 Safari/537.36\" \"-\"","container_id":"67b9cf765a25505510613f77c400f107a6d4bcd3039e3831460fad28bd467c0b","container_name":"/nginx","source":"stdout"}

日志中包含的信息有,fluentd的配置文件的信息,fluentd的版本,ruby版本,es插件等等的版本信息,最后一個就是收集到的日志信息。

查看es的索引:

[root@my yibin]# curl http://192.168.74.182:9200/_cat/indices?v
health status index                    uuid                   pri rep docs.count docs.deleted store.size pri.store.size
yellow open   log-audit-2020.11        Hi1qLtXGQbm2NdNjK_gXTw   1   1        481            0    210.4kb        210.4kb
green  open   .kibana_task_manager_1   eFqwbcB2RTq7LZKatgHF4g   1   0          2            0     21.7kb         21.7kb
yellow open   log-secure-2020.11       DEDAhB6dS5uo50jeY2Tu4A   1   1          2            0     12.4kb         12.4kb
yellow open   my-test-2020.11          HNsZBogvQMiwWwh3uj6DBA   1   1         38            0     20.4kb         20.4kb
green  open   .apm-agent-configuration 7AsnoJtoT3WrB7p26BP14w   1   0          0            0       283b           283b
green  open   .kibana_1                TmqoMtVJTOOgtG4Cl3L0kA   1   0         10            3     30.2kb         30.2kb

可以看到我們my-test的索引成功生成了,最后我們再將它添加到kibana中進行整理與展示就行了。

當然,僅僅是一個容器的話,這樣是沒有問題的,如果是多個容器,我們就需要將他們區分,在開始運行docker容器時,我們添加了參數--log-driver fluentd來指定容器日志輸出到fluentd進行轉發,但收集到的日志沒有明顯能夠說明該條日志來自於哪個app的標簽。這樣的需求可以通過在啟動容器時添加--log-opt tag=thrall參數使得該容器輸出的日志都帶上tag=thrall的標簽。這樣我們就可以知道該條日志來源於哪個app。

<match *thrall*>    #匹配tag中包含thrall的日志
  @type elasticsearch
  host localhost
  port 9200
  include_tag_key    #會輸出所有tag到每一條日志記錄中
  include_tag_key true
  tag_key log_name
  logstash_format true
  logstash_prefix thrall    #我們可以將每個容器日志起單獨的名字,也可以將他們放到一個索引里,最后使用kibana展示中的過濾功能來完成內容的分隔
</match>

參考鏈接:

使用fluentd管理docker日志


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM