Docker:Docker删除upper目录下文件再创建,其与merged目录文件iNode不一致(验证中……)

发布时间 2023-07-16 19:39:55作者: 钢板意志

问题描述

磁盘空间不足,经排查发现是docker下的overlay目录下一个服务的容器层(存在于merged和upper)的日志文件占用空间过大。

操作

1、尝试docker的清理磁盘命令

一开始使用命令docker system prune清理磁盘,该命令用于删除关闭的容器、无用的数据卷和网络,以及dangling镜像(即无tag的镜像)。

日志文件没有被清除。

2、尝试直接删除merged目录下文件

因为该目录为读写层,所以打算直接删除该文件,首先尝试直接删除merged目录中的日志文件,发现删除无效,依旧存在。
merged为联合挂载容器层和镜像层产生的容器视图,所以修改该目录,docker容器内部也会修改。

3、尝试删除upper目录下文件

第二次尝试删除upper目录中的日志文件,

是这样考虑的,由于merged目录是upper和lower的联合展示,那么删除upper下的文件,merged也会对应删除(反之亦然)。

却发现upper下文件删除了,但是merged还有。再次删除merged下的日志文件,报错
rm: cannot remove ‘wrapper.log’: Stale file handle

过时的文件句柄,说明此时inode指向的block是空的或者存在问题。

4、排查中看到有说与文件系统有关

查询过程中,有看到,CentOS7默认文件系统xfs,与docker的overlay/overlay2存储驱动不匹配,导致容器内删除文件无效。

①重新格式化xfs文件系统,修改参数ftype=1、
②可将centos文件系统格式化为ext4、
③修改docker存储驱动为老的devicemapper、
④宿主机删除(我们的操作就是宿主机删除)(overlay/overlay2的文件系统是OverlayFS,为上层文件系统,主流底层文件系统为ext4和xfs)

网上的解决方案,使用fsck -a <设备号>命令,自动检查修复文件系统。(尽量别用,对于公司的生产环境影响过大),尝试之后并没有效果。

5、临时解决,重新创建容器

最后我们的解决方案是删除了容器,重新创建的容器

6、探究问题原因

问题根本原因是什么?

之后又尝试直接删除merged目录下的文件,此时未删除upper目录下文件,发现没有问题,能够删除,不过一会又会创建出来,文件inode值没变,只是权限变了。

复现操作删除upper下文件,发现merged下日志文件依旧存在,且进行删除操作还是报错过时的文件句柄!!

继续探究

尝试硬链接merged下的日志文件到upper。报错 Invalid cross-device link!!

跨文件系统了。

疑惑

后来又看到网上的一些解决方案,联想到自己目前的问题

我要删除的是日志文件,在我进行删除操作时,它对应的docker容器是开启的,也就是说日志文件正在被写入。

rm操作时将该文件从文件结构上解除连接,但是存储空间依旧存在。

外部宿主机merged删除日志文件后,内部容器又将日志文件恢复了,此时的外部文件是容器内创建的,也就是overlay文件驱动。
但是我的宿主机文件系统是xfs,此时造成了文件系统不一致?

排查是否设置ftype,使用命令xfs_info /,ftype=1 是开启的。说明宿主机可以适配overlayFS文件系统的文件。

底层文件系统是内核的一部分。

继续测试

(验证一下上述疑惑,手动创建文件,发现同样存在该问题,那么就不是上述疑惑了。)
目前有点懵,继续测试在docker容器中创建文件,外部删除会不会有这个情况?

测试中发现一件事情,如果容器创建时有挂载外部卷,那么merged里的文件和容器内的就不是一个inode了,容器内文件和挂载卷文件是一个inode。(merged没有了,出现在宿主机挂载位置)

还会有疑惑Docker的写时复制的影响?

测试容器内创建文件,upper删除造成的影响

容器内创建test文件(inode:1319259),宿主机upper目录删除对应出现的test文件,发现并无影响,对应的merged和容器内都会删除。

再尝试容器创建test文件,命令执行完没有反应?cat test,输出为空,也就是说看不到test文件,但是容器内还存在!!

尝试在upper创建test文件,创建成功但是inode变了(inode:1320457),再去看容器和merged,也出现的test文件,但是inode还是之前那个inode(inode:1319259)

疑惑,文件系统的问题?

然后使用df -Th查看文件系统类型,发现merged文件系统是overlay,upper是xfs,难道说还是因为类型匹配有问题?

又测试了几个文件系统分别为overlay与xfs的容器,发现都有这个问题!!

是ftype=1这个参数 还是不能很好的适配overlay和xfs吗?

测试ext4(extfs)与overlay2 不存在该问题

换几台服务器,验证一下,是不是和文件系统有关

经测试宿主机文件系统为xfs,docker文件驱动为overlay2,也是存在这个问题。
同样使用df -Th 查看文件系统类型,upper目录是xfs,merged是overlay。

测试结果

测试1
容器内创建文件,
1、merged和容器内删除无影响,
2、upper删除会导致 merged和容器内无法创建,
且upper再次创建同名文件,upper中inode变了(也是新的文件,文件内容是空的),但是merged和容器内还是之前的inode(文件内容也还是之前的),
删除merged下该文件报错无效的文件句柄。

测试2
upper中创建文件,发现存在上述同样的问题。

时隔一段时间后的测试

后来测试一个容器发现没有这个问题,同样的机器为什么会有不同的表现?

创建容器时,如果设置 --privileged=true 的容器删除就没有影响,否则会出现上述问题。这个问题同样存在于 ext4/overlay 的服务器中。

但是事情变得越发奇怪了,
重启容器之后,在 ext4/overlay 的服务器能够删除 merged 目录下的文件。但是 xfs/overlay 还是报错无效的文件句柄。

ext4 如果是通过 -v 挂载出来的,什么问题都没有,因为df -Th都是 ext4。

参考博客:

基于XFS文件系统的OverlayFS

linux删除文件后没有释放空间

Docker容器内文件无法删除