一、背景

服务每运行一段时间,系统盘空间都能以肉眼可见的速度再减少;不免让人好奇是谁在持续的占用空间,毕竟对于数据库、对象存储这些占空间的程序早已将其数据卷映射至其他磁盘上了。
难道是系统运行产生的一些日志文件,于是便开始逐步定位系统的大文件;最终发现是docker在运行过程中产生的日志文件过大。想到以前逻辑部署服务时,基于pm2守护进程帮忙管理日志文件,并能按日期切割;现在看来docker默认并没有这么做;因此,亟需调查docker如何实现定期清理日志文件。

二、问题定位

1. 定位大文件

基于du -sh 命令定位当前目录的总磁盘使用情况;于是很快定位到/var/lib/docker/containers 目录下容器的日志文件有些已经快10GB了。

 #过滤大文件
 du -sh /* | grep G
 #输出
 5G      /home
 32G     /var

 #进一步过滤大文件
 du -sh /var/* | grep G
 #输出
 30G     /var/lib
 2.0G    /var/log

 ...

2. 临时解决

  1. 方式一,直接删除日志文件

     #停止容器
     docker stop xxx
     #删除日志文件
     rm -rf xxx.json.log
     #启动容器
     docker start xxx
    
  2. 方式二,清空日志文件

     sh -c "cat /dev/null > xxx.json.log"  
    

三、设置docker容器日志限制

临时解决方案,只是暂时将磁盘空间得到释放;随着时间的推移,日志文件又将占满空间。虽然,可以设置定时任务,定期清理;但是我们还是希望能保留最近的日志,方便定位问题。当然,docker给了解决方案;既可以设置单个容器日志大小,也可以全局设置日志大小。

1. 单个容器日志限制

  1. 修改docker-compose.yaml 文件;添加logging部分内容:

     nginx: 
       image: nginx:latest 
       logging: 
         driver: "json-file" 
         options: 
           max-size: "100m" # 单个日志文件大小上限为100MB
           max-file: "3"    # 最多有三个日志文件
    
  2. 重启docker容器即可生效

     docker-compose up -d
    

2. 全局设置

  1. 编辑/etc/docker/daemon.json 文件;添加以下内容:

     {
       "log-driver":"json-file",
       "log-opts": {
         "max-size":"100m",
         "max-file":"3"
       }
     }
    
  2. 重启 Docker 服务
    注:对于已经创建的容器,修改内容并不会生效;所以必须重新创建容器,可以使用--force-recreate参数强制重新创建容器即可。

     #重新加载docker守护进程配置文件
     systemctl daemon-reload
    
     #重启 Docker 服务
     systemctl restart docker
    
     #重启容器并强制重新创建容器
     docker-compose up -d --force-recreate
    
  3. 查看配置是否生效

     #检查Docker对象的详细信息(xxx:容器ID)
     docker inspect xxx
    
     #输出信息如下即为成功
     "LogConfig": {
       "Type": "json-file",
       "Config": {
         max-size: "100m"
         max-file: "3"  
       }
     }
    

四、官方文档

https://docs.docker.com/config/containers/logging/configure/#configure-the-default-logging-driver

五、总结

docker确实给我们带来了很多便利,想以前裸机部署项目的时候,手动下载各种软件都会耗费一定的时间;而现在基于docker的CI/CD,让我们的服务不论是迭代上线,还是在新的环境部署,都能快速的实现。
不过,在使用docker过程中,难免会踩一些坑;在此做个记录,以免重复踩坑。