Docker 容器日志管理与清理实战指南

在生产环境中,Docker 容器运行时间一长,日志文件很容易堆积,占用大量磁盘空间,甚至导致服务器磁盘满而影响服务正常运行。本文将详细介绍 Docker 容器日志的管理方法、清理策略以及自动化方案。

一、Docker 日志存储位置

Docker 容器的日志默认存储在宿主机的 /var/lib/docker/containers/<容器ID>/<容器ID>-json.log 文件中。可以通过以下命令查看容器日志文件的实际位置:

docker inspect --format='{{.LogPath}}' <容器名称或ID>

例如:

docker inspect --format='{{.LogPath}}' nginx

二、查看容器日志大小

2.1 查看单个容器日志大小

du -h $(docker inspect --format='{{.LogPath}}' <容器ID>)

2.2 查看所有容器日志总大小

du -h $(docker inspect --format='{{.LogPath}}' $(docker ps -aq))

或者更简洁的方式:

docker system df

这条命令会显示 Docker 整体的磁盘使用情况,包括镜像、容器、数据卷等占用的空间。

三、手动清理容器日志

3.1 清空单个容器日志

truncate -s 0 $(docker inspect --format='{{.LogPath}}' <容器ID>)

注意:不要直接使用 rm 命令删除日志文件,因为 Docker 进程会保持文件句柄打开,删除后空间不会释放,需要重启容器才能回收空间。使用 truncate 清空文件内容则不会有这个问题。

3.2 批量清空所有容器日志

创建一个清理脚本:

#!/bin/bash
# 清理所有Docker容器日志

echo "开始清理 Docker 容器日志..."

# 获取所有运行中容器的日志路径
containers=$(docker ps -q)
for container in $containers; do
    logpath=$(docker inspect --format='{{.LogPath}}' $container)
    if [ -f $logpath ]; then
        echo "清空容器 $container 的日志: $logpath"
        truncate -s 0 $logpath
    fi
done

# 清理已停止容器的日志
stopped_containers=$(docker ps -aq --filter "status=exited")
for container in $stopped_containers; do
    logpath=$(docker inspect --format='{{.LogPath}}' $container 2>/dev/null)
    if [ -f "$logpath" ]; then
        echo "清空已停止容器 $container 的日志: $logpath"
        truncate -s 0 $logpath
    fi
done

echo "日志清理完成!"

保存为 clean-docker-logs.sh,赋予执行权限并运行:

chmod +x clean-docker-logs.sh
./clean-docker-logs.sh

四、配置 Docker 日志滚动策略

为了避免日志无限增长,最好的方式是在 Docker 配置文件中设置全局的日志滚动策略,或者在启动单个容器时指定日志参数。

4.1 全局配置日志策略

编辑 Docker 配置文件 /etc/docker/daemon.json

{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m",
    "max-file": "3"
  }
}

配置说明:

  • max-size: 100m:单个日志文件最大 100MB
  • max-file: 3:最多保留 3 个日志文件

配置完成后需要重启 Docker 服务:

systemctl daemon-reload
systemctl restart docker

注意:全局配置只对新建的容器生效,已存在的容器需要重建才能应用新的日志策略。

4.2 单个容器启动时指定日志策略

在启动容器时通过 --log-opt 参数指定:

docker run -d   --name nginx   --log-opt max-size=100m   --log-opt max-file=3   nginx:latest

五、使用 logrotate 管理日志

对于已经在运行且不方便重建的容器,可以使用系统的 logrotate 工具来管理日志。

创建 logrotate 配置文件 /etc/logrotate.d/docker

/var/lib/docker/containers/*/*.log {
    daily
    rotate 7
    compress
    delaycompress
    missingok
    notifempty
    copytruncate
    size 100M
}

配置说明:

  • daily:每天轮转一次
  • rotate 7:保留 7 个备份
  • compress:压缩旧日志
  • copytruncate:先复制文件内容再清空,避免 Docker 进程无法写入
  • size 100M:单个文件超过 100MB 时轮转

可以手动测试配置是否生效:

logrotate -d /etc/logrotate.d/docker

六、定时自动清理

可以将清理脚本加入 crontab 定时执行,例如每天凌晨 2 点清理一次:

crontab -e

添加以下内容:

0 2 * * * /root/clean-docker-logs.sh >> /var/log/clean-docker-logs.log 2>&1

七、最佳实践建议

  1. 提前配置日志策略:在部署容器前就规划好日志大小和保留策略,不要等磁盘满了才临时处理
  2. 集中化日志收集:使用 ELK(Elasticsearch + Logstash + Kibana)或 Loki 等工具将容器日志集中收集和管理
  3. 定期监控磁盘空间:设置磁盘空间告警,及时发现异常增长
  4. 区分日志级别:生产环境避免输出过多 debug 级别的日志,减少日志产生量
  5. 应用内部日志管理:容器内的应用日志也应该配置滚动策略,不要全部输出到 stdout/stderr

通过以上方法,可以有效管理 Docker 容器日志,避免日志文件无限增长导致的磁盘空间问题,保证服务器稳定运行。