zhuqibs
作者zhuqibs·2020-04-06 20:08
软件开发工程师·Adidas

k8s 中出现的dead 状态的container 的解决方案

字数 1350阅读 1630评论 0赞 5

在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脚本,其内容如下:

!/bin/bash

set -x

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进行调用,其源码如下:

define _GNU_SOURCE

include

include

include

include

include

define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \

} 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 条评论

Ctrl+Enter 发表

作者其他文章

相关文章

相关问题

相关资料

X社区推广