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


由於分布式系統的日志集中采集的需求非常強烈,我們組通過調研和實踐搭建了一套基於Docker的日志收集系統Amethyst。

我們首先在測試環境搭建了一套基於Docker swarm集群的ELK分布式環境。

測試雲

docker swarm 配置:

[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里可以看見測試數據,所以我們測試兩個月后便准備投入生產,從此記錄從評審開始遇到的主要問題。

評審階段:

關鍵詞:網絡如何限流

解決辦法:kafka consumer配額,Filebeat的壓力感知功能可以在kafka限流時降低自身發送日志的速率。

參考 https://www.cnblogs.com/huxi2b/p/8609453.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機制

 


免責聲明!

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



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