赞
踩
一周内测试服务器出现了3次问题。每次都是redis报错,RDB日志无法写入,设备上没有空间。测试服务器像往常一样更新项目代码并发布。测试服使用docker 去编译和发布项目的环境和项目本身。但是在准备运行 docker 进行项目更新时,却提示异常,内容如下:
$ docker-compose -f xxx.yml up -d --build
[249520] INTERNAL ERROR: cannot create temporary directory!
提示:INTERNAL ERROR: cannot create temporary directory!
“不能创建临时的文件夹”?
不应该啊,什么都没动。这时就赶紧查看下服务器的磁盘使用情况
# 查看系统的磁盘容量使用情况
$ df -h
文件系统 容量 已用 可用 已用% 挂载点
...
/dev/nvme0n1p2 468G 128G 317G 29% /
overlay 468G 128G 317G 29% /data/docker/overlay2/xxxx/merged
overlay 468G 128G 317G 29% /data/docker/overlay2/xxxx/merged
...内容同上
PS: 我这里修改了docker目录到 /data/docker
,你们的可能在 /var/lib/docker
这个情自行替换命令中的目录地址。
发现磁盘还有很多的使用空间,那为什么不能创建临时文件呢?于是手动去创建一个空文件试试。结果也是失败。于是又想起来查看下索引节点的使用情况。
# 查看系统的索引节点使用情况
$ df -i
文件系统 Inodes 已用(I) 可用(I) 已用(I)% 挂载点
...
/dev/nvme0n1p2 31227904 31227904 0 100% /
overlay 31227904 31227904 0 100% /data/docker/overlay2/xxxx/merged
overlay 31227904 31227904 0 100% /data/docker/overlay2/xxxx/merged
...内容同上
好家伙,3千万个节点索引全部使用完毕。那么可以排除是其它服务的问题,这个问题就产生在docker的目录上。
这时上网搜,有的说得重启docker,转移目录。有的就是说清理对应文件就行了,一带而过。我觉得自行的随意删除文件,在不了解系统和docker 的情况下,很容易导致镜像或者docker出现问题。
我个人倾向于先保守,再激进。在不停用先有的容器下,先执行下docker自带的清理命令吧 docker system prune
。它会帮我们将停止运行的容器,和关联的网络,和 悬空镜像等一些内容清理掉。
PS:docker system prune
还支持一些扩展参数,可以支持清理运行中的容器,所有的镜像等。这里我不想清理镜像,并且所有服务的容器我都没有停止,保证不会误删内容。
# 清理命令
$ docker system prune
WARNING! This will remove:
- all stopped containers
- all networks not used by at least one container
- all dangling images
- all dangling build cache
Are you sure you want to continue? [y/N] y
Deleted Containers:
70dac77db2c98ca3606f54b993f12660bde3cb6effd54a526b51696be64ec92c
Total reclaimed space: 0B
清理之后删除了一些无用的容器,回收空间没有。在查看索引的使用还是百分百。
鉴于docker中的镜像配置一直都没有改过,而且之前部署的一直没有出现问题。那么应该就是某个正在运行的容器出现异常,导致碎文件过多,把索引节点全部使用没了。
基本能确定是docker 某个或某些容器产生的问题,与其一顿乱删,乱怀疑。不如就先找到是哪个目录下产生了那么多的文件。这里我使用了几个命令(来源自网友):
du -h /data/docker/overlay2 --max-depth=1
只查看 overlay2
下一层文件夹的空间占用大小
# 先看下docker 目录下这些镜像和容器产生的目录有没有异常大小的
$ sudo du -h /data/docker/overlay2 --max-depth=1
40K /data/docker/overlay2/aaa-init
24K /data/docker/overlay2/aaa
12M /data/docker/overlay2/bbb
40K /data/docker/overlay2/bbb-init
36K /data/docker/overlay2/ccc
...
# 最大的不过几百兆。没有问题,都是在正常的使用范围内。
for i in /data/docker/overlay/2*; do echo $i; find $i | wc -l; done
去循环查找制定目录下的所有文件,统计文件个数返回。 如果需要root权限,可以向下面的写法。
$ sudo -- bash -c 'for i in /data/docker/overlay2/*; do echo $i; find $i | wc -l; done' /data/docker/overlay2/xxx 9 /data/docker/overlay2/aaa 60499422 /data/docker/overlay2/aaa-init 18 ... $ sudo -- bash -c 'for i in /data/docker/overlay2/aaa/*; do echo $i; find $i | wc -l; done' ./diff 30235375 ./link 1 ./lower 1 ./merged 30264042 ./work 2
然后我们就发现了,目录是 aaa 的这个文件夹下,文件居然有6千万个!进入后再次统计,嗯就是这个目录没跑了。
那么现在我们的根源目录找到了,现在只需要知道它是那个容器产生的就行了。docker 高版本以后,这个挂载的目录名称就和容器的id区分开了,所以这两个不能直接进行关联。
于是我又找到了一个命令。
# 查看 overlay2/ 下文件夹对应的容器信息
$ docker ps -q | xargs docker inspect --format '{{.State.Pid}}, {{.Id}}, {{.Name}}, {{.GraphDriver.Data.WorkDir}}' | grep 这里放目录的名称aaa
68640, 容器的ID, /abcd, /data/docker/overlay2/aaa/work
这样我们就找到对应的容器id,然后可以先stop这个容器。然后执行 docker system prune
命令,帮我们去清理这个容器的目录。因为文件很多,所以这个命令执行会需要很长的时间,耐心等待即可。它不会死机的。(我执行了将近一个小时。。。)
之后再去看 df -i
就发现索引节点,全部都释放出来了。服务器可以正常的创建文件或者文件夹了。
最后。我们这里是某个程序出现错误,导致一直在重试去创建文件。。然后就把索引节点使用光了。。。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。