被 Docker 日志坑惨了

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 被 Docker 日志坑惨了

原文链接:被 Docker 日志坑惨了


最近在读《计算机程序的构造和解释》,里面有一句话:代码必须能够被人阅读,只是机器恰巧可以执行。


我也想到了一句话:BUG 一定能够被人写出,只是恰好我写的多而已。


说多了都是泪,来看看我最近遇到的一个问题。


问题


普通的一天,打开普通的电脑,登录一台普通的服务器,敲下一条普通的命令。


在我使用命令补全时,出现了一条不普通的提示:


-bash: cannot create temp file for here-document: No space left on device ls -bash
复制代码


怎么磁盘满了?


使用 df -h 一看还真是。


什么原因呢?


解决


首先,查找一下系统里的大文件,看看是哪个小可爱搞的鬼。


du -sh /* | grep G
复制代码


很快就定位到了这个目录:/var/lib/docker/containers


原来是 Docker 这家伙,这个目录下存放的都是容器运行过程中产生的日志。


使用下面命令来给这些文件按大小排个序:


du -d1 -h /var/lib/docker/containers | sort -h
32K /var/lib/docker/containers/d607c06e475191fff1abd0c2b4b672e7fe8a96cb197f4e8557b18600de2e60af
36K /var/lib/docker/containers/0d4321106721b9d26335fefef7b9e8e23629691684a4da2f953ac8223c8240c3
36K /var/lib/docker/containers/7525aab4aa917aa1016169114762261726ac7b9cc712bef35cdc7035b50d20ce
36K /var/lib/docker/containers/9252e1c373d59ef5613c2b6122eb6e43aa2bd822bd2c199aa67d6eb659c4adb7
142M  /var/lib/docker/containers
142M  /var/lib/docker/containers/15700ee92cd2831554b9a1e78127df0f07248c1498d35c17525407bc8a98bc1a
复制代码


文件名称就是容器 ID,每个文件对应一个容器,也就可以定位到,具体是哪个容器产生了大量的日志。


使用这个命令可以将大文件快速清空:


sh -c "cat /dev/null > ${log_file_name}"
复制代码

但是清空了文件哪算解决问题,新的日志还在源源不断往日志里打呢。看了看日志内容,很熟悉。前两天为了调试程序,刚加的一条 print


编辑代码,删除 print,重启容器。好了,日志不再疯狂追加了。


为什么 print 语句将日志都输出到文件里了呢?别着急,后面再来详细介绍。


先处理一下眼前的问题,放任日志无限增长是肯定不行的,需要有一个单个文件大小限制。否则,明天张三再加一条 print,磁盘又满了。


这里有两个方案:


  1. 单一容器配置


  1. 全局配置


单一容器配置


启动容器时,通过参数来控制日志的文件个数和单个文件的大小:


docker run -it --log-opt max-size=10m --log-opt max-file=3 redis
复制代码


但这样做是比较麻烦的,更多的采用的是全局配置的方式。


全局配置


编辑 /etc/docker/daemon.json


{
    "log-driver":"json-file",
    "log-opts":{
        "max-size" :"50m",
        "max-file":"3"
    }
}
复制代码


重启 Docker 服务:


systemctl daemon-reload
systemctl restart docker
复制代码


注意: 已存在的容器不会生效,需要重建才可以。


接下来再说说上文提到的 print 问题。


Docker 日志


Docker  日志分为两类:


  • Docker 引擎日志(也就是 dockerd 运行时的日志)


  • 容器的日志,容器内的服务产生的日志


引擎日志


Docker 引擎日志一般是交给了 Upstart(Ubuntu 14.04) 或者 systemd (CentOS 7, Ubuntu 16.04)。前者一般位于 /var/log/upstart/docker.log 下,后者一般通过 journalctl -u docker 进行查看。


不同系统的位置都不一样,网上有人总结了一份列表,我修正了一下,可以参考:


系统 日志位置
Ubuntu(14.04) /var/log/upstart/docker.log
Ubuntu(16.04) journalctl -u docker.service
CentOS 7/RHEL 7/Fedora journalctl -u docker.service
CoreOS journalctl -u docker.service
OpenSuSE journalctl -u docker.service
OSX ~/Library/Containers/com.docker.docker/Data/com.docker.driver.amd64-
Debian GNU/Linux 7 /var/log/daemon.log
Debian GNU/Linux 8 journalctl -u docker.service
Boot2Docker /var/log/docker.log


容器日志


使用下面命令可以显示当前运行的容器的日志信息:


docker logs CONTAINER
复制代码


UNIX 和 Linux 命令有三种输入输出,分别是 STDIN、STDOUT 和 STDERR。docker logs 显示的内容包含 STDOUT 和 STDERR。


在生产环境下,如果我们的应用输出到日志文件里,那么我们在使用 docker logs 时一般收集不到太多重要的信息。


这里来看一下 nginx 和 httpd 是怎么做的:


  • nginx 官方镜像,使用了一种方式,让日志输出到 STDOUT,也就是创建一个符号链接 /var/log/nginx/access.log 到 /dev/stdout。


  • httpd 使用的是让其输出到指定文件,正常日志输出到 /proc/self/fd/1 (STDOUT) ,错误日志输出到 /proc/self/fd/2 (STDERR)。


当日志量比较大的时候,使用 docker logs 来查看日志,会对 docker daemon 造成比较大的压力,容易导致容器创建慢等一系列问题。


只有使用了 local 、json-file、journald 日志驱动的容器才可以使用 docker logs 捕获日志,使用其他日志驱动无法使用 docker logs


Docker 默认使用 json-file 作为日志驱动。


除此之外,Docker 还提供了很多其他日志驱动,这里就不过多介绍。还有日志管理方案,我也不是很有经验,大家如果感兴趣的话自己搜搜看吧。




参考文章:


  1. www.cnblogs.com/zhangmingch…


  1. www.cnblogs.com/operationho…


文章中的脑图和源码都上传到了 GitHub,有需要的同学可自行下载。


地址:github.com/yongxinz/te…



相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
2月前
|
存储 Kubernetes 监控
在Docker中,很多应用容器都是默认后台运行的,怎么查看它们的输出和日志信息?
在Docker中,很多应用容器都是默认后台运行的,怎么查看它们的输出和日志信息?
|
3月前
|
存储 Docker 容器
docker查看日志:docker service logs 与 docker container logs
docker查看日志:docker service logs 与 docker container logs
154 0
|
5月前
|
存储 运维 监控
【Docker专栏】Docker日志管理与监控的最佳方法
【5月更文挑战第7天】本文探讨了Docker容器的日志管理与监控,强调其在运维中的重要性。Docker默认使用`json-file`日志驱动,可通过`docker logs`命令查看。建议选择合适日志驱动,配置日志选项,并集成ELK Stack等工具进行高级分析。实时监控、设置警报、分析数据和审计日志是实践关键。最佳实践包括日志数据与容器数据分离、使用日志代理、保护敏感信息及遵守法规。关注新技术以提升系统稳定性和安全性。
791 10
【Docker专栏】Docker日志管理与监控的最佳方法
|
5月前
|
监控 应用服务中间件 nginx
使用 Docker Compose V2 快速搭建日志分析平台 ELK (Elasticsearch、Logstash 和 Kibana)
ELK的架构有多种,本篇分享使用的架构如图所示: Beats(Filebeat) -> -> Elasticsearch -> Kibana,目前生产环境一天几千万的日志,内存占用大概 10G
278 4
|
5月前
|
Docker 容器
docker 全局日志控制
docker 全局日志控制
|
5月前
|
Docker 容器
一篇文章搞懂docker日志的查看
`docker logs` 命令用于查看Docker容器的日志,支持多个选项:`-f` 跟踪实时日志,`--since` 显示指定时间后的日志,`--tail` 显示指定行数(默认全部),`-t` 显示时间戳。例如,`docker logs -f --tail=200 <容器ID/名称>` 显示最后200行实时日志。还可以结合`grep`进行过滤,或使用`--since`和`--until`指定时间范围。日志可重定向至文件,如`docker logs <容器id> > container_logs.txt`。
1559 6
|
5月前
|
监控 Docker 容器
Docker从入门到精通:Docker log 命令学习
了解 Docker 日志管理对容器监控至关重要。`docker logs` 命令用于查看和管理容器日志,例如,`docker logs <container_name>` 显示容器日志,`-f` 或 `--follow` 实时跟踪日志,`--tail` 显示指定行数,`--timestamps` 添加时间戳,`--since` 按日期筛选。Docker 支持多种日志驱动,如 `syslog`,可通过 `--log-driver` 配置。有效管理日志能提升应用程序的稳定性和可维护性。
148 0
|
2月前
|
Kubernetes Ubuntu Windows
【Azure K8S | AKS】分享从AKS集群的Node中查看日志的方法(/var/log)
【Azure K8S | AKS】分享从AKS集群的Node中查看日志的方法(/var/log)
|
21天前
|
Java
日志框架log4j打印异常堆栈信息携带traceId,方便接口异常排查
日常项目运行日志,异常栈打印是不带traceId,导致排查问题查找异常栈很麻烦。
|
1月前
|
存储 监控 数据可视化
SLS 虽然不是直接使用 OSS 作为底层存储,但它凭借自身独特的存储架构和功能,为用户提供了一种专业、高效的日志服务解决方案。
【9月更文挑战第2天】SLS 虽然不是直接使用 OSS 作为底层存储,但它凭借自身独特的存储架构和功能,为用户提供了一种专业、高效的日志服务解决方案。
63 9
下一篇
无影云桌面