现象
有同事反馈容器云pod中默认提供的10g(我们节点的docker graph driver是devicemapper)根目录被占满了,但是又无法找到具体是哪些文件占用
这种情况很有可能是存在一些被标记为删除的文件(删除动作目前了解到是人为触发的),但是由于进程并没有中止,文件并没有实际删除,表现出来就是进程会占用文件但又找不到。
排查
可以通过lsof -s | grep -i delete来查看是哪些进程占用了僵死文件,以下简单重现问题
使用nohup cmd args &组合执行命令
nohup tail -f /var/log/messages &
通过lsof查看tail进程使用的文件信息
[root@k8s-node01 ~]# ps -ef | grep tail
root 3308 1164 0 14:44 pts/1 00:00:00 grep --color=auto tail
root 17747 17027 0 14:33 pts/0 00:00:00 tail -f /var/log/messages
[root@k8s-node01 ~]# lsof -w -p 17747
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
tail 17747 root cwd DIR 253,1 4096 2359297 /appdata
tail 17747 root rtd DIR 253,1 4096 2 /
tail 17747 root txt REG 253,1 66896 4720 /usr/bin/tail
tail 17747 root mem REG 253,1 106075056 3921 /usr/lib/locale/locale-archive
tail 17747 root mem REG 253,1 2151672 3908 /usr/lib64/libc-2.17.so
tail 17747 root mem REG 253,1 163400 3499 /usr/lib64/ld-2.17.so
tail 17747 root 0w CHR 1,3 0t0 5334 /dev/null
tail 17747 root 1w REG 253,1 3343 2371796 /appdata/nohup.out
tail 17747 root 2w REG 253,1 3343 2371796 /appdata/nohup.out
tail 17747 root 3r REG 253,1 1683758 393813 /var/log/messages
tail 17747 root 4r a_inode 0,10 0 5330 inotify
删除文件/appdata/nohup.out
rm -rf /appdata/nohup.out
再次查看tail进程占用的文件
[root@k8s-node01 appdata]# lsof -w -p 17747
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
tail 17747 root cwd DIR 253,1 4096 2359297 /appdata
tail 17747 root rtd DIR 253,1 4096 2 /
tail 17747 root txt REG 253,1 66896 4720 /usr/bin/tail
tail 17747 root mem REG 253,1 106075056 3921 /usr/lib/locale/locale-archive
tail 17747 root mem REG 253,1 2151672 3908 /usr/lib64/libc-2.17.so
tail 17747 root mem REG 253,1 163400 3499 /usr/lib64/ld-2.17.so
tail 17747 root 0w CHR 1,3 0t0 5334 /dev/null
tail 17747 root 1w REG 253,1 5075 2371796 /appdata/nohup.out (deleted)
tail 17747 root 2w REG 253,1 5075 2371796 /appdata/nohup.out (deleted)
tail 17747 root 3r REG 253,1 639 393813 /var/log/messages
tail 17747 root 4r a_inode 0,10 0 5330 inotify
可以看到nohup.out文件被标记为删除
不断重复执行lsof -w -p 17747,可以发现nohup.out文件大小(lsof第七列为大小)还是会继续增长
通过以上就可以发现这种僵死文件即使被删除但是会占磁盘空间,在我们的容器云使用场景因为达到了pod 10g空间限制,pod就无法正常运行了
结论
因为对应的环境是压测环境,java应用将日至输出到了控制台,并发大的时候,就会出现将大量应用日志都写道了nohub.out文件中,最终用完了空间。
所以清理文件,更推荐的是cat /dev/null > file,而不是直接删除文件
这里我们应该思考的是,在虚拟机中常用的nohup cmd args &的组合,是否也适合在容器场景里面呢?
--》在容器云里面,不再建议使用这种组合方式,因为使用容器运行的方式不存在终端关闭nohup信号中止进程的问题,另外使用 & 后台运行,容易导致容器直接推出(exit 0)
nohup cmd args & 这个组合的作用在虚拟机上就是可以在后台运行,与执行终端脱离,不响应挂断hang up,可以简单测试一下
开启两个终端 其中一个窗口执行 tail -f /var/log/messages后关闭终端,关闭窗口会中止进程,在另一个窗口执行ps -ef | grep tail 无法找到 其中一个窗口执行tail -f /var/log/messages &后,ctrl+c无法中止进程,关闭窗口会中止进程,在另一个窗口执行ps -ef | grep tail 无法找到 其中一个窗口执行 nohup tail -f /var/log/messages,ctrl+c可以中止进程,关闭窗口不会中止进程,在另一个窗口执行ps -ef | grep tail 可以看到ppid由bash变成1 执行 nohup tail -f /var/log/messages & ctrl+c和关闭窗口都不会退出 [root@k8s-node01 ~]# kill -l 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM 16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR 31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3 38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8 43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7 58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2 63) SIGRTMAX-1 64) SIGRTMAX