Docker cp 提示“no space left on device”

Docker cp 提示“no space left on device”

作者:张首富
时间:2021-05-24
w x:y18163201

前言

此篇文章记录的并不是 磁盘空间不足

问题描述

今天在测试一个功能,需要频繁的替换一个 docker 容器内的一个文件,因为还处在测试阶段,所以我就没有频繁的构建 docker 镜像了;在前几次执行docker cp命令的时候都能正常的操作。突然再次执行 docker cp命令时提示如下报错:

# docker cp mod_shine.so  fsagent:/usr/local/freeswitch/mod/mod_shine.so 
Error response from daemon: mount /data:/data/dockerd/overlay2/63a84fe2d10722bf0cc7cc56537f889eb1f84840bb1c3f8ce8e0272bf55903b7/merged/home, flags: 0x5000: no space left on device

不想看下面直接出解决方案

临时解决

更改下面的 centos 默认挂载磁盘的个数

echo "1000000" >  /proc/sys/fs/mount-max 

然后就可以继续docker cp ;永久解决还需要看下面的问题分析

解决问题思路

以为是宿主机没有磁盘空间了

df -Th               #查看磁盘空间,发现还有空间
df -i                #查看是否 inode 耗尽发现未耗尽
lsof | grep deleted  #查看是否有删除的大文件没有释放,发现并没有

然后通过上面的操作时候确定这个问题不是因为磁盘满或者 inode 耗尽造成的问题,这个时候就有点懵圈了。

仔细分析报错

仔细查看刚才的报错信息,发现是 mount挂载的时候报错没有空间,猜想:

1,centos 挂载磁盘数量有没有限制?

2,如果有应该如何查看当前挂载了多少?

3,系统默认最多能挂载多少呢?

带着这些疑问和上面的报错信息开始 google,然后在 github 上发现了一个给我相识的问题,https://github.com/moby/moby/pull/38993

问题复现

按照 github 上面的操作复现了这个现象

$ docker run --name mm -d -v /:/rootfs busybox sleep 3d
73b50c2e626ad9378f429b20ba77355cf815bc9f846f19c173a0e62f57224ad3
$ docker exec mm wc -l /proc/self/mountinfo
86 /proc/self/mountinfo
$ docker cp mm:/etc/group /dev/null
$ docker exec mm wc -l /proc/self/mountinfo
185 /proc/self/mountinfo
$ docker cp mm:/etc/group /dev/null
$ docker cp mm:/etc/group /dev/null
$ docker cp mm:/etc/group /dev/null
$ docker cp mm:/etc/group /dev/null
$ docker cp mm:/etc/group /dev/null
$ docker exec mm wc -l /proc/self/mountinfo
6323 /proc/self/mountinfo
$ docker cp mm:/etc/group /dev/null
$ docker cp mm:/etc/group /dev/null
$ docker cp mm:/etc/group /dev/null
Error response from daemon: mount /:/var/lib/docker/overlay2/c9dbd9463b6c972fa712132d3177cfc19c808ed3e0dcd9a208f7ad487ad40a40/merged/rootfs, flags: 0x5000: no space left on device
$ docker exec mm wc -l /proc/self/mountinfo
50675 /proc/self/mountinfo

问题能复现就能找到具体原因。

分析原因

1, 看这个情况就是挂载的数量达到 centos 系统默认值的上限了;默认值上线是多少呢?

# cat /proc/sys/fs/mount-max
100000

2, 为什么上图显示才有 50675 的时候在挂载都显示挂载满了呢?

我们可以观察下每次复制都是成倍的增长的。所以我们虽然挂载数量还没达到默认值,但是他不足以支撑下次的挂载了,所以报错了。

3,测试挂载别的目录会不会有这个情况?

我 docker 的家目录在/home/docker目录下,这点需要注意。

$ docker run --name mm -d -v /data:/data busybox sleep 3d               #无上述现象发生
$ docker run --name mm -d -v /tmp:/tmp busybox sleep 3d         #无上述现象发生
$ docker run --name mm -d -v /home:/home busybox sleep 3d               #上述现象发生

通过这样大量的测试,我发现了,只有在 docker 家目录被挂载到docker 里面之后 docker cp才会有上述情况,会看出问题的 docker 容器 确实如此。

到此问题找到得以解决

总结

这就是 docker 挂载使用不规范造成的隐藏性的 bug,立即制定 docker 使用规范记录发放到研发人员。以免在造成此类问题发生。

上一篇:文件管理基础命令之二


下一篇:Linux之cp命令