其实用 Docker 跑 Spring Cloud 微服务项目里挺常见的,本质问题基本都集中在 overlay2 存储层膨胀,不是数据库也照样能吃爆磁盘。

一、为什么会出现几百 G 的 overlay2

Docker 的 overlay2 本质是镜像层 + 容器写层叠加,Spring Cloud 项目容易踩这几个坑:

1️⃣ 日志疯狂增长(最常见)

Spring Boot 默认日志如果你没限制:

  • logs/*.log
  • catalina.out
  • 或 stdout(docker logs)

👉 在 Docker 里,这些会变成:

/var/lib/docker/containers/<id>/<id>-json.log

如果没做限制:

👉 一个服务一天能写几个 G
👉 多个微服务 = 几十/上百 G

2️⃣ 镜像层反复 build(CI/CD 或本地开发)

如果你经常:

docker build .

但:

  • 没清旧镜像
  • tag 每次变
  • 或使用 snapshot 依赖

👉 overlay2 会堆积大量 dangling layers(悬空层)


3️⃣ 容器写层(重点!)

即使你没有数据库:

Spring Cloud 服务可能会写:

  • 临时文件(/tmp)
  • 文件缓存(比如 Excel、PDF)
  • 上传文件没清理
  • Feign / WebClient 下载缓存

👉 这些都写在 container writable layer


4️⃣ Docker volumes / bind mount 没用好

如果你:

❌ 没把日志、缓存挂出去
👉 全写在 overlay2

正确应该:

-v /data/logs:/app/logs


5️⃣ 容器删除但 layer 没释放

Docker 有个坑:

👉 container 删了,但 layer 还在
👉 特别是:

  • 中断 build
  • 异常退出
  • overlay 引用没清理干净

二、为什么“删不掉”

你说的重点来了 👇

1️⃣ overlay2 不能手动删 ❌

路径:

/var/lib/docker/overlay2

👉 不能直接 rm
👉 否则 Docker 会坏掉


2️⃣ 有引用链(关键原因)

overlay2 的 layer:

👉 可能被:

  • container
  • image
  • build cache

引用

👉 所以你删文件没用

三、先确认是谁占空间

先跑:

docker system df

再细一点:

docker system df -v

重点看:

  • Images
  • Containers
  • Local Volumes
  • Build Cache

四、解决方案(按有效程度排序)

✅ 1. 一键清理(安全版)

docker system prune -a

👉 删除:

  • 停止的容器
  • 未使用镜像
  • dangling layers

如果想更狠一点:

docker system prune -a --volumes

⚠️ 会删 volume,小心数据

✅ 2. 限制日志大小(必须做)

/etc/docker/daemon.json

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

然后:

systemctl restart docker

👉 立刻止血


✅ 3. 清理 build cache

docker builder prune -a


✅ 4. 查最大容器日志

du -h /var/lib/docker/containers | sort -rh | head -20

找到最大的:

truncate -s 0 <logfile>


✅ 5. 正确挂载日志目录(推荐)

-v /data/logs:/app/logs

Spring Boot 配:

logging:
file:
name: /app/logs/app.log

五、总结一下紧急处理步骤

  • 立刻腾出空间
  • 暂不修改配置
  • 不影响正在运行的容器,也不用关闭需要运行的容器

✅ 1. 一键清理(安全版)

docker system prune -a

✅ 二、最安全:只清日志(不会影响运行)

查最大容器日志

du -h /var/lib/docker/containers | sort -rh | head -20

其中/var/lib/docker根据docker自身的配置(在/etc/docker/daemon.json中查看root配置)

结果如图:

看你这个输出,其实已经非常清晰了 👇

👉 真正占空间的只有两个容器:

5.8G c3824f1989eb...
324M f9a9e5039f7e...
269M 3da63a7cf708...

其他基本可以忽略。

执行👇

truncate -s 0 /data1/docker/containers/c3824f1989eb*/c3824f1989eb*-json.log

另外两个:

truncate -s 0 /data1/docker/containers/f9a9e5039f7e*/f9a9e5039f7e*-json.log
truncate -s 0 /data1/docker/containers/3da63a7cf708*/3da63a7cf708*-json.log

👉 效果:立刻释放几 GB
👉 服务完全不受影响


✅ 三、一键清理“无用容器”(推荐一起做)

docker container prune -f

👉 删除所有 stopped 容器(安全)


✅ 四、再清理镜像垃圾(很可能还有几十G)

docker image prune -a -f

更多推荐