在 docker 原生支持的众多日志引擎中, 结合实际生产环境的需求, 最终选择了众多linux 发行版都默认支持的 journald 日志系统, journald 日志系统是 systemd 自带的服务, 在实际使用过程中, 上手很快, 而且很符合线上查看 docker 日志的习惯与需求
docker原生支持的日志引擎
- none 关闭 docker 的回显日志, docker logs 看不到任何输出
- json-file 把每个 container 的回显日志打到每个 container 的内部, 形式为json 文件
- syslog 把所有 container 的回显日志打到系统的 syslog 中
- journald 把所有 container 的回显日志打到系统的 journald 服务中
- fluentd 把所有 container 的回显日志打到 fluentd 服务中
- gelf 把所有 container 的回显日志打到支持 GELF(Graylog Extended Log Format) 格式的服务中, 比如 Graylog 或 Logstash
以上原生的日志引擎是最常用的6种,其中 json-file
是 docker 默认使用的日志系统
为什么选择了journald
- 首先排除了
none
的日志引擎, 因为它抛弃了宿主机中所有 container 的回显日志 - 之所有排除
json-file
是因为在实际使用中, 有的 container 在启动后有大量的回显日志, 尤其在程序内部报错时打出的日志信息尤其巨大, 而该 json 文件会放到磁盘对应该 container 的文件夹中越来越大, 常常因为某几个 container 的 json 日志而撑爆整个宿主机的磁盘 - syslog 日志收集的方式我在使用 harbor 私有镜像服务的时候见过, harbor 官方提供的部署方式中, 所有的 container 的日志都集中收集在某一个 container 中, 执行 docker logs 的时候会提示你
"logs" command is supported only for "json-file" and "journald" logging drivers (got: syslog)
1 | # syslog 在 harbor 中的应用解析 |
这个模式在我们生产环境中并不适用, 因为无法通过 docker logs
直接查看日志, 而是需要到指定的容器中去找, 这对于研发查看日志拍错来说无疑是个巨大的麻烦.所以这个日志引擎也不适用于我们的生产环境
- fluentd 和 gelf 这两个日志服务类型一般是配合 elasticsearch/kibana 来一起使用, 因为回显日志是程序回显, 不是业务日志回显, 所以没有进入到 elasticsearch 分析的需求, 业务日志一部分在 nginx 那一层就分析了, 还有的是通过把日志目录挂载出来, 让宿主机的 Log 服务去处理的. 因为规模比较小, 所以暂时用不到这个重的日志服务. 如果你需要分析很多 container 的日志, 可以考虑使用 fluentd 或 logstash
小结: 因为量级不够大, 用不到 fluentd 和 logstash; 因为研发有需求通过 docker logs
快速查看日志, 所以不能用 syslog; 因为 json-file 有让日志文件无止境变大的问题, 而清掉这个日志只能通过停止⏹docker 服务后才能echo > filename
被重定向掉, 否则会引起 docker 服务的崩溃; 最终选择了现在大多数 Linux 发行版默认支持的 journald 日志服务.
更改 docker 的默认存储引擎
1 | > vim /etc/docker/daemon.js |
只需在 json 配置文件中加入一行日志引擎的配置即可, 最后重启 docker 服务
可以通过 docker info
查看更改后的日志引擎
指定 container 启动时的存储引擎
1 | docker run \ |
更换为 journald 日志引擎后, 所有使用 journald 引擎的 container 依然可以通过 docker logs containerName
的方式查看回显日志, 也可以在宿主机中使用 journalctl
命令来查看日志的集合,以下是 journalctl 的常用配置及用法简介
journald 配置文件
journald 的配置文件存放在 /etc/systemd/journald.conf
默认的内容如下:
1 | [Journal] |
journald 默认配置下, 默认日志最大限制为所在文件系统容量的 10%
默认配置下, journald 的日志存放在 /var/log/journal
下, 如果该目录在根分区下, 且根分区空间大小为10G, 那么 journald 存放日志最大的大小为1G, 超出1G 后将删除最早的日志
也可以精确指定占用的空间大小
1 | SystemMaxUse=50M |
其他 journald 的配置也没有细研究过, 主要还是没有需求~ 😆
journalctl 的使用
journalctl
从头查看所有日志journalctl -b
查看本次开机后的所有系统引导日志journalctl -b -1
显示上次开机后的系统引导日志, 以此类推journalctl -f
类似于tail -f
或tailf
journalctl /usr/bin/dockerd
后加程序的绝对路径,可以显示该程序的所有日志信息journalctl -xe
systemd 启动程序失败时会提示你使用这个命令查看错误信息, 其中x
表示在日志输出中增加一些解释性的短文本,e
表示立即跳转至日志的尾部
journald 使用注意事项
在 journald 日志引擎的实际使用中, 我们发现了另一个问题, 就是 journald 的默认配置文件中的一个问题. 在 journald 默认的配置文件中
1 | root@larry-ali:~# cat /etc/systemd/journald.conf |
有以下几个非常重要的优化项目
ForwardToSyslog=yes
ForwardToWall=yes
以上两个参数默认都是 yes
意味着 journald 收集日志后还会转发到 syslog 中
由此造成的影响是: journald 虽然可以乖乖的按照上面的配置进行日志的清理, 但是 syslog 却不在 journald 的控制范围之内
在日志量很大的情况下, 我们发现 syslog 中的日志量也变得巨大, 而且里面都是容器的日志, 所以我们需要把上面两个参数的值改为no
禁止🚫journald 收到日志后转发给 syslog
更改完配置文件后, 重启 journald 服务 systemctl restart systemd-journald.service
参考文档
docker 日志引擎官方文档: https://docs.docker.com/engine/admin/logging/overview/
journald 配置文件官方文档: https://www.freedesktop.org/software/systemd/man/journald.conf.html#
journalctl 命令官方文档: https://www.freedesktop.org/software/systemd/man/journalctl.html#
journalctl 中文man手册:http://www.jinbuguo.com/systemd/journalctl.html
journald.conf 中文手册:http://www.jinbuguo.com/systemd/journald.conf.html
journald 初级指南:http://os.51cto.com/art/201405/440886.htm