一、Docker日志处理机制
当启动一个容器的时候,它其实是docker daemon
的一个子进程,docker daemon
可以拿到容器里面进程的标准输出,拿到标准输出后,它会通过自身一个LogDriver
模块来处理,LogDriver
支持的方式很多,可以写到本地的文件(默认方式),可以发送到syslog
等。
Docker默认会手机应用程序的标准输出存储到一个json.log文件中,文件的格式类似下面这种:
{"log":"2020-02-24T09:07:23.178+0000 I COMMAND [conn18] command graylog.$cmd command: update { update: \"sessions\",
ordered: true, $db: \"graylog\" } numYields:0 reslen:59 locks:{ Global: { acquireCount: { r: 1, w: 1 } },
Database: { acquireCount: { w: 1 } }, Collection: { acquireCount: { w: 1 } } } protocol:op_query 107ms\n","stream":"stdout",
"time":"2020-02-24T09:07:23.178711207Z"}
如果深究其日志位置,每个容器的日志默认都会以 json-file 的格式存储于 /var/lib/docker/containers/<容器id>/<容器id>-json.log
下,以一行一个作为一条JSON数据存储。Docker的这种日志存储方式是可以配置的,具体参数可以在执行run
启动容器的时候通过log-driver
进行配置,具体配置请参考log-driver
:https://docs.docker.com/config/containers/logging/configure/#supported-logging-drivers。
二、Docker日志驱动
Docker默认使用了json-file driver
作为log driver,而gelf
则是示例使用的log driver。
当容器数量比较多,或者是采用类似swarm集群部署Docker的时候,各种日志分散存在各个json.log文件中,当查找问题或者进行相关统计的时候,分散的日志是很不友好的,所以我们需要一个能够集中管理Docker日志的工具。
1、Graylog
相信大部分的人都用过或者听说国ELK这个强大的日志栈架构,这里要使用的graylog和ELK非常相似,算是后起之秀。
为什么要选择graylog作为Docker的日志收集平台?
- Docker原生支持graylog协议,直接将日志发送到graylog(通过gelf协议)
- graylog官方提供了将本身部署在Docker的支持
2、Graylog部署
graylog官方提供了Dockerfile供开发者快速在Docker上部署日志系统,在这个Docker Hub的地址中,也提供了docker-compose.yml
来快速部署整个graylog栈,包括mongodb
、ElasticSearch
,而不需要分别单独进行部署。
(1)创建目录
创建一个目录用来部署graylog,假设为/root/graylog
,以下所有操作都是在该目录中进行的。
(2)初始化目录和配置文件
# 创建数据目录
mkdir -p ./graylog/data
# 创建配置文件目录
mkdir -p ./graylog/config
cd ./graylog/config
# 直接下载官方推荐配置文件
wget https://raw.githubusercontent.com/Graylog2/graylog-docker/2.5/config/graylog.conf
wget https://raw.githubusercontent.com/Graylog2/graylog-docker/2.5/config/log4j2.xml
有可能出现下载不到的情况,这时因为DNS污染的原因,参考修改Hosts临时解决GitHub的raw.githubusercontent.com无法链接的问题即可正常下载。
(3)修改下载完的graylog.conf中的root_timezone为GMT_0800中国时区
root_timezone - Etc/GMT-8
(4)新建docker-compose.yml来供docker-compose快速启动完整服务
配置内容如下:
version: '2'
services:
# MongoDB: https://hub.docker.com/_/mongo/
mongodb:
image: mongo:3
volumes:
- mongo_data:/data/db
# Elasticsearch: https://www.elastic.co/guide/en/elasticsearch/reference/6.x/docker.html
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:6.5.1
volumes:
- es_data:/usr/share/elasticsearch/data
environment:
- http.host=0.0.0.0
- transport.host=localhost
- network.host=0.0.0.0
# Disable X-Pack security: https://www.elastic.co/guide/en/elasticsearch/reference/6.x/security-settings.html#general-security-settings
- xpack.security.enabled=false
- xpack.watcher.enabled=false
- xpack.monitoring.enabled=false
- xpack.security.audit.enabled=false
- xpack.ml.enabled=false
- xpack.graph.enabled=false
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
ulimits:
memlock:
soft: -1
hard: -1
mem_limit: 512M
# Graylog: https://hub.docker.com/r/graylog/graylog/
graylog:
image: graylog/graylog:2.5
volumes:
- graylog_journal:/usr/share/graylog/data/journal
#- /home/codeman/graylog/config:/usr/share/graylog/data/config
environment:
- GRAYLOG_PASSWORD_SECRET=somepasswordpepper
# Password: admin
- GRAYLOG_ROOT_PASSWORD_SHA2=8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918
# 这个地址需要配置成你要访问的地址,比如你的容器部署在192.168.1.2,你需要配置成http://192.168.1.2:9000/api,否则访问会报错
- GRAYLOG_WEB_ENDPOINT_URI=http://192.168.27.135:9000/api
links:
- mongodb:mongo
- elasticsearch
depends_on:
- mongodb
- elasticsearch
ports:
# Graylog web interface and REST API
# web界面端口
- 9000:9000
# gelf收集日志的端口,如果需要添加graylog收集器,可以新增暴露出来的端口
# Syslog TCP
- 514:514
# Syslog UDP
- 514:514/udp
# GELF TCP
- 12201:12201
# GELF UDP
- 12201:12201/udp
# Volumes for persisting data, see https://docs.docker.com/engine/admin/volumes/volumes/
volumes:
mongo_data:
driver: local
es_data:
driver: local
graylog_journal:
driver: local
(5)启动整个服务
docker-compose up
如果启动没有问题,会看到
graylog server up and running
的终端输出消息访问htp://IP:9000/会看到graylog的web界面,使用admin/admin登陆,至此部署已完成。
登陆
第一次加载速度比较慢,因为要初始化配置加载数据等
(6)Graylog系统配置
加载完成后,进入search页面,发现没有显示什么数据
graylog的日志收集通过定义input对象来完成,在graylog web管理界面进入input对象配置,选择GELF UDP协议来新建一个输入器(input),可以看成是对日志收集的监控,System -> Input -> GELF UDP -> Launch new input
出现弹窗,编辑配置信息,保存后,就可以开始收集日志了
但是发现配置的
input
状态还是fail,重新打开弹窗编辑,将绑定地址改为0.0.0.0
这时候再看
input
的状态,已经不报失败了点击Start input,启动对日志的输入监听
(7)验证服务
graylog已经部署启动配置完了,这时就需要测试输入日志来验证服务是否可正常展示收集日志,创建一个不断输出日志的容器,命令如下:
docker run --log-driver=gelf --log-opt gelf-address=udp://{graylog服务器地址}:12201 \
--log-opt tag=<当前容器服务标签,用来供graylog查询的时候进行分类> <IMAGE> <运行命令>
使用示例:
docker run -d \
--log-driver=gelf \
--log-opt gelf-address=udp://localhost:12201 \
--log-opt tag="{{.ImageName}}/{{.Name}}/{{.ID}}" \
busybox sh -c 'while true; do echo "Hello, this is A"; sleep 10; done;'
由于这里已经指定将日志发送到udp://localhost:12201
,所以使用docker logs
查看容器日志时,会显示配置的日志驱动不支持读取日志,如下如图所示:
进入graylog的web管理界面查看日志信息,可以看到日志时间内容,通过勾选左侧的菜单还可以看到更多的信息
点击单条日志也可以看到完整的日志详情
(8)使用docker-compose配置容器日志
如果通过docker-compose命令,则可以在docker-compose.yml中加入相关配置,以下用nginx容器举例。新建一个nginx的目录,在目录中新建一个docker-compose.yml文件,内容如下:
version: '2'
services:
nginx:
image: nginx:latest
ports:
- "80:80"
logging:
driver: "gelf"
options:
gelf-address: "udp://192.168.27.135:12201"
tag: front-nginx
同样使用docker-compose up
启动,启动后可能有下面的提示:
但是可以无视这个警告,日志还是会发送过去的,这时可以在graylog的web后台中看到nginx所产生的日志了,为了让nginx产生日志,访问下nginx
可以看到在浏览器发起HTTP请求产生的nginx日志了