[ELK] 将 logstash 日志打到 kafka 集群 - 迁
先看下我这边的环境:
logstash agent 从虚拟机抽取日志后分发到 redis 和 kafka 集群 (部分日志),但是我们的产品环境和管理网是隔离的,只能通过管理机 iptables 转发到 kafka,logstash output 的配置:
output { redis { host => "1.1.1.1" port => "6379" data_type => "list" key => "logstash-redis" } kafka { bootstrap_servers => "DT-WH-3:9092,DT-WH-4:9092,DT-WH-5:9092" topic_id => "platform1_log" codec => "json" compression_type => "snappy" }
可以看到日志会同时发往 redis 和 kafka 一份,关键是 bootstrap_servers 要写域名,这个是和 kakfa 中 advertised.host.name 匹配的,这个值是 kafka 运行 broker 时,会把 broker 的 ip/port 注册到 zookeeper,默认是方法 InetAddress.getLocalHost.getHostAddress 获得的所以有些时候客户端是拿到 localhost 这样的地址,如果是同一网络内,写 ip 也可以通,但是我这边环境是需要地址映射的,所以在 kafka 里面写域名,kafka 将域名返回给客户端,写了域名还不够,还需要改客户端本地 hosts 把对应的域名指到管理机的 iptables DNAT 转发的 ip 接口上去。
cat /etc/hosts 1.1.1.10 DT-WH-1-3 1.1.1.11 DT-WH-1-4 1.1.1.12 DT-WH-1-5
iptables 的配置:
管理机是双网卡,虚拟出3块内网网卡和3块外网网卡 iptables -t nat -A PREROUTING -p tcp -m tcp -d 1.1.1.12 --dport 9092 -j DNAT --to-destination 192.168.16.15:9092 iptables -t nat -A POSTROUTING -d 192.168.16.15 -p tcp -m tcp --dport 9092 -j SNAT --to-source 192.168.14.5 略...
参考文档:
https://segmentfault.com/q/1010000004565585
遇到的坑:
-
开两个 logstash agent 会重复打日志,这个问题查了好久,我是用 supervisorctl 管理 logstash 进程,为啥会多启动一个我也不清楚,下次遇到这种问题先看下进程数量。
-
logstash 可以配置一个 kafka 实例地址,但是 iptables 映射必须 3 个地址都映射否则会丢数据,猜测是 zookeeper 返回不同的 kafka 地址来分片数据,只配一个地址显然是不行的。
-
也可以在 es 的管理机上做 logstash output 到不同接口(es 和 kafka)
input { redis { data_type => "list" key => "logstash-redis" host => "1.1.1.1" port => 6379 threads => 20 } } output { if [host] == "web-1" { kafka { bootstrap_servers => "DT-WH-3:9092,DT-WH-4:9092,DT-WH-5:9092" topic_id => "platform1_log" codec => "json" compression_type => "snappy" } } elasticsearch { hosts => "8.8.8.8:9200" index => "platform1-%{+YYYY.MM.dd}" template_overwrite => true } }