Docker容器日志占用空间过大的解决方式

 更新时间:2024年03月08日 08:40:13   作者:MuShanYu  
当我们尝试查看特定 Docker 容器的日志时,通常会使用 docker logs <容器名称> 命令,,然而,有时候会发现控制台持续输出日志信息,持续时间可能相当长,直到最终打印完成,导致日志积累过多,占用了系统磁盘空间,所以本文给大家介绍了解决方法,需要的朋友可以参考下

1. 问题描述

当我们尝试查看特定 Docker 容器的日志时,通常会使用 docker logs <容器名称> 命令。然而,有时候会发现控制台持续输出日志信息,持续时间可能相当长,直到最终打印完成。这种现象往往源自对 Docker 容器日志长时间未进行处理,导致日志积累过多,占用了系统磁盘空间。因此,为了释放磁盘空间优化系统性能,我们可以采取一些简单而有效的方法来处理这些庞大的日志文件

2. docker日志处理机制

需要处理问题,那我们肯定要先了解docker的日志处理机制,了解了基本的机制,能够帮助我们更好的理解问题并解决问题。

2.1 日志查看

docker logs <容器名称>可以查看docker容器的输出日志,但是这里的日志主要包含标准输出标准错误输出,一些容器可能会把日志输出到某个日志文件中,比如tomcat,这样使用docker logs <容器名称>命令是无法查看的。

注意docker logs命令查看的是容器的全部日志,当日志量很大时会对容器的运行造成影响,可以通过docker logs --tail N container name查看最新N行的数据,N是一个整数。

2.2 处理机制

当我们启动一个docker容器时,实际上时作为docker daemon的一个子进程运行的,docker daemon可以拿到容器里进程的标准输出与标准错误输出,并通过docker的log driver模块来处理,大致图示如下:

上面图中所列举的就是所支持的Log Driver:

  • none:容器没有日志,docker logs不输出任何内容
  • local:日志以自定义格式存储
  • json-file:日志以json格式存储,默认的Log Driver
  • syslog:将日志写入syslog。syslog守护程序必须在主机上运行
  • journald:将日志写入journald。journald守护程序必须在主机上运行
  • gelf:将日志写入Graylog Extended Log Format端点,如Graylog或Logstash
  • fluentd:将日志写入fluentd。fluentd守护程序必须在主机上运行
  • awslogs:将日志写入Amazon CloudWatch Logs
  • splunk:通过HTTP Event Collector将日志写入splunk
  • etwlogs:将日志作为ETW(Event Tracing for Windows)事件写入。只在Windows平台可用
  • gcplogs:将日志写入Google Cloud Platform Logging
  • logentries:将日志写入Rapid7 Logentries

可以使用命令docker info | grep "Logging Driver"

2.3 默认的json-file

json-file Log Driver是Docker默认启用的Driver,将容器的STDOUT/STDERR输出以json的格式写到宿主机的磁盘,日志文件路径为 /var/lib/docker/containers/{container_id}/{container_id}-json.log

格式是这样的:

json-file将每一行日志封装到一个json字符串中。

json-file支持如下配置:

  • max-size:单个日志文件的最大大小,单位可以为k、m、g,默认是-1,表示日志文件可以无限大。
  • max-file:最多可以存多少个日志文件,默认数量是1,当默认数量大于1时,每个日志文件达到最大存储大小,且数量达到设置数量,产生新日志时会删除掉最旧的一个日志文件。
  • labels:指定日志所使用到的标签,使用逗号分割。比如traceId,message两个标签。
  • env:指定与日志相关的环境变量,使用逗号分割
  • env-rejex:一个正则表达式来匹配与日志相关的环境变量
  • compress:是否压缩日志文件

3. 如何解决?

3.1 查看日志大小

我们可以通过如下脚本获取当前所有容器的日志大小,这里时使用docker默认的json-file的形式:

#!/bin/sh 
echo "======== docker containers logs file size ========"  

logs=$(find /var/lib/docker/containers/ -name *-json.log)

for log in $logs
do
    ls -lh $log
done

执行脚本:

json-file的命令开头的一小串字符时容器的id。

例如我有一个docker容器id是2de6f164ee11,我们可以适当修改shell脚本,查看某一个容器的日志大小。

logs=$(find /var/lib/docker/containers/ -name *-json.log | grep "2de6f164ee11")

3.2 删除日志

如果docker容器正在运行,使用rm -rf的方式删除日志后,磁盘空间并没有释放。原因是在Linux或者Unix系统中,通过rm -rf或者文件管理器删除文件,将会从文件系统的目录结构上解除链接(unlink)。如果文件是被打开的(有一个进程正在使用),那么进程将仍然可以读取该文件,磁盘空间也一直被占用。

正确的方式是直接使用命令改写日志文件。

cat /dev/null > *-json.log
  • cat: 是一个命令,用于连接文件并打印它们的内容到标准输出(通常是终端)。
  • /dev/null: 是一个特殊的设备文件,向它写入的内容会被丢弃,读取它将会立即返回结束符。
  • >: 是重定向操作符,将命令的输出重定向到文件。
  • *-json.log: 是通配符,用于匹配当前目录中所有以 -json.log 结尾的文件。

可以使用如下脚本,直接处理所有的日志文件:

#!/bin/sh 
echo "======== start clean docker containers logs ========"  

logs=$(find /var/lib/docker/containers/ -name *-json.log)

for log in $logs
        do
                echo "clean logs : $log"  
                cat /dev/null > $log
        done

echo "======== end clean docker containers logs ========"

注意,虽然使用这种方式可以删除日志,释放磁盘,但是过一段时间后,日志又会涨回来,所以要从根本上解决问题,只需要添加两个参数。没错!就是上面所讲到的max-size和max-file。

3.3 治本操作

在运行docker容器时,添加上max-size和max-file可以解决日志一直增长的问题。

docker run -it --log-opt max-size=10m --log-opt max-file=3 alpine ash

这段启动命令表示总共有三个日志文件,每个文件的最大大小时10m,这样就能将该容器的日志大小控制在最大30m。

4. 总结

在运行容器时,我们就应该优先考虑如何处理日志的问题,后面不必为容器运行后所产生的巨大日志而手足无措。

当然需要删除无用日志可以通过3.1,3.2的操作完成,建议在运行容器的时候加上max-size和max-file参数或者至少加上max-size参数。

以上就是Docker容器日志占用空间过大的解决方式的详细内容,更多关于Docker日志占用空间过大的资料请关注脚本之家其它相关文章!

相关文章

  • 使用Docker部署MySQL数据库的两种方法

    使用Docker部署MySQL数据库的两种方法

    在现代软件开发中,MySQL 是一种流行的关系数据库管理系统,因其可靠性和易用性受到广泛欢迎,通过 Docker,可以快速、便捷地部署和管理 MySQL 数据库实例,本文将介绍两种通过 Docker 部署 MySQL 的方法,需要的朋友可以参考下
    2024-10-10
  • Docker compose 编排工具详解

    Docker compose 编排工具详解

    Compose是一个用于定义和运行多容器Docker应用程序的工具。使用Compose,您可以使用Compose文件来配置应用程序的服务。然后,使用单个命令,您可以从配置中创建并启动所有服务
    2021-09-09
  • 低版本Docker升级高版本Docker的详细教程及成功避坑

    低版本Docker升级高版本Docker的详细教程及成功避坑

    如果我们使用docker来管理容器,那么保持docker引擎的更新将会是十分重要的,下面这篇文章主要给大家介绍了关于低版本Docker升级高版本Docker的详细教程及成功避坑,文中通过图文介绍的非常详细,需要的朋友可以参考下
    2023-05-05
  • 解决Docker错误“docker build“ requires exactly 1 argument(s)问题

    解决Docker错误“docker build“ requires exactly 1 argument(s)

    这篇文章主要介绍了解决Docker错误“docker build“ requires exactly 1 argument(s)问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-08-08
  • 在云服务器上基于docker安装jenkins的实现步骤

    在云服务器上基于docker安装jenkins的实现步骤

    本文主要介绍了在云服务器上基于docker安装jenkins的实现步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-07-07
  • Docker构建镜像的两种方式实现

    Docker构建镜像的两种方式实现

    从 docker 镜像仓库中下载的镜像不能满足我们的需求时,可以通过以下两种方式对镜像进行更改。本文就详细的介绍了这两种方法,感兴趣的可以了解一下
    2021-09-09
  • 在Docker中安装OnlyOffice的详细过程记录

    在Docker中安装OnlyOffice的详细过程记录

    OnlyOffice是一款免费且开源的Office协作办公套件,支持桌面端和移动端等多平台,下面这篇文章主要给大家介绍了关于如何在Docker中安装OnlyOffice的详细过程记录,需要的朋友可以参考下
    2024-01-01
  • spring-boot构建docker镜像上传仓库的示例教程

    spring-boot构建docker镜像上传仓库的示例教程

    这篇文章主要介绍了spring-boot构建docker镜像上传仓库,受限创建一个简单spring-boot-web项目,查看镜像上传仓库这时候有两种解决方案,对docker镜像上传仓库相关知识感兴趣的朋友跟随小编一起看看吧
    2022-12-12
  • 解决docker CMD/ENTRYPOINT执行sh脚本报: not found/run.sh:

    解决docker CMD/ENTRYPOINT执行sh脚本报: not found/run.sh:

    这篇文章主要介绍了解决docker CMD/ENTRYPOINT执行sh脚本报: not found/run.sh:的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-11-11
  • docker修改默认ip的实现步骤

    docker修改默认ip的实现步骤

    在 Docker 中,默认的网络是 bridge 网络,它通常使用 172.17.0.0/16 这个网段,那么如何修改,本文就来详细的介绍下docker修改默认ip的实现步骤,感兴趣的可以了解一下
    2024-02-02

最新评论