人生理想,技术交流加Q:411239339

救命!Docker又偷偷吃了我100G硬盘

浏览:29次阅读
没有评论

共计 2613 个字符,预计需要花费 7 分钟才能阅读完成。

一、问题背景:硬盘又哭了

你是不是也遇到过这种情况:某天打开服务器一看,硬盘空间莫名其妙只剩下几个 G 了。一查才发现,Docker 这家伙悄悄占了几十个 G,甚至上百 G 的空间。

这事儿其实挺常见的。Docker 用着用着,就像家里的储物间一样,堆满了各种 " 可能以后用得上 " 的东西:

  • 早就不用的旧镜像还躺在那里
  • 测试完就停掉的容器尸体遍地
  • 各种构建过程中产生的临时文件
  • 已经悬空 (dangling) 的镜像层

最要命的是,Docker 默认不会主动清理这些东西。它就像一个勤俭持家的老人,啥都舍不得扔。

二、解决方案:对症下药

2.1 先看看到底占了多少空间

开工之前,咱得先摸清家底:

docker system df

这命令会给你一个清晰的报告,类似这样:

TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
Images          15        5         8.5GB     6.2GB (72%)
Containers      20        3         2.1GB     1.8GB (85%)
Local Volumes   10        2         3.2GB     2.8GB (87%)
Build Cache     0         0         0B        0B

看到那个 RECLAIMABLE(可回收)没?那就是可以安全清理的空间。

2.2 终极大招:一键清理

如果你不想搞太复杂,直接上这个:

docker system prune -a --volumes

警告:这个命令会删除:

  • 所有停止的容器
  • 所有没有被容器使用的网络
  • 所有没有被使用的镜像(不只是悬空镜像)
  • 所有没有被使用的卷

执行前它会问你确认,输入 y 就开始清理了。

适用场景:测试环境、个人开发机器,或者你确定那些镜像不要了。

2.3 温柔版:分步清理

如果是生产环境,还是稳一点比较好:

第一步:清理停止的容器

docker container prune

这只删除已经停止的容器,不影响运行中的服务。

第二步:清理悬空镜像

docker image prune

悬空镜像就是那些没有标签的中间层镜像,通常是构建过程中产生的。

第三步:清理未使用的镜像

docker image prune -a

加了 -a 参数后,会删除所有没被容器使用的镜像。慎用!

第四步:清理数据卷

docker volume prune

这个要特别小心,数据卷里可能有数据库数据等重要内容。

2.4 进阶技巧:定向清理

有时候你只想删除特定的东西:

删除指定时间之前的容器

docker container prune --filter "until=24h"

删除特定镜像

docker rmi 镜像 ID
# 或者强制删除
docker rmi -f 镜像 ID

批量删除未使用的镜像

docker images | grep "none" | awk '{print $3}' | xargs docker rmi

2.5 查看清理效果

清理完再跑一次:

docker system df

看着回收的空间数字往下掉,是不是有种收拾完房间的爽快感?

三、原理说明:为什么会占这么多空间

3.1 Docker 的存储机制

Docker 使用了一种叫 " 分层存储 " 的机制。每个镜像都由多个只读层组成,容器运行时会在最上面加一个可写层。

这种设计很聪明,可以节省空间(多个容器共享相同的基础层),但也容易产生垃圾:

  • 你拉取了一个镜像的多个版本,旧版本不会自动删除
  • 构建镜像时,每个指令都会创建一层
  • 容器停止后,它的可写层还在占空间

3.2 Ubuntu 24.04 的特殊性

Ubuntu 24.04 使用的是较新的存储驱动(通常是 overlay2),虽然效率更高,但对于文件系统的占用计算可能有点 " 诚实过头 "。

另外,Ubuntu 24.04 的默认文件系统是 ext4,inode 的占用也要考虑进去。如果你创建了大量小文件的镜像,可能 inode 先用完,而不是实际空间。

可以用这个命令查看:

df -ih

四、常见问题

Q1:清理后空间还是没释放怎么办?

这可能是因为 Docker 使用了 thin pool 或者其他存储驱动的特性。试试重启 Docker 服务:

sudo systemctl restart docker

如果还不行,检查一下是不是容器日志占了空间:

sudo du -sh /var/lib/docker/containers/*/*-json.log

日志太大的话,可以配置日志轮转:

// /etc/docker/daemon.json
{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  }
}

Q2:误删了重要镜像怎么办?

赶紧重新拉取:

docker pull 镜像名: 标签

所以,清理前最好先备份一下镜像列表:

docker images > docker_images_backup.txt

Q3:能不能设置自动清理?

当然可以!创建一个定时任务:

sudo crontab -e

添加这一行(每周日凌晨 3 点清理):

0 3 * * 0 docker system prune -f

-f 参数表示不需要确认,直接清理。

Q4:生产环境能用 prune 吗?

可以,但要慎重:

    1. 千万别用 -a --volumes,会把正在用的镜像都标记为可删除
  1. 只用 docker system prune -f(不带 -a),它只清理悬空资源
  2. 最好在业务低峰期执行
  3. 提前做好备份和镜像清单

Q5:为什么我的 Docker 目录在 /var/lib/docker 占了很多空间?

这是 Docker 的默认数据目录。如果根分区空间不够,可以考虑迁移 Docker 目录:

# 停止 Docker
sudo systemctl stop docker

# 迁移数据
sudo mv /var/lib/docker /home/docker

# 创建软链接
sudo ln -s /home/docker /var/lib/docker

# 启动 Docker
sudo systemctl start docker

或者修改配置文件指定新路径:

// /etc/docker/daemon.json
{"data-root": "/home/docker"}

总结

Docker 空间清理其实不难,关键是要:

    1. 定期检查​:养成习惯,每隔一段时间跑一次 docker system df
    1. 按需清理:测试环境可以激进点,生产环境要保守
    1. 做好备份:清理前记录一下现有的镜像和容器
    1. 配置日志:防止日志文件无限增长
    1. 自动化:设置定时任务,省心省力

记住一句话:​磁盘空间就像钱包,总是在你不注意的时候就空了。定期清理,服务器才能跑得更欢快!


微信公众号文章:mp.weixin.qq.com/s/jqDizYje-SvThQ2opxFH0A

有问题欢迎留言讨论,如果这篇文章帮到了你,别忘了点个「在看」!

正文完
创作不易,扫码加点动力
post-qrcode
 0
果较瘦
版权声明:本站原创文章,由 果较瘦 于2026-01-11发表,共计2613字。
转载说明:除特殊说明外本站文章皆由果较瘦原创发布,转载请注明出处。