前言:
這幾天研究了下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>
