— 问题 —
遇到过这样的错误吧:
No space left on device
然而当 df -H 的时候,又是这样:
# df -H Filesystem Size Used Avail Use% Mounted on udev 1.1G 4.1k 1.1G 1% /dev tmpfs 210M 758k 209M 1% /run /dev/xvda1 43G 18G 23G 45% /
明明还有那么多空间。。。当然,有经验的人肯定立刻就想到了:
# df -i Filesystem Inodes IUsed IFree IUse% Mounted on udev 253256 430 252826 1% /dev tmpfs 255939 473 255466 1% /run /dev/xvda1 2621440 2618687 2753 100% /
原来是 inode 耗尽了。
— 原因 —
Inode 全名 Index Node ,主要是用于保存文件大小、类型等文件系统对象(文件、目录)的元数据,它本身并不存储实际数据,一个文件或者文件夹都对应一个 inode 。
Inode 的总数和大小是在创建文件系统时候指定的,文件系统创建后就不能更改。所以在你创建了大量的文件、文件夹和链接( symlink )之后,你的 inode 资源就会越来越少了。
Inode 耗尽应该算是在 Docker 下使用 AUFS 常见的问题了。众所周知, AUFS 是 Docker 最先支持的存储驱动,具备速度快、节省存储空间、管理简单等优点,尽管 Linux 内核并不直接支持 AUFS ,但不妨碍很多 Ubuntu 用户直接使用 AUFS 。
但是我们也不能就这么简单地把锅甩给 AUFS ,还是要自己做好应用程序的监控和设计。
— 工具 —
这里介绍一个简单、方便的工具: inodes ( https://github.com/tripflex/inodes ) ,这个工具可以方便计算指定文件夹的inodes使用情况,你再也不必使用 find + for + df 这些网上流传的各种命令组合了。
安装非常简单,只需要下载二进制文件就可以了:
# wget -O /bin/inodes https://raw.smyl.es/inodes/master/inodes # chmod +x /bin/inodes
使用也简单,参数不多:
参数 | 示例 | 说明 |
---|---|---|
-d | inodes -d /path/to/dir | 可选。要查看的路径,默认使用当前目录。 |
-t | inodes -t 50000 | 可选。树形显示使用超过了50000个 inode 的目录。 |
-e | inodes -e 100 | 可选。过滤掉使用inode小于100个的目录。 |
这个应用执行后结果大概是这样的:
— 解决 —
首先找到inode到底都被哪些目录占用了,方法可采用上面介绍的工具,但是这个过程可能比较耗时,甚至几个小时。
删除没用的镜像:
# docker images -qf dangling=true | xargs docker rmi
删除没用的Volume:
# docker volume ls -qf dangling=true |xargs docker volume rm
再不行,备份数据,重新格式化或者加硬盘,在创建文件系统的时候,指定一个比较大的inode数,比如:
# mkfs -t ext4 -N
或者干脆换不使用 inode 的文件系统,比如 btrfs 或 DeviceMapper 。
— 建议 —
关于如何使用 Docker + AUFS ,官方有一份详细的说明 ( https://docs.docker.com/engine/userguide/storagedriver/aufs-driver/ ),大家可以参考下。其中说道了 Volume ,由于 Volume 略过了存储驱动,所以就省去了一些必要的初始化设置工作和 CoW ,所以重 IO 的数据都推荐使用 Volume 。
这里其实有一个问题, 如果 Docker 镜像中定义了 Volume ,而启动的时候又没有通过 -v 选项为定义的 Volume 指定绑定的 HOST 路径,那么 Docker 就会自动在
/var/lib/docker/volumes/ 文件夹下面创建一个 Volume 供新启动的容器使用。
坑爹的地方在于,如果你通过 docker rm 命令删除这个容器的时候, Docker 默认是不会删除这些默认创建的 Volume 的。
那么这里大叔就给大家一些建议:
- 有一说一,没用的 Volume 别写到 Dockerfile 里去
- 写到了 Dockerfile ,就尽量为其指定宿主机路径
- 删除的时候使用 -v 选项
评论前必须登录!
注册