Docker容器日志分为2类:
- Docker引擎日志(Docker本身运行的日志)。
- 容器日志,各个容器内产生的日志。
- Docker引擎日志
Centos系统下Docker引擎log一般给systemd管理,可通过 journalctl -u docker.service 命令查看。 - 容器日志
一、查看日志命令
docker logs 容器ID 显示当前运行容器的log,输出Linux下的STDOUT(标准输出)、STDERR(标准错误输出),docker logs 显示的内容包含STDOUT和STDERR。生产环境中,如果应用输出到我们自己的日志文件里,使用docker logs一般收集不到太多重要信息,大多有用log在容器内部。
docker logs 容器ID 或 -f 参数 实施查看log,类似Linux的tail -f。如:[[email protected] logs]# docker ps |grep part ed9e7d9df4b1 b2b-partner-img/b2b-partner-test "/bin/sh -c ‘java ..." 45 minutes ago Up 45 minutes 0.0.0.0:8081->8081/tcp b2b-partner-test-container [[email protected] logs]# [[email protected] logs]# docker logs -f ed9e7d9df4b1
二、Docker日志驱动
Docker CE版本,docker logs命令仅适用于如下的驱动程序:
常用的日志驱动主要有:json-file(默认)、local、syslog、journald、fluentd。
1). Docker日志驱动命令:
查看系统设置的日志驱动[[email protected] logs]# docker info |grep "Logging Driver" | docker info --format ‘{{.LoggingDriver}}‘ json-file
查看单个容器设置的日志驱动命令,docker inspect -f ‘{{.HostConfig.LogConfig.Type}}‘ 容器ID
[[email protected] ~]# docker inspect -f ‘{{.HostConfig.LogConfig.Type}}‘ b0c936eca8ce json-file
2). Docker日志驱动全局配置文件,/etc/docker/daemon.json,JSON格式。
当前日志驱动:cat /etc/docker/daemon.json { "registry-mirrors": ["https://tnxo20jc.mirror.aliyuncs.com"] }
上面是对所有容器更改,也可以针对单一容器设置日志驱动 --log-driver。如上显示的是阿里云的镜像加速地址。
3). 日志驱动-local
local日志驱动记录从容器的STDOUT/STDERR输出,并写到主机硬盘。默认情况,local日志驱动为每个容器保留100M的日志信息,并启用压缩来保存。
local日志驱动存储位置 /var/lib/docker/containers/容器ID/local-logs/,以container.log命名。支持的驱动选项有:
全局设置日志驱动为-local,需在配置文件 /etc/docker/daemon.json:{ "log-driver": "local", "log-opts": { "max-size": "10m" } }
重启docker服务生效。
单个容器日志驱动设置为-local,加 --log-driver local 参数。# 运行一个容器 ,并设定日志驱动为 local ,并运行命令 ping www.baidu.com [[email protected] docker]# docker run -itd --log-driver local alpine ping www.baidu.com 3795b6483534961c1d5223359ad1106433ce2bf25e18b981a47a2d79ad7a3156 # 查看运行的容器的 日志驱动是否是 local [[email protected] docker]# docker inspect -f ‘{{.HostConfig.LogConfig.Type}}‘ 3795b6483534961c local
4). 日志驱动-JSON,Docker默认日志驱动。
json-file日志驱动记录从容器的STDOUT/STDERR输出,并用JSON格式写到文件中。
json-file日志路径,/var/lib/docker/containers/容器ID/容器ID-json.log:[[email protected] ~]# ll /var/lib/docker/containers/09c7bec493c86f0116c4ee91bc54a9262ef1b73fbf27bb0b7a89778a0a28c125/ 总用量 320 -rw-r----- 1 root root 290515 Aug 6 17:57 09c7bec493c86f0116c4ee91bc54a9262ef1b73fbf27bb0b7a89778a0a28c125-json.log drwx------ 2 root root 4096 Aug 6 17:14 checkpoints -rw-r--r-- 1 root root 4367 Aug 6 17:56 config.v2.json -rw-r--r-- 1 root root 1380 Aug 6 17:56 hostconfig.json -rw-r--r-- 1 root root 13 Aug 6 17:56 hostname -rw-r--r-- 1 root root 177 Aug 6 17:56 hosts -rw-r--r-- 1 root root 175 Aug 6 17:56 resolv.conf -rw-r--r-- 1 root root 71 Aug 6 17:56 resolv.conf.hash drwxrwxrwt 2 root root 40 Aug 6 17:56 shm
json-file日志驱动支持的驱动选项有:
5). 日志驱动-syslog
syslog日志驱动将日志路由到syslog服务器,syslog以原始的字符串作为日志消息元数据,接收方可以提取以下的消息:
level日志等级,debug、warning、error、info
timestamp时间戳
hostname事件发生的主机
facility系统模块
进程名称和进程ID
修改全局日志驱动为syslog:cat /etc/docker/daemon.json { "log-driver": "syslog", "log-opts": { "syslog-address": "udp://1.2.3.4:1111" } }
三、生产环境存储Docker容器中的日志
上面介绍的是Docker官方提供的日志驱动,但都是针对容器的STDOUT/STDERR输出的日志驱动。
容器中的日志可分为2大类: - 标准输出STDOUT/STDERR日志
也就是STDOUT/STDERR,这类日志可通过Docker官方的日志驱动进行收集。如:
NGINX日志有access.log 和 error.log,在Docker Hub上可看到Nginx的Dockerfile对于这两个日志的处理是:RUN ln -sf /dev/stdout /var/log/nginx/access.log && ln -sf /dev/stderr /var/log/nginx/error.log
都是软链接到 /dev/stdout 和 /dev/stderr,所以这类容器是可以使用Docker官方的日志驱动。
- 文本日志
都存储于容器内部,并没有重定向到容器的STDOUT/STDERR。如Tomcat日志有Catalina、localhost、manager、host-manager,我们可在Docker Hub上看到Tomcat的dockerfile只有Catalina进行处理,其他日志都存储于容器内部里,只有进入容器才可看到其他的日志。CMD ["catalina.sh", "run"]
针对这类容器有专门的方案应对。
- 完全是STDOUT/STDERR输出类型的容器,可选择json-file、syslog、local等Docker支持的日志驱动。
- 当有文本文件日志类型容器,有如下方案处理:
方案1 挂载目录bind
创建一个目录,将目录挂载到容器中产生日志的目录。docker run -d --name tomcat-bind -P --mount type=bind,src=/opt/logs/,dst=/usr/local/tomcat/logs/ tomcat
方案2 使用数据卷volume
创建数据卷,创建容器时绑定数据卷docker run -d --name tomcat-volume -P --mount type=volume,src=volume_name,dst=/usr/local/tomcat/logs/ tomcat
方案3 计算容器rootfs挂载点
使用挂载宿主机目录方式采集日志对应用会有一定的侵入性,因它要求容器启动时包含挂载命令。如果采集过程中能对用户透明那就太棒了,事实上,可通过计算容器rootfs挂载带你来达到这种目的。
容器rootfs挂载点密不可分的一个概念是storage driver。实际使用过程,用户往往会根据Linux版本、文件系统类型、容器读写情况因素选择合适的storage driver。不同storage driver下,容器rootfs挂载带你遵循一定的规律,因此我们可根据storage driver的类型推断出容器的rootfs挂载点,进而采集容器内部log,下表展示部分storage driver的rootfs挂载点及其计算方法。
查看sms微服务容器挂载位置:[[email protected] ~]# docker ps | grep sms b0c936eca8ce 9e1a0e0ee678 "/.r/r /bin/sh -c ..." 18 months ago Up 8 months r-ms-test-sms-1-561a64f3 [[email protected] ~]# docker inspect -f ‘{{.GraphDriver.Data.MergedDir}}‘ b0c936eca8ce # 查看sms容器的挂载点位置 /mnt/docker/overlay/ee687989905069e3450318a0750a0d88909190191441cccbd47d83cc042f23ab/merged [[email protected] ~]# ll /mnt/docker/overlay/ee687989905069e3450318a0750a0d88909190191441cccbd47d83cc042f23ab/merged #查看挂载点的目录结构 总用量 84 -rw-r--r-- 118 root root 23 Feb 17 2017 10.42.1.1 -rw-r--r-- 126 root root 15712 Dec 14 2016 anaconda-post.log lrwxrwxrwx 1 root root 7 Dec 14 2016 bin -> usr/bin drwxr-xr-x 1 root root 4096 Jan 24 2018 data drwxr-xr-x 4 root root 4096 Jan 24 2018 dev drwxr-xr-x 1 root root 4096 Jan 24 2018 etc drwxr-xr-x 2 root root 4096 Nov 5 2016 home lrwxrwxrwx 1 root root 7 Dec 14 2016 lib -> usr/lib lrwxrwxrwx 1 root root 9 Dec 14 2016 lib64 -> usr/lib64 drwx------ 2 root root 4096 Dec 14 2016 lost+found drwxr-xr-x 2 root root 4096 Nov 5 2016 media drwxr-xr-x 2 root root 4096 Nov 5 2016 mnt drwxr-xr-x 2 root root 4096 Nov 5 2016 opt drwxr-xr-x 2 root root 4096 Jan 24 2018 proc dr-xr-x--- 1 root root 4096 Aug 2 18:33 root drwxr-xr-x 1 root root 4096 Dec 22 2017 run lrwxrwxrwx 1 root root 8 Dec 14 2016 sbin -> usr/sbin drwxr-xr-x 2 root root 4096 Nov 5 2016 srv drwxr-xr-x 2 root root 4096 Jan 24 2018 sys drwxrwxrwt 1 root root 4096 Nov 30 2018 tmp drwxr-xr-x 13 root root 4096 Dec 22 2017 usr drwxr-xr-x 1 root root 4096 Dec 22 2017 var [[email protected] ~]# ll /mnt/docker/overlay/ee687989905069e3450318a0750a0d88909190191441cccbd47d83cc042f23ab/merged/usr/local/ 总用量 44 drwxr-xr-x 2 root root 4096 Nov 5 2016 bin drwxr-xr-x 2 root root 4096 Nov 5 2016 etc drwxr-xr-x 2 root root 4096 Nov 5 2016 games drwxr-xr-x 2 root root 4096 Nov 5 2016 include drwxr-xr-x 8 root root 4096 Dec 22 2017 jdk1.8 drwxr-xr-x 2 root root 4096 Nov 5 2016 lib drwxr-xr-x 2 root root 4096 Nov 5 2016 lib64 drwxr-xr-x 2 root root 4096 Nov 5 2016 libexec drwxr-xr-x 2 root root 4096 Nov 5 2016 sbin drwxr-xr-x 5 root root 4096 Dec 22 2017 share drwxr-xr-x 2 root root 4096 Nov 5 2016 src
方案4 在代码中实现直接将日志写到redis
Docker => Redis => Logstash => Elasticsearch
原文地址:https://blog.51cto.com/10874766/2430921