在k8s管理docker的过程中,我们发现会出现大量的处于dead状态的container,这些container 使用docker rm -f container-id是无法删除的。为此,对此进行了调研,发现是由于container使用的root文件系统没有卸载导致的,因为container 使用了mnt namespace技术,宿主机上无法直接卸载指定的文件系统。因此有了如下的解决方案。本解决方案通过bash脚本进行了实现,主要涉及到了两个文件,rm_dead_container.sh, ns_enter.
rm_dead_container.sh是一个bash脚本,其内容如下:
IDS=docker ps -f status=dead -q
for ID in $IDS
do
IDL=docker inspect --format='{{.ID}}' $ID
DeviceName=docker inspect --format='{{.GraphDriver.Data.DeviceName}}' $ID
while true
do
grep $DeviceName /proc/[1-9]*/mounts -rn >/tmp/grep.rst
LINE=head -n 1 /tmp/grep.rst
if [ -z $LINE ]
then
docker rm $ID
break
fi
PID=echo $LINE|cut -d '/' -f 3
./nsenter /proc/$PID/ns/mnt umount /dev/mapper/$DeviceName
done
done
ns_enter 是一个用c语言写的进入指定namespace执行指定命令的工具,供rm_dead_container.sh进行调用,其源码如下:
} while (0)
int
main(int argc, char *argv[])
{
int fd;
if (argc < 3) {
fprintf(stderr, "%s /proc/PID/ns/FILE cmd args...\n", argv[0]);
exit(EXIT_FAILURE);
}
fd = open(argv[1], O_RDONLY); / Get descriptor for namespace /
if (fd == -1)
errExit("open");
if (setns(fd, 0) == -1) / Join that namespace /
errExit("setns");
execvp(argv[2], &argv[2]); / Execute a command in namespace /
errExit("execvp");
}
如果觉得我的文章对您有用,请点赞。您的支持将鼓励我继续创作!
赞5
添加新评论0 条评论