因爲分佈式系統的日誌集中採集的需求很是強烈,咱們組經過調研和實踐搭建了一套基於Docker的日誌收集系統Amethyst。html
咱們首先在測試環境搭建了一套基於Docker swarm集羣的ELK分佈式環境。node
測試雲linux
docker swarm 配置:docker
[elastic@host-10-191-51-44 ~]$ docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION qjdc5dhfauxz9b6bxlj12k0b4 * host-10-191-51-44 Ready Active Reachable 18.09.4 sn0uy2i8rwfpk1z8jjwkmb3un host-10-191-51-45 Ready Active Reachable 18.09.4 rjsxhmbrstpxadw9vc4rzbc4e host-10-191-51-46 Ready Active Leader 18.09.4 xl24brlx3b6r1r9bm22nl3s95 host-10-191-51-47 Ready Active 18.09.4
四臺linux主機配置各爲:網絡
Kernel Version: 3.10.0-327.el7.x86_64 Operating System: CentOS Linux 7 (Core) OSType: linux Architecture: x86_64 CPUs: 8 Total Memory: 15.51GiB
Docker swarm service包括分佈式
NAME SERVICES ORCHESTRATOR es 4 Swarm kafka 3 Swarm kibana 1 Swarm log 1 Swarm zk 3 Swarm
五種service關係以下圖所示:測試
Filebeat主機和Amethyst處於同一個測試網網段,ip地址直接能夠鏈接,狀態一切正常,kibana裏能夠看見測試數據,因此咱們測試兩個月後便準備投入生產,今後記錄從評審開始遇到的主要問題。ui
評審階段:spa
關鍵詞:網絡如何限流日誌
解決辦法:kafka consumer配額,Filebeat的壓力感知功能能夠在kafka限流時下降自身發送日誌的速率。
參考 http://www.javashuo.com/article/p-zjsbyaen-mz.html
也考慮過使用容器tc限流,可是發現tc只能對輸出流量作限制,故放棄。
第一次發佈:
關鍵詞:1) filebeat 跨區跨防火牆鏈接kafka IP地址不通.
2) docker程序所屬用戶爲manag
問題1:因爲kafka的三個IP地址作了NAT映射,filebeat 中配置鏈接IP爲kafka映射後的地址,鏈接kafka時,kafka會返回給filebeat註冊到zookeeper的對外地址,也就是KAFKA_ADVERTISED_LISTENERS;這裏出現一個問題:1)當咱們把kafka集羣中的KAFKA_ADVERTISED_LISTENERS配置爲映射前地址,kafka集羣狀態正常可是,filebeat鏈接時會收到kafka返回的映射前地址,因此filebeat沒法鏈接,致使i/o wait。2)當咱們把kafka集羣中的KAFKA_ADVERTISED_LISTENERS配置爲映射後地址,會致使KAFKA集羣之間沒法通信,從而集羣狀態異常。
解決辦法:
網絡通信不使用IP地址的方式,經過主機名和/etc/hosts映射的方式通信,當把KAFKA_ADVERTISED_LISTENERS配置爲主機名後,kafka返回給filebeat的地址就是hostname:port,這裏只要在Filebeat主機中在/etc/hosts 添加映射後的IP和hostname關係即可以讓filebeat得到hostname後依然能夠找到映射地址。
問題2:這是由於咱們經過Docker啓動進程時,默認會指定進程的uid爲1000,而生產環境上uid=1000的用戶正是manage用戶,故docker啓動的進程顯示爲manage所屬。
解決辦法:能夠經過在docker swarm stack配置文件中指定服務uid來限定docker進程的名稱。
第二次發佈:
關鍵詞:1) kafka集羣狀態異常致使
問題1: 當把kafka配置的KAFKA_ADVERTISED_LISTENERS修改成hostname後,發現各主機用hostname之間沒法ping通,而在測試網中嘗試都可以經過hostname ping通(後面瞭解應該是測試雲的openstack內置的dns解析能夠在openstack虛擬機外部解析hostname),這裏想固然的修改elk集羣中的/etc/hosts 各IP和主機映射;這時啓動kafka集羣狀態仍是異常。在嘗試在物理機上部署kafka後,集羣狀態就正常了;正準備讓logstash從kafka裏消費數據時發現logstash也沒法讀取kafka配置文件中的hostname,這裏想到其實最初在kafka集羣中添加/etc/hosts的操做應該是在各Docker內部完成!此時配置uid=「0」,啓動kafka_stack和logstash_stack,在容器內部添加/etc/hosts條目。
解決辦法:在kafka和logstash內部添加/etc/hosts條目。
研究方向:
kafka通信機制
docker的uid機制