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 使用規范記錄發放到研發人員。以免在造成此類問題發生。
