ELK+logspout收集Docker日志
1. Docker日志收集流程
基本思路通过logstash获取docker中的日志,然后,将日志转发给elasticsearch进行索引,kibana分析和可视化。
获取docker中的日志文件可以有多种方式:
- 添加一个MQ或者Redis作为docker容器和logstash的中间层,docker中的服务将日志传输到中间层,然后,logstash从中间获取
- 使用工具获取docker中的日志,例如:filebeat,logspout,log-pilot;但是不建议在每个服务器上安装logstash,因为logstash运行会占有大量的服务器资源,增加服务器压力。
- filebeat的配置好像相对比较复杂,没有具体了解;
- logspout 可以获取docker的stdout日志
- log-pilot 是阿里开源的日志工具,可以处理stdout和日志文件
本文中主要使用logspout.
2. Logspout+ELK收集日志
2.1 Docker安装ELK
- logstash配置文件
input {
tcp {
port => 5000
type => syslog
codec => json
}
udp {
port => 5000
type => syslog
}
file {
codec => json
path => "/opt/build/*.json"-->
}
}
filter {
grok {
match => { "message" => "%{TIMESTAMP_ISO8601:timestamp}\s+%{LOGLEVEL:severity}\s+\[%{DATA:service},%{DATA:trace},%{DATA:span},%{DATA:exportable}\]\s+%{DATA:pid}---\s+\[%{DATA:thread}\]\s+%{DATA:class}\s+:\s+%{GREEDYDATA:rest}" }
}
}
output {
elasticsearch { hosts => ["elasticsearch:9200"] }
stdout { codec => rubydebug }
}
配置解释:logstash配置分为三个部分:
- input: 输入,也就是文件输入流,可以通过tcp,udp推送,或者到只能目录获取,其中file的配置,就是读取指定目录的内容(这里可以不配置);配置tcp因为不同机器上的logspout需要通过tcp推送日志;
- filter: 过滤;gork将非标准化日志转化为标准化的
- output:输出,可以指定输出的 index
- 配置elk的docker compose文件
version: '3'
services:
elasticsearch:
image: elasticsearch:6.5.0
# command: elasticsearch
ports:
- "9200:9200"
- "9300:9300"
logstash:
image: logstash:6.5.0
command: logstash -f /etc/logstash/conf.d/logstash.conf
volumes:
- ./config:/etc/logstash/conf.d
- /opt/build:/opt/build
ports:
- "5001:5000"
kibana:
image: kibana:6.5.0
environment:
- ELASTICSEARCH_URL=http://elasticsearch:9200
ports:
- "5601:5601"
- 安装ELK镜像
使用docker-compose build
命令构建镜像;
构建过程可能会失败,需要重复几次;
运行使用docker-compose up -d
2.2 安装logspout
- 其他机器上安装logspout
version: "3"
networks:
logging:
services:
logspout:
image: gliderlabs/logspout:latest
networks:
- logging
volumes:
- /etc/hostname:/etc/host_hostname:ro
- /var/run/docker.sock:/var/run/docker.sock
command:
syslog+tcp://logstash的宿主机ip:5001
其中,使用syslog+tcp的方式,将收集的日志文件推送到logstash;
- 界面查看
访问:http://kibana宿主机ip:5601/ 可以看到kibana界面;
首次访问,需要创建一个index:
如果elasticsearch中有索引将会如下图所示,index-name输入框填写logstash-*,然后点击Next step
按钮,选择下拉框中的@timestamp
,然后,点击创建索引,之后,点击菜单栏中的Discover
将会看到有日志信息:(ps:不同的版本,看到的界面可能会不一样)
- 指定需要收集的容器
logspout默认收集所在主机的所有容器的日志,但是,有时候我们只希望收集部分容器的日志,有两种方式可以解决:
- 每个容器启动时,添加环境变量
LOGSPOUT=ignore
,例如上边ELK中的设置,官方例子:
docker run -d -e 'LOGSPOUT=ignore' image
// 或者
docker run -d --label logspout.exclude=true image
- logspout启动时指定包含哪些容器,可以参考官方文档中介绍的方式:https://github.com/gliderlabs/logspout
我使用了第二种方式,将上边logspout的docker-compose文件修改,最后发送消息时增加 filter.name
command:
syslog+tcp://172.16.52.23:5001?filter.name=*_monitor
需要收集日志的容器,启动时需要设置后缀为_monitor
的别名,即可监控该容器的日志;
filter的其他参数:
// 指定容器id
filter.id=3b6ba57db54a
// 指定文件
filter.sources=stdout%2Cstderr
// 标签'a'以'x'开头,标签'b'以'y'结尾。
filter.labels=a:x*%2Cb:*y
注意其中逗号的写法;
如果有多个路由目的地,可以使用逗号分隔
docker run \
--volume=/var/run/docker.sock:/var/run/docker.sock \
gliderlabs/logspout \
raw://192.168.10.10:5000?filter.name=*_db,syslog+tls://logs.papertrailapp.com:55555?filter.name=*_app
参考
ELK+Filebeat 集中式日志解决方案详解
使用Docker Compose运行ELK
使用ELK处理Docker日志(一)
https://github.com/gliderlabs/logspout
使用ELK收集Docker Swarm日志
docker swarm集群日志管理ELK实战
Docker 日志收集新方案:log-pilot