Docker overlay2占满VPS磁盘,哪些能清、哪些不能直接删?

镜像层、可写层、日志、构建缓存和数据卷要分开处置
发布于
10

VPS根分区告警后,很多人会发现/var/lib/docker/overlay2占了大量空间,于是准备按目录大小直接删除。这里最危险的误区是:把overlay2当成普通缓存目录。

不要直接删除/var/lib/docker/overlay2里的子目录。这些目录可能对应镜像只读层、正在运行容器的可写层或挂载关系。绕过Docker元数据删除,可能导致容器无法启动、镜像损坏,甚至让占用关系更难恢复。

先确认Docker数据根目录和文件系统

/var/lib/docker是常见默认路径,但实际环境可能修改了data-root,也可能把Docker放在独立磁盘。先只读确认:

docker info --format '{{.DockerRootDir}}'
df -h
df -i
docker system df
docker system df -v

df -h看容量,df -i看inode。大量镜像小文件、构建产物或日志可能同时造成容量或inode压力。只有先锁定真正已满的挂载点,后续清理才不会在错误磁盘上忙一圈。

overlay2里面主要是什么

使用OverlayFS存储驱动时,Docker会组合镜像的只读层与容器的可写层,让容器看到完整文件系统。多个镜像和容器还可能共享底层内容,因此目录大小与“某个容器独占多少空间”并非简单一一对应。

空间来源 典型表现 正确入口
镜像层 多版本镜像、悬空镜像、旧发布残留 docker image ls与镜像引用关系
容器可写层 应用把上传、缓存或数据库写进容器内部 docker ps -a --size与应用路径
Build Cache 频繁构建、重复拉依赖、长期未清理 docker builder du或版本支持的构建缓存视图
容器日志 json-file日志持续增长 日志驱动配置与容器日志路径
数据卷 数据库、上传文件、业务持久化数据 docker volume ls/inspect和备份策略

数据卷通常不属于overlay2可写层,但会共同占用Docker数据根目录所在文件系统。磁盘告警时必须一起盘点,不能只盯着一个目录名。

第一类:停止容器和旧镜像可以定向处理

docker ps -a
docker image ls --digests
docker ps -a --size
docker system df -v

先确认哪些容器仍属于当前编排、哪些镜像是回滚版本、哪些容器只是一次性任务。删除应面向明确对象,先停用、验证无依赖,再用Docker命令移除。

不要在生产VPS上直接把docker system prune -a --volumes当成“通用清理命令”。其中-a会扩大镜像清理范围,--volumes可能触及未被当前容器引用但仍有业务价值的数据。自动化清理前还要考虑灰度、回滚和临时停止的项目。

第二类:Build Cache要看近期构建和回滚需求

在同一台VPS反复执行镜像构建,缓存会持续积累。先使用当前Docker或BuildKit版本支持的命令查看缓存,再按时间、项目和可重建性定向处理。清理缓存通常不会删除正在运行容器,但会让下一次构建重新下载或计算依赖,增加构建时间与网络流量。

更根本的做法是优化Dockerfile层顺序、缩小构建上下文、配置.dockerignore,并把持续集成构建与生产运行环境适当分离。

第三类:容器可写层变大,说明数据写错了位置

如果docker ps -a --size显示某个容器可写层异常增长,应进入应用层确认来源,常见的是:

  • 上传文件没有挂到持久化卷;
  • 缓存、转码文件或临时下载留在容器内;
  • 应用日志写入容器文件,同时又被日志驱动收集;
  • 数据库数据目录没有正确挂卷;
  • 调试模式生成大量转储或跟踪文件。

先备份并验证数据含义,再修改挂载和应用路径,通常需要重新创建容器。不要直接从宿主机进入overlay2目录删除所谓“大文件”,因为你可能绕过应用一致性、权限和容器挂载视图。

第四类:json-file日志不在overlay2,也能把同一磁盘写满

Docker默认日志驱动在不少环境中是json-file。容器不断输出异常堆栈或访问日志时,日志文件可能快速增长。先查看单个容器使用的日志驱动和路径:

docker inspect --format '{{.HostConfig.LogConfig.Type}} {{.LogPath}}' 容器名

可以在Docker守护进程配置中为新建容器设置日志限额,示意配置如下:

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

数值应按业务日志量和审计保留需求确定,配置语法也要用当前版本文档校验。守护进程的默认日志配置通常只应用于之后新建的容器,已有容器需要在验证配置、备份和可用性后重新创建。日志限额只控制磁盘增长,异常刷日志的根因仍要修复。

如果轮转配置存在但日志仍增长,可参考极跃圈的VPS日志轮转不生效排查

第五类:未被引用的数据卷不能等同于垃圾

docker volume ls
docker volume inspect 卷名

一个卷没有被当前运行容器挂载,可能是旧数据库,也可能是等待回滚、迁移或临时停机的项目。删除前至少确认卷创建来源、Compose项目、最近使用时间、数据类型和可恢复备份。

数据库卷尤其不能通过宿主机直接挑文件删除。应使用数据库自身的归档、清理和备份机制,验证恢复后再处理旧卷。

清理后df空间没有下降怎么办

Docker对象减少但df没有明显变化,可能存在已删除但仍被进程打开的日志、挂载边界、快照或其他目录占用。可先重新运行docker system dfdf -h,再检查打开的已删文件:

sudo lsof +L1

这类dfdu不一致问题,可继续按极跃圈的VPS磁盘隐藏占用排查顺序定位。不要因为一次清理没有立即下降,就转而手工删除overlay2目录。

磁盘接近100%时的处置顺序

  1. 暂停会持续生成镜像、缓存或日志的非关键任务;
  2. 记录Docker根目录、挂载点、inode和各类对象占用;
  3. 优先处理明确可再生成的构建缓存与已确认无引用对象;
  4. 为异常日志止损,并保留必要的故障证据;
  5. 迁移写入容器层的业务数据,重新创建容器验证;
  6. 对数据卷先备份和恢复演练,再删除旧副本;
  7. 空间仍不足时,按存储结构迁移Docker根目录或扩容文件系统。

紧急释放空间也应一次只处理一类对象,每一步复查关键容器、磁盘余量和错误日志。批量删除速度快,但恢复错误对象往往更慢。

如何防止overlay2再次失控

  • 为磁盘容量、inode、日志增长和Docker对象占用设置提前告警;
  • 生产容器把持久化数据放入明确命名的卷或外部存储;
  • 为容器日志设置合理限额,并监控异常输出速率;
  • 保留有限且明确的回滚镜像,不无限积累每次构建;
  • 定期审计停止容器、旧镜像、Build Cache和孤立卷;
  • 把清理规则写成有白名单、时间窗口和恢复验证的流程。

结论

Docker overlay2占满VPS磁盘时,正确做法不是进入目录手工删除,而是通过Docker对象关系判断镜像层、容器可写层、构建缓存、日志和数据卷各自的来源。先只读盘点,再定向清理;业务数据先备份,日志和构建策略随后补齐,才能避免空间释放后又迅速涨满。

常见问题(FAQ)

可以直接删除overlay2里的大目录吗?
不可以。目录可能对应镜像层或运行容器的可写层,手工删除会绕过Docker元数据,可能导致容器和镜像损坏。
docker system prune -a --volumes能一键解决吗?
风险较高。它会扩大镜像清理范围并可能触及未被当前容器引用但仍有价值的数据卷,生产环境应先核对引用、回滚和备份。
为什么清理Docker后df空间没有下降?
可能有已删未释放日志、挂载边界、快照或其他目录占用。应复查docker system df、df并用lsof检查仍被进程打开的已删文件。
如何防止overlay2再次占满磁盘?
应把持久化数据挂卷,限制容器日志,审计旧镜像和构建缓存,并为磁盘容量、inode和增长速度设置提前告警。

本文由作者原创/授权发布于极跃圈(jiyueip.com)未经许可,禁止转载。题图来自Unsplash,基于CC0协议。

声明:极跃圈(JIYUEIP.com)内网友所发表的所有内容及言论仅代表其本人,并不反映任何极跃圈(JIYUEIP.com)之意见及观点。

0 讨论
热门最新
总结
暂无总结
0 / 600

VPS磁盘满了最常见的表现:网站打不开(MySQL写不进去)、Docker容器启动失败(没空间写日志)、SSH登录巨慢。本文用du和ncdu两个命令找到谁在吃空间,再针对Docker日志、系统日志和旧备份三类大户下手清理。 第一步:确认磁盘