ELK+logspout收集Docker日志

时间:2024-04-10 11:16:37

1. Docker日志收集流程

ELK+logspout收集Docker日志
  基本思路通过logstash获取docker中的日志,然后,将日志转发给elasticsearch进行索引,kibana分析和可视化。
  获取docker中的日志文件可以有多种方式:

  1. 添加一个MQ或者Redis作为docker容器和logstash的中间层,docker中的服务将日志传输到中间层,然后,logstash从中间获取
  2. 使用工具获取docker中的日志,例如:filebeat,logspout,log-pilot;但是不建议在每个服务器上安装logstash,因为logstash运行会占有大量的服务器资源,增加服务器压力。
    • filebeat的配置好像相对比较复杂,没有具体了解;
    • logspout 可以获取docker的stdout日志
    • log-pilot 是阿里开源的日志工具,可以处理stdout和日志文件

  本文中主要使用logspout.

2. Logspout+ELK收集日志

2.1 Docker安装ELK

  1. 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
  1. 配置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"
  1. 安装ELK镜像
    使用docker-compose build命令构建镜像;
    构建过程可能会失败,需要重复几次;
    运行使用docker-compose up -d

2.2 安装logspout

  1. 其他机器上安装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;

  1. 界面查看
    访问:http://kibana宿主机ip:5601/ 可以看到kibana界面;
    首次访问,需要创建一个index:
    ELK+logspout收集Docker日志
    如果elasticsearch中有索引将会如下图所示,index-name输入框填写logstash-*,然后点击Next step按钮,选择下拉框中的@timestamp,然后,点击创建索引,之后,点击菜单栏中的Discover将会看到有日志信息:(ps:不同的版本,看到的界面可能会不一样)
    ELK+logspout收集Docker日志
    ELK+logspout收集Docker日志
  2. 指定需要收集的容器
    logspout默认收集所在主机的所有容器的日志,但是,有时候我们只希望收集部分容器的日志,有两种方式可以解决:
  • 每个容器启动时,添加环境变量LOGSPOUT=ignore,例如上边ELK中的设置,官方例子:
docker run -d -e 'LOGSPOUT=ignore' image
// 或者
docker run -d --label logspout.exclude=true image

我使用了第二种方式,将上边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