生產環境Docker部署ELK跨區訪問kafka不通問題的解決

因爲分佈式系統的日誌集中採集的需求很是強烈,咱們組經過調研和實踐搭建了一套基於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機制

相關文章
相關標籤/搜索