docker overlay2占用大量磁盘空间问题排查汇总

Docker容器硬盘空间占用问题排查

docker用久了以后有较大概率遇到这个问题,表现就是/var/lib/docker/overlay2下占用90%以上的硬盘空间(下图是别的帖子的,我就懒得自己截图了,就做个问题示意图而已)。
在这里插入图片描述

一、检查是否有多余的容器和镜像

可以通过命令检查:

// 查看所有容器
docker ps -a
//查看所有镜像
docker images
//删除容器
docker rm 容器id或容器名称
//删除镜像
docker rmi 镜像id
//查看docker内部的硬盘使用情况
docker system df

或者一步到位

//清理磁盘,删除关闭的容器、无用的数据卷和网络,以及dangling镜像(即无tag的镜像)
docker system prune
//清理更干净、彻底,可以将没有容器使用的Docker镜像都删掉。
docker system prune -a

二、清除容器日志

运行时间较长(1年以上)容器日志文件会堆积较多,占用大量硬盘,网上有的帖子就是这种情况,主要清除/var/lib/docker下的日志文件,清除脚本如下:

echo "======== start clean docker containers logs ========"
logs=$(find /var/lib/docker/containers/ -name *-json.log) #containers下没有的话可以往上一级
for log in $logs
        do
                echo "clean logs : $log"
                cat /dev/null > $log
        done
echo "========
<think>我们已知overlay2目录存储了Docker容器的层数据,当该目录占用过大时,我们需要找出是哪个容器导致的。 根据引用[2]和引用[3]提供的方法,我们可以通过以下步骤来查找: 步骤1:进入overlay2目录 通常,overlay2目录位于`/var/lib/docker/overlay2`,我们可以进入该目录。 步骤2:使用磁盘使用分析命令 在该目录下,我们可以使用`du`命令来查看每个子目录的大小,并排序,从而找出占用空间最大的目录。 步骤3:将目录名与容器关联 每个容器的层数据存储在overlay2目录下的子目录中,但子目录名并不直接对应容器名。因此,我们需要通过目录名来查找对应的容器。 具体操作如下: 1. 首先,使用以下命令查看overlay2下各个目录的大小,并按大小逆序排序: ```bash cd /var/lib/docker/overlay2 du -sh * | sort -rh | head -n 20 ``` 这样我们可以列出最大的20个目录(具体数量可根据需要调整)。 2. 找到占用空间最大的目录后,我们需要知道这个目录对应哪个容器。每个容器的元数据中会记录其使用的层(即overlay2下的目录)。我们可以通过以下命令来查找: ```bash docker ps -a --no-trunc | grep <目录名> ``` 但是,由于容器元数据中存储的是完整的层ID,而我们在overlay2目录下看到的可能是缩略形式(因为目录名是64位ID的前面一部分,但有时也会是完整的),所以我们可以尝试用目录名去匹配。 3. 另一种更直接的方法(如引用[2]和引用[3]所述)是使用`docker inspect`命令来查找容器使用的层ID,然后与overlay2中的目录匹配。但这样比较麻烦。 4. 实际上,我们可以通过一个脚本或命令来遍历所有容器,然后获取每个容器使用的层ID(即`GraphDriver`数据中的`MergedDir`或`UpperDir`所在的目录),然后与overlay2中的目录进行匹配。 但是,有一个更简单的方法:在overlay2目录中,每个容器的层目录通常会有一个对应的`link`文件(以`l`开头的文件),该文件内容指向一个长ID的目录,并且这个`link`文件的名称就是容器层在`/var/lib/docker/image/overlay2/layerdb/sha256`下的子目录名的一部分,进而关联到容器。不过这个方法较为复杂。 5. 实际上,我们可以通过以下命令,将每个容器与其使用的overlay2目录关联起来: ```bash docker ps -qa | xargs docker inspect --format '{{.Id}} {{.GraphDriver.Data.MergedDir}}' | grep overlay2 ``` 这个命令会输出每个容器的ID和其对应的overlay2目录(即MergedDir)。然后我们可以将上一步中占用大的目录与这里输出的目录进行匹配,从而确定是哪个容器。 6. 但是,由于MergedDir的路径是完整的,我们可以直接根据路径名来匹配。例如,如果我们在`du`命令中看到`/var/lib/docker/overlay2/abcd...`占用很大,那么我们在上面的输出中查找包含`abcd...`的路径,该路径对应的容器ID就是我们要找的容器。 7. 然后,我们可以通过容器ID来获取容器的名称: ```bash docker ps -a --no-trunc | grep <容器ID> ``` 步骤4:清理(可选) 一旦找到占用过大的容器,我们可以根据情况决定是否停止并删除该容器,或者清理容器内的日志等(注意:容器内的日志默认也存储在overlay2中,但通常不建议直接删除overlay2中的文件,而应该通过容器管理命令来处理)。 另外,引用[1]提到容器日志文件过大也是一个原因,我们可以通过设置日志大小限制来避免。引用[4]提到迁移Docker数据目录的方法,如果磁盘空间不足,可以考虑迁移。 因此,总结步骤如下: 1. 进入overlay2目录,找出占用空间最大的目录。 2. 获取所有容器的层目录(MergedDir),并与第一步的目录匹配,找到容器ID。 3. 根据容器ID找到容器名称。 下面是一个具体的例子: 假设在overlay2目录下,我们发现`abcd1234...`目录占用很大,然后执行: ```bash docker ps -qa | xargs docker inspect --format '{{.Id}} {{.GraphDriver.Data.MergedDir}}' | grep abcd1234 ``` 如果输出类似: `d3c4b5... /var/lib/docker/overlay2/abcd1234.../merged` 那么容器ID就是`d3c4b5...`,然后我们可以用`docker ps -a | grep d3c4b5`查看容器名。 注意:如果容器数量很多,以上命令可能会较长,我们可以使用循环来逐个检查。 另外,也可以使用以下命令一次性列出所有容器及其对应的overlay2目录(MergedDir)的大小(但需要计算每个容器层目录的大小): ```bash docker ps -qa | xargs -I {} sh -c 'echo {}; docker inspect --format "{{.GraphDriver.Data.MergedDir}}" {} | xargs du -sh' ``` 这个命令会列出每个容器ID和其MergedDir目录的大小。但是,由于MergedDir目录实际上是overlay2下的某个目录的`merged`子目录,而实际数据存储在其上一层(即overlay2下的目录本身),所以直接计算MergedDir的大小可能不准确,因为`merged`是一个挂载点,我们更应该计算其上层目录(即overlay2下的目录)的大小。因此,我们更推荐第一种方法。 因此,我们回到第一种方法:先找出overlay2下的大目录,再匹配容器。 另外,还有一种工具:`docker system df`可以查看Docker磁盘使用情况,`docker system df -v`可以查看每个容器的磁盘使用,但注意这个命令显示的是容器读写层的大小,而overlay2目录中包含了只读层和读写层,所以可能不完全对应。所以,我们仍然推荐直接分析overlay2目录。 综上所述,我们给出如下操作步骤: ### 操作步骤 1. **确定overlay2目录位置**:通常为`/var/lib/docker/overlay2`,如果不在该位置,可以通过`docker info | grep "Docker Root Dir"`查看。 2. **列出overlay2目录下各子目录的大小**: ```bash sudo du -sh /var/lib/docker/overlay2/* | sort -rh | head -n 20 ``` 3. **记录占用空间最大的目录名**(例如:`abcd1234...`)。 4. **获取所有容器的层目录信息**: ```bash docker ps -qa | xargs docker inspect --format '{{.Id}} {{.GraphDriver.Data.MergedDir}}' ``` 或者,为了更精确,我们可以使用容器名和容器ID一起输出: ```bash docker ps -qa | xargs docker inspect --format '容器ID: {{.Id}}, 容器名: {{.Name}}, MergedDir: {{.GraphDriver.Data.MergedDir}}' ``` 5. **在输出中查找包含步骤3中目录名的行**,因为MergedDir的路径通常类似于`/var/lib/docker/overlay2/abcd1234.../merged`,所以会包含`abcd1234...`。 6. **找到对应的容器ID和容器名**。 7. **确认后,可以针对该容器进行清理或调整**。 另外,如果容器已经停止,那么`docker ps -a`可以显示所有容器(包括已停止的),所以上述命令会包括已停止的容器。 如果上述方法没有找到对应的容器(可能是因为容器被删除了,但数据还未清理),那么可能是残留的数据,我们可以使用`docker system prune`来清理未使用的数据(注意:这会删除所有未使用的容器、网络、镜像等数据,谨慎使用)。 另外,引用[4]提到迁移数据目录的方法,如果磁盘空间不足,可以考虑迁移。 最后,关于容器日志过大的问题,我们可以通过设置日志大小限制来防止单个容器日志过大: ```bash # 在运行容器时设置 docker run --log-opt max-size=10m --log-opt max-file=3 ... # 或者全局设置,修改/etc/docker/daemon.json,添加: { "log-driver": "json-file", "log-opts": { "max-size": "10m", "max-file": "3" } } ``` 然后重启docker服务。 希望这些步骤能帮助你找到导致overlay2目录占用过大的容器。 §§相关问题§§ 1. 如何限制Docker容器的日志大小? 2. 如何清理Docker占用磁盘空间(包括镜像、容器、网络等)? 3. 如何迁移Docker的数据目录到新的位置?</think>### 排查Docker overlay2目录占用过大的具体容器 以下是逐步排查的具体方法,通过分析overlay2目录与容器关联性定位问题容器: --- #### **步骤1:进入overlay2目录** ```bash cd /var/lib/docker/overlay2 # Docker默认存储路径 ``` --- #### **步骤2:扫描占用空间最大的子目录** ```bash sudo du -sh * | sort -rh | head -n 20 ``` - **作用**:列出overlay2下所有子目录的大小,按降序排列,显示前20个最大目录 - **输出示例**: ```bash 4.8G 2f8d4e5d3c1a0b... # 此哈希串即容器层ID 3.2G 7a3b9c0d8e2f1a... 1.1G l/5RYXKZQO3X... # "l/"开头的软链接目录 ``` --- #### **步骤3:关联目录与容器ID** 通过目录名反查容器名称和ID: ```bash # 遍历所有容器,匹配层ID docker ps -a --no-trunc | grep <目录名> # 精确匹配容器(推荐) docker inspect $(docker ps -aq) --format \ '{{.Id}} {{.Name}} {{index .GraphDriver.Data "MergedDir"}}' | grep <目录名> ``` - **示例**: ```bash docker inspect $(docker ps -aq) --format \ '{{.Id}} {{.Name}} {{index .GraphDriver.Data "MergedDir"}}' | grep 2f8d4e5d3c1a0b ``` - **输出**: ```bash d3b9d1a8c7f2 /nginx /var/lib/docker/overlay2/2f8d4e5d3c1a0b.../merged ``` > 此处`d3b9d1a8c7f2`是容器ID,`/nginx`是容器名[^2][^3] --- #### **步骤4:验证容器状态** ```bash docker ps -a | grep d3b9d1a8c7f2 # 检查容器运行状态 docker logs d3b9d1a8c7f2 # 查看日志是否异常增长 ``` --- #### **步骤5:清理已停止容器的残留数据** 若容器已删除但数据未清理: ```bash docker system prune -af # 清理所有未使用的镜像/容器/网络 ``` --- ### 关键说明 1. **目录名与容器关系**: - `overlay2/{hash}`:容器读写层(实际数据存储位置) - `overlay2/l/{link}`:符号链接指向层目录(短ID) 2. **常见原因**: - 容器持续写入日志未轮替(检查`/var/lib/docker/containers/<容器ID>/*.log`) - 容器内应用生成大量临时文件 - 容器删除后未清理层数据[^1][^4] --- ### 预防措施 - **日志限制**:在`/etc/docker/daemon.json`添加: ```json { "log-driver": "json-file", "log-opts": {"max-size": "10m", "max-file": "3"} } ``` - **定期清理**: ```bash docker system df # 查看磁盘使用 docker system prune # 手动清理 ``` - **数据目录迁移**:若默认磁盘空间不足,迁移Docker根目录[^4]
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值