在运维工作中,Docker怎么清理容器磁盘空间?

在运维工作中,Docker容器会产生大量的磁盘占用(如镜像层、容器日志、数据卷等),若不及时清理,可能导致宿主机磁盘满,影响容器运行。以下是Docker磁盘空间清理的核心方法常用命令自动化策略,按优先级排序:

一、第一步:查看磁盘使用情况

在清理前,需明确磁盘空间占用分布(镜像、容器、数据卷、缓存),使用 docker system df 命令:

docker system df
# 输出示例:
TYPE                TOTAL     ACTIVE    SIZE      RECLAIMABLE
Images              20        10        1.2GB     800MB (66%)
Containers          15        5         500MB     400MB (80%)
Local Volumes       8         3         2GB       1.5GB (75%)
Build Cache         50        0         3GB       3GB (100%)
  • 关键指标
    • RECLAIMABLE 列显示可回收的空间大小及比例;
    • Build Cache 通常占用最大,且可完全清理(若不需要构建缓存)。

二、第二步:清理已停止的容器

已停止的容器(Exited状态)仍会占用磁盘空间,尤其是容器内有大量日志时。

1. 手动清理指定容器

# 删除单个容器(需先停止)
docker rm 容器ID/名称

# 强制删除运行中的容器(不推荐,可能导致数据丢失)
docker rm -f 容器ID/名称

# 删除所有已停止的容器(安全)
docker container prune

2. 批量清理长期未运行的容器

# 删除7天前创建的所有容器(先查看,确认后删除)
docker ps -a --filter "created before=$(date -d '7 days ago' +%Y-%m-%dT%H:%M:%S)" --format '{{.ID}}' | xargs docker rm

三、第三步:清理无用镜像

镜像占用空间通常最大,尤其是多版本镜像(如app:v1app:v2)或构建失败的中间镜像。

1. 手动删除指定镜像

# 删除单个镜像(需确保无容器依赖)
docker rmi 镜像ID/名称:标签

# 强制删除镜像(即使有容器依赖,不推荐)
docker rmi -f 镜像ID

# 删除所有悬空镜像(dangling images,即无标签的中间层镜像)
docker image prune

2. 批量删除未使用的镜像

# 删除所有未被容器使用的镜像(谨慎!可能删除当前环境不需要但未来需要的镜像)
docker image prune -a

# 删除特定标签的镜像(如所有测试镜像)
docker images | grep "test" | awk '{print $3}' | xargs docker rmi

四、第四步:清理数据卷(Volumes)

数据卷是持久化存储,但无用的数据卷(如容器删除后残留的卷)会持续占用空间。

1. 手动删除指定数据卷

# 删除单个数据卷
docker volume rm 卷名称

# 删除所有未被容器使用的卷(谨慎!可能删除有用的持久化数据)
docker volume prune

2. 批量清理长期未使用的数据卷

# 查找并删除超过30天未使用的数据卷(需借助第三方工具,如docker-volume-cleanup)

五、第五步:清理构建缓存(Build Cache)

Docker构建过程中会生成大量中间层缓存(Build Cache),若不需要快速重建镜像,可清理。

# 清理所有构建缓存(谨慎!会导致下次构建变慢)
docker builder prune -a

# 保留最近3天的构建缓存
docker builder prune --filter "until=72h"

六、第六步:清理日志文件

容器日志(如/var/lib/docker/containers/容器ID/容器ID-json.log)可能疯狂增长,需定期清理或配置日志轮转。

1. 临时清理现有日志

# 查看容器日志大小(需进入宿主机)
du -sh /var/lib/docker/containers/*/*-json.log

# 清空单个容器日志(不删除文件,避免影响容器)
cat /dev/null > /var/lib/docker/containers/容器ID/容器ID-json.log

# 批量清空所有容器日志(先确认路径,再执行)
find /var/lib/docker/containers/ -name "*-json.log" -exec sh -c 'echo > {}' \;

2. 配置日志驱动与大小限制(推荐)

/etc/docker/daemon.json中添加日志限制配置,重启Docker生效:

{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",  # 单个日志文件最大10MB
    "max-file": "3"     # 最多保留3个日志文件
  }
}

七、第七步:自动清理策略

为避免手动清理,可配置定时任务或使用工具自动执行清理。

1. 配置cron定时清理(推荐)

每周日凌晨2点清理未使用资源:

# 编辑cron表
crontab -e

# 添加任务(保留最近24小时的构建缓存,删除所有未使用资源)
0 2 * * 0 docker system prune -a --filter "until=24h" --volumes

2. 使用docker-gc等第三方工具

# 安装docker-gc(自动清理未使用镜像和容器)
curl -sSL https://raw.githubusercontent.com/spotify/docker-gc/master/docker-gc > /usr/local/bin/docker-gc
chmod +x /usr/local/bin/docker-gc

# 配置白名单(/etc/docker-gc-exclude)
echo "image:app:prod" > /etc/docker-gc-exclude

# 每天执行一次
0 0 * * * /usr/local/bin/docker-gc

八、深度清理:重建Docker数据目录(谨慎操作)

若磁盘空间极度紧张,且上述方法无效,可考虑重建Docker数据目录(需停机,数据卷需提前备份):

# 1. 停止Docker服务
systemctl stop docker

# 2. 备份重要数据卷(如数据库卷)
cp -r /var/lib/docker/volumes/mysql-data /backup/

# 3. 删除Docker数据目录(危险!)
rm -rf /var/lib/docker

# 4. 重启Docker(会重新初始化数据目录)
systemctl start docker

# 5. 恢复数据卷
cp -r /backup/mysql-data /var/lib/docker/volumes/

九、清理效果验证

清理后,再次检查磁盘使用情况:

# 查看Docker磁盘使用
docker system df

# 查看宿主机磁盘空间
df -h

总结:清理优先级与最佳实践

  1. 优先清理docker system prune -a --volumes(删除所有未使用镜像、容器、数据卷);
  2. 次优先:清理构建缓存(docker builder prune)和容器日志;
  3. 长期策略:配置日志大小限制(max-size)和自动清理cron任务;
  4. 注意事项
    • 清理前确认无重要数据(如数据库卷);
    • 避免在业务高峰期执行大规模清理;
    • 对生产环境建议先测试清理脚本,再上线。

通过定期清理和合理配置,可有效控制Docker磁盘空间增长,避免因磁盘满导致的生产事故。

posted @ 2025-07-28 20:42  天道酬勤zjh  阅读(300)  评论(0)    收藏  举报