kubelet删除Pod报device or resource busy

删除 deployment 资源后, 某些 pod 资源的状态一直显示 Terminating, 进入到该 pod 所在的宿主机, 查看 kubelet 日志:

1
journalctl -u kubelet -f

会发现有删除某些目录/文件 device or resource busy 的错误出现, 说明有其他的进程在挂载容器内使用的目录

使用如下脚本, 检查目录挂载情况

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[root@k8s-node ~]# cat leak.sh 
#!/bin/bash
declare -A map
for i in `find /proc/*/mounts -exec grep $1 {} + 2>/dev/null | awk '{print $1"#"$2}'`
do
pid=`echo $i | awk -F "[/]" '{print $3}'`
point=`echo $i | awk -F "[#]" '{print $2}'`
mnt=`ls -l /proc/$pid/ns/mnt |awk '{print $11}'`
map["$mnt"]="exist"
cmd=`cat /proc/$pid/cmdline`
echo -e "$pid\t$mnt\t$cmd\t$point"
done

for i in `ps aux|grep docker-containerd-shim |grep -v "grep" |awk '{print $2}'`
do
mnt=`ls -l /proc/$i/ns/mnt 2>/dev/null | awk '{print $11}'`
if [[ "${map[$mnt]}" == "exist" ]];then
echo $mnt
fi
done

执行脚本, 后跟device or resource busy的目录绝对路径

1
sh leak.sh /var/lib/kubelet/pods/81791176-a505-11e7-accf-5254fe5a9007/volumes/kubernetes.io~secret/default-token-pzyxh

执行后, 可以看到该目录被哪些进程所挂载

1
8392    mnt:[4026532536]    /bin/bash/start.sh--logtostderr -v=2    /var/lib/kubelet/pods/81791176-a505-11e7-accf-5254fe5a9007/volumes/kubernetes.io~secret/default-token-pzyxh

一级一级往上追踪父进程

1
2
3
4
5
[root@k8s-node ~]# ps -ef | grep 8392
root 8392 8345 0 9月30 ? 00:00:00 /bin/bash /start.sh --logtostderr -v=2
root 8420 8392 0 9月30 ? 00:17:19 /usr/bin/python /usr/bin/supervisord -c supervisord.conf
root 13757 7126 0 13:35 pts/2 00:00:00 grep --color=auto 8392
[root@k8s-node ~]#

我遇到的情况是另一个专门用于收集日志的容器, 挂载了这个容器中的数据目录, 导致删除该容器时, 报device or resource busy的错误

这种情况下, 你可以是用kubectl execdocker exec进入到容器中, 将该目录 umount 掉, 过一会儿, 该 pod 即可被 Kubernetes 正确删除


参考文档: