Docker Overlay2 空间优化


目录


分析

overlay2 目录占用磁盘空间较大的原因通常与 Docker 容器和镜像的存储机制以及它们的长期累积相关,其实我之前在 Docker 原理那里已经提到过了。

通常时以下几种原因导致:

  • 大量的镜像和容器层

    每次运行一个 Docker 容器时,它都会从镜像中创建一个新的写层(之前提到的写时复制机制),这个层存储了容器运行时的所有文件修改。如果有很多容器运行或停止,但未被删除,overlay2 目录中的层(例如 diffmerged 目录)会占用大量空间。

    注意的是:每次启动或停止容器,Docker 会创建新的层,这些层没有被清理会长期占用空间,即使容器不再运行,其数据层依然占据磁盘空间。

  • 未删除的旧镜像

    Docker 会将所有拉取的镜像保存在本地,如果没有及时删除不再使用的镜像,这些镜像的层也会持续占用空间。因为每个 Docker 镜像都由多个层组成,每一层都会占用磁盘空间,且这些层存储在 overlay2 目录下。

  • 容器内文件的增多

    容器内的写操作(例如应用日志、临时文件等)都会写入 overlay2diff 层。如果某些容器产生了大量文件(例如日志文件、缓存等),这些文件会导致存储层膨胀。

  • 日志文件过大

    如果 Docker 容器产生了大量日志,特别是在没有对日志大小进行限制的情况下,日志文件会持续增长,占用大量空间。

  • 未清理的缓存和未使用的镜像层

    Docker 在构建镜像或运行容器时,会生成大量的缓存数据。这些数据在 overlay2 中存储,如果没有定期清理,长期累积会占用大量磁盘空间。

  • 挂载卷中的数据未清理

    容器运行时,挂载到容器中的数据卷可能存储了大量的数据,特别是当某些服务(如数据库、文件处理应用)生成大量数据时。

优化

数据路径规划

我们可在 Docker 配置文件中进行指定:

sh 复制代码
vim /etc/docker/daemon.json
sh 复制代码
{
    ...
    "data-root": "/data/docker",
    "log-driver": "json-file",
	...
}
sh 复制代码
systemctl daemon-reload
systemctl restart docker.service

配置后,重启 Docker 服务即可生效。

日志大小限制

有时,对于频繁产生大量日志的应用程序来说,如果你 Docker 服务没有对容器日志做限制,那必将会占用宿主机磁盘容量。

我们可在 Docker 配置文件中进行限制:

sh 复制代码
vim /etc/docker/daemon.json
sh 复制代码
{
    ...
    "log-opts": {
        "max-size": "60m",
        "max-file": "3"
    },
	...
}
sh 复制代码
systemctl daemon-reload
systemctl restart docker.service

配置后,重启 Docker 服务即可生效。

overlay2 大小限制

verlay2 是 Docker 默认的存储驱动之一,它将文件系统的多个层叠加在一起,并使用写时复制 (CoW) 来实现容器文件系统的管理。

查找 overlay2 目录中占用空间最多的文件:

sh 复制代码
du -sh /data/docker/overlay2/* | sort -h

这样可以通过 overlay2 ID 匹配对应的容器 ID,就可以找出产生大数据的容器,进行快速定位:

sh 复制代码
docker inspect --format='{{.GraphDriver.Data.MergedDir}} {{.ID}}' $(docker ps -aq)

此时就可以找出这个容器了:

sh 复制代码
docker ps

但要注意的是,overlay2 目录下的数据不能轻易手动删除,否则容器异常。虽然 overlay2 本身并没有直接的大小限制,但由于它依赖于底层文件系统(通常是 ext4xfs),存储大小的限制通常由底层文件系统决定。

可以通过 storage-opts 配置来限制每个容器的写层大小。这样可以防止容器无限制地增长,占用所有的磁盘空间。

sh 复制代码
{
    ...
    "storage-opts": [
        "overlay2.override_kernel_check=true",
        "overlay2.size=10G"
    ]
	...
}

这个配置会为每个容器的写层分配 10GB 的空间。当容器超过此限制时,会出现磁盘已满的错误。

注意,overlay2.size 仅在 Docker 使用 xfs 文件系统并启用 d_type 支持时有效。但是不建议通过此方法限制 overlay2 大小,而是部署服务前就应该做好了服务器磁盘容量规划,并实时监控服务器健康状态。

清理冗余数据

1、查看 docker 整体数据容量

sh 复制代码
du -sh /data/docker

2、查看镜像、容器、数据卷和构建缓存大小

sh 复制代码
docker system df

a. 可释放 15.63GB 未使用的容器镜像空间

sh 复制代码
docker image prune

如果想删除所有未使用的镜像(包括无标签的 dangling 镜像),可以使用:

sh 复制代码
docker image prune -a

b. 停止并删除未使用的容器

sh 复制代码
docker container prune

c. 清理未使用的网络

sh 复制代码
docker network prune

d. 清理系统缓存(移除未使用的网络、卷和构建缓存)

sh 复制代码
docker system prune -a

总结

一切的优化均基于理论+实践。

相关推荐
zyu674 小时前
03-Docker存储和网络
网络·docker·容器
牛奔5 小时前
Docker Compose 两种安装与使用方式详解(适用于 Docker 19.03 版本)
运维·docker·云原生·容器·eureka
青州从事52110 小时前
20260108【mac】【brew】【docker】安装
macos·docker·eureka
菜鸟思维12 小时前
优化NextJs 项目的Docker 镜像 从3.62G 优化到 296.85M
docker
怣疯knight12 小时前
Docker Desktop 4.55.0版本安装成功教程
windows·docker
东方佑13 小时前
使用Docker Compose一键部署OnlyOffice:完整指南与配置解析
运维·docker·容器
赵文宇(温玉)13 小时前
Docker的价值、特点、创新与关键技术
运维·docker·容器
Coder码匠15 小时前
Docker Compose 部署 Spring Boot 应用完全指南
spring boot·docker·容器
可爱又迷人的反派角色“yang”15 小时前
k8s(二)
linux·运维·docker·云原生·容器·kubernetes·云计算
计算机小手15 小时前
内网穿透系列十六:使用 wg-easy 快速搭建基于 wireguard 的虚拟局域网,支持Docker部署
经验分享·网络协议·docker·开源软件