Logstash Docker部署的踩坑笔记
这周要开始做埋点日记的分析,初步调研后,准备用filebeat+logstash+mongodb来做。
基于golang写的filebeat比较轻量,解压后就可以直接用了,而logstash还有好多依赖要装,所以毫不犹豫就选择用docker来部署。
因为是现学现用,时间也有些紧,再加上完全是新手入门,看到文档Configuaring Logstash for Docker中Bind-mounted settings files这段后,
就自己定义了一个logstash.yml
input{
beats {
port => 5044
}
}
output{
mongodb {
uri => "mongodb://localhost:27017"
database => "spot_logs"
collection => "raw_data"
}
}
心想着这样通过volume挂进去就可以用了。
docker run --rm -it -v ./logstash.yml:/usr/share/logstash/config/logstash.yml docker.elastic.co/logstash/logstash:7.2.0
然后,悲剧开始了~~~
首先,我定义的其实是一个.conf文件,而不是logstash.yml。
于是,刚一启动就报错了。
当我经过一番搜索,知道这其实是一个conf文件后,就直接改把它的后缀名改成了.conf,然后执行了
docker run --rm --network host -it -v ./logstash.conf:/usr/share/logstash/config/logstash.conf docker.elastic.co/logstash/logstash:7.2.0
然后,“奇迹发生”了~~filebeat发过来日志,logstash都能收到,而且还打印了出来(好神奇,那可是我第一次跑通filebeat+logstash),但是还没开心1分钟,就发现mongodb里根本没数据。
然后,没有方向的我,开始了一通乱试(略去不表,其实都是泪),白白耗费了一个下午加晚上也没找到原因(那时真是心情沉重,想着这个sprint估计有点难交差了!)。
回到家后,洗了澡,重新开始思考这个问题的时候,我突然意识到,可能我设置的配置根本就不起作用,现在的行为没准是logstash镜像的默认行为。(在时间压力下,现学现用,很容易钻牛角尖,这时暂停下来,平静心情,换个思路很重要!)
查了一下logstash官方的dockerfile也没发现什么,到是在一篇搜索到文章中,发现可能是e受容器里的pipelines.yml的影响。
当我打开容器里的/usr/share/logstash/config/pipelines.yml的时候,看见:
- pipeline.id: main
path.config: "/usr/share/logstash/pipeline"
再打开 /usr/share/logstash/pipeline,看到:
input {
beats {
port => 5044
}
}
output {
stdout {
codec => rubydebug
}
}
真是一口老血喷出来~心想好坑呀,隐藏的这么深!
于是,仿造这个pipelines.yml,也写了个pipelines.yml,把config指向自己的配置。
- pipeline.id: main
path.config: "/usr/share/logstash/config/logstash.conf"
pipeline.workers: 3
再挂载进docker启动后,看到mongodb的报错信息后,就知道自己的设置终于生效了。
报错的原因,是因为logstash-output-mongodb这个output默认是没有的,需要自己装好,解决方法也很简单,自定义一个dockerfile,做一个安装好logstash-output-mongodb的镜像就好。
同时,在这里我也把自己写的放在config文件里的pipelines.yml和logstash.conf拷了进去,具体内容如下;
FROM docker.elastic.co/logstash/logstash:7.2.0
RUN rm -f /usr/share/logstash/pipeline/logstash.conf
COPY ./config/ /usr/share/logstash/config/
RUN logstash-plugin install logstash-output-mongodb
然后运行:
docker build -f logstash.dockerfile -t mine/logstash:1.0
最后定义了一个docker-compose.logstash.yml文件:
version: '3'
services:
logstash:
image: mine/logstash:1.0
restart: always
container_name: finxos_logstash
network_mode: 'host'
volumes:
- "$PWD/config/logstash.conf:/usr/share/logstash/config/logstash.conf"
depends_on:
- mongodb
mongodb:
image: mongo:4.0
restart: always
container_name: finxos_mongodb
volumes:
- "$PWD/mongodb_data:/data/db"
network_mode: 'host'
这样就可以通过下面的命令一键启动了。
docker-compose -f docker-compose.logstash.yml up
写在最后
在下笔前,我是心想着写下自己的踩坑经验,估计会对他人有用。
但是写着的时候,才发现我觉得很坑的默认行为,其实在Configuaring Logstash for Docker的Pipeline Configuration章节里有提到。
而当时的我急着赶紧用起来,看到Pipeline也不知道是干什么的(其实现在也不是很清楚),就直接跳到Settings章节了。
真的是要好好看文档!抓住重要信息呀!
但是再一想,即再来一次,以当时的我刚刚接触filebeat+logstash, docker也好久不用了的状态,还面临着完成业务需求的紧迫感,大概率还是会略过这段。
现学现用,真的很痛苦!
这期间,关键是要准确的定位问题,然后逢山开路,遇水搭桥,其实也不失为一次蜕变的体验!
而关键的关键在于,要相信自己最终还是会搞定的。