Docker磁盘空间自动化清理实战

Docker 磁盘空间自动化清理实战

前言

作为一名开发者或运维工程师,你是否经常遇到 Docker 磁盘空间不足的问题?随着容器化技术的广泛应用,Docker 镜像、容器和网络等资源会不断累积,占用大量磁盘空间。今天,我将分享一套完整的 Docker 自动清理方案,帮助你轻松管理 Docker 磁盘空间。

问题背景

在日常开发和生产环境中,Docker 会累积大量未使用的资源:

  • 过时的镜像版本
  • 停止的容器实例
  • 未使用的网络和卷
  • 构建缓存

这些资源如果不及时清理,可能导致磁盘空间告急,影响系统正常运行。手动清理既繁琐又容易遗忘,因此我们需要一套自动化解决方案。

解决方案概览

我们通过以下步骤实现 Docker 自动清理:

  1. 创建智能清理脚本
  2. 设置定时执行任务
  3. 建立完善的日志监控机制

实战步骤

第一步:创建智能清理脚本

我们首先创建一个功能全面的清理脚本,它不仅能清理3个月前的镜像,还能清理其他未使用的资源,并提供详细的操作日志。

bash 复制代码
mkdir -p /usr/local/bin/docker-cleanup && cat > /usr/local/bin/docker-cleanup/cleanup.sh << EOF 

#!/bin/bash

# Docker 3个月镜像清理脚本

echo "=============================="
echo "Docker 磁盘清理开始 - \$(date)"
echo "=============================="

# 记录开始时间
START_TIME=\$(date +%s)

# 1. 查看清理前磁盘使用情况
echo -e "\n1. 清理前 Docker 磁盘使用情况:"
docker system df

# 2. 清理3个月前的未使用镜像
echo -e "\n2. 清理3个月前的未使用镜像:"
docker image prune -a -f --filter "until=2160h"  # 2160小时 = 3个月
echo "3个月前的镜像已清理"

# 3. 清理所有停止的容器
echo -e "\n3. 清理已停止的容器:"
docker container prune -f
echo "已停止的容器已清理"

# 4. 清理未使用的网络
echo -e "\n4. 清理未使用的网络:"
docker network prune -f
echo "未使用的网络已清理"

# 5. 清理构建缓存
echo -e "\n5. 清理构建缓存:"
docker builder prune -f
echo "构建缓存已清理"

# 6. 查看清理后磁盘使用情况
echo -e "\n6. 清理后 Docker 磁盘使用情况:"
docker system df

# 7. 计算并显示释放的空间
END_TIME=\$(date +%s)
DURATION=\$((END_TIME - START_TIME))

echo "=============================="
echo "清理完成 - \$(date)"
echo "执行时间: \${DURATION} 秒"
echo "=============================="

# 8. 发送清理报告到系统日志
logger "Docker 定期清理完成,耗时 \${DURATION} 秒"

exit 0
EOF

脚本功能详解:

  1. 时间过滤清理 :使用 --filter "until=2160h" 参数,只清理3个月前的镜像,保护近期使用的镜像
  2. 全面清理:不仅清理镜像,还包括容器、网络、构建缓存
  3. 可视化报告:清理前后都显示 Docker 磁盘使用情况
  4. 性能监控:记录执行时间,方便性能优化
  5. 系统日志:将执行结果写入系统日志,便于集中监控

第二步:授权脚本执行权限

bash 复制代码
chmod +x /usr/local/bin/docker-cleanup/cleanup.sh

这一步很关键,确保脚本有执行权限。建议使用 sudo 执行,因为 Docker 命令通常需要 root 权限。

第三步:配置 Crontab 定时任务

Crontab 是 Linux 系统的定时任务管理器,我们利用它来设置每日自动清理。

bash 复制代码
# 编辑 crontab
sudo crontab -e

添加以下内容:

bash 复制代码
# Docker 自动清理配置
# 每天凌晨6点执行清理(系统负载较低时段)
0 6 * * * /usr/local/bin/docker-cleanup/cleanup.sh >> /var/log/docker-cleanup.log 2>&1

# 每周一凌晨3点清理30天前的日志文件(防止日志文件过大)
0 3 * * 1 find /var/log/docker-cleanup-*.log -mtime +30 -delete

Crontab 时间表达式解释:

  • 0 6 * * *:每天6:00执行
  • >> /var/log/docker-cleanup.log 2>&1:将标准输出和错误输出都重定向到日志文件
  • 0 3 * * 1:每周一3:00执行
  • -mtime +30:删除30天前的文件

第四步:验证配置

完成配置后,需要进行验证以确保一切正常工作。

bash 复制代码
# 查询定时任务信息
sudo crontab -l

# 立即运行一次(测试用)
sudo /usr/local/bin/docker-cleanup/cleanup.sh

# 查看日志
tail -50 /var/log/docker-cleanup.log

测试时建议:

  1. 先手动执行脚本,检查输出是否符合预期
  2. 可以使用 docker system df 查看清理前后对比
  3. 检查日志文件是否正确生成

进阶配置

方案一:增强日志功能

如果你需要更详细的日志,可以修改脚本的日志部分:

bash 复制代码
# 在脚本开头添加日志配置
LOG_FILE="/var/log/docker-cleanup/$(date +%Y%m%d).log"
exec &> >(tee -a "$LOG_FILE")

方案二:邮件通知

想要接收清理报告?添加邮件通知功能:

bash 复制代码
# 安装邮件客户端
sudo apt-get install mailutils -y

# 在脚本末尾添加
echo "清理报告" | mail -s "Docker清理完成 $(date)" your-email@example.com

方案三:安全备份机制

在清理前自动备份重要镜像:

bash 复制代码
# 在清理脚本开头添加备份逻辑
BACKUP_DIR="/backup/docker-images"
mkdir -p $BACKUP_DIR

# 备份特定标签的镜像
docker images --format "{{.Repository}}:{{.Tag}}" | grep -v "<none>" | while read image; do
    if [[ $image == *:latest ]] || [[ $image == *:stable ]]; then
        echo "备份重要镜像: $image"
        docker save -o "$BACKUP_DIR/$(echo $image | tr '/' '_' | tr ':' '_').tar" $image
    fi
done

注意事项

1. 风险控制

  • 测试环境先验证:在生产环境部署前,先在测试环境充分测试
  • 使用 --dry-run :可以使用 docker image prune -a --dry-run --filter "until=2160h" 预览将被删除的镜像
  • 重要镜像保护:为重要镜像添加保护标签,避免被清理

2. 性能考虑

  • 选择低峰时段:凌晨执行避免影响业务
  • 监控执行时间:如果清理时间过长,考虑调整清理策略
  • 磁盘空间预警:可以结合磁盘监控,空间不足时自动触发清理

3. 特殊情况处理

  • 构建服务器:如果使用 Docker 进行持续集成,可能需要保留更长的构建缓存
  • 生产环境:生产环境可能需要对清理策略更保守
  • 多节点集群:在 Docker Swarm 或 Kubernetes 集群中,需要在所有节点部署

监控与维护

查看清理效果

bash 复制代码
# 查看历史清理记录
grep "Docker 定期清理完成" /var/log/syslog

# 查看磁盘空间变化
df -h /var/lib/docker

# 查看镜像数量变化
docker images | wc -l

日志轮转配置

为防止日志文件过大,可以配置 logrotate:

bash 复制代码
sudo nano /etc/logrotate.d/docker-cleanup

添加以下内容:

复制代码
/var/log/docker-cleanup.log {
    daily
    rotate 7
    compress
    delaycompress
    missingok
    notifempty
    create 644 root root
}

总结

通过以上配置,我们实现了一个全自动的 Docker 磁盘清理方案,具有以下优点:

  1. 自动化:无需人工干预,定时执行
  2. 安全可控:只清理3个月前的资源,保护重要数据
  3. 全面清理:覆盖镜像、容器、网络、缓存等多个维度
  4. 可追溯:完整的日志记录,便于问题排查
  5. 灵活可扩展:可以根据需要调整清理策略

这套方案已经在多个生产环境中稳定运行,有效解决了 Docker 磁盘空间问题。希望这篇文章能帮助你更好地管理 Docker 环境,让你的系统始终保持最佳状态。

扩展思考

如果你有更复杂的需求,可以考虑:

  1. 按项目清理:只清理特定项目的镜像
  2. 智能保留策略:根据使用频率自动决定保留哪些镜像
  3. 集群级清理:在 Docker Swarm 或 Kubernetes 集群中统一管理
  4. 与 CI/CD 集成:在流水线结束后自动清理临时资源

如果你有任何问题或改进建议,欢迎在评论区留言讨论!

相关推荐
尼古拉斯·纯情暖男·天真·阿玮2 小时前
实验七 防火墙与入侵防护实验
linux·服务器·网络
b***25112 小时前
储能电池包制造中18650电池点焊机的关键作用
自动化·制造
AirDroid_cn2 小时前
Realme怎样远程控制oppo?手机自带的功能可以实现吗?
运维·服务器·网络
咕噜咕噜啦啦2 小时前
Windows安装CVAT
linux·服务器·opencv
负二代0.02 小时前
Linux的进程管理
linux·运维·服务器
ChineHe2 小时前
Docker基础篇001_Docker入门指南(基于官方教程,5W字详细版)
运维·docker·微服务·容器·云计算·devops
IT 行者2 小时前
Spring Security 7 之 OIDC /connect/userinfo 端点解析:ID Token 与用户信息获取
linux·服务器·spring
一只鹿鹿鹿2 小时前
springboot集成工作流教程(全面集成以及源码)
大数据·运维·数据库·人工智能·web安全
慧一居士2 小时前
同一个服务器上不同的域名跳往不同的前端项目页面,不显示端口号 ngnix根据不同域名跳转
运维·服务器·前端