问题现象:
当我们的容器通过exec进行探测的时候,需要经过几个过程,分别是
runc init → runc exec → containerd-shim exec → containerd exec → dockerd exec
containerd-shim启动runc exec去容器内执行用户命令,而runc exec启动runc init进入容器时,由于往pipe写入数据超过限制大小而被阻塞。当最底层的runc init被阻塞时,造成了调用链路上所有进程都被阻塞,进而看到容器被hang住卡死
解决方法:
1、我们最直接的方法是重启机器,这样所有的主机进程都被kill,docker异常容器恢复,这种方式会导致机器上的服务都被重启,测试环境可以这样子搞
2、既然docker exec可能会引起docker hang死,那么我们禁用系统中所有的docker exec操作即可。最典型的是kubelet的probe,当前我们默认给所有Pod添加了ReadinessProbe,并且是以exec的形式进入容器内执行命令。我们调整kubelet的探测行为,修改为tcp或者http probe即可
3、我们很多的老服务已经在使用exec来探测了,进行整改不太容易,那怎么办呢,有没有直接杀死异常容器的办法,可以临时解决这个问题,答案是肯定的。如下操作:
一、
[root@-5-4-25 ~]# docker ps |grep kindling
17ec165b597f dockerhub.yonyoucloud.com/c87e2267-1001-4c70-bb2a-ab41f3b81aa3/kindling-agent "sh start.sh" 3 months ago Up 3 months k8s_kindling-agent_kindling-agent-9m8vn_kindling_e55d79eb-6e76-49c2-870e-2e679feb8f13_102
[root@-5-4-25 ~]#
[root@-5-4-25 ~]#
[root@-5-4-25 ~]#
[root@-5-4-25 ~]# ps uax |grep 17ec165b597f
root 6867 7.7 0.0 1071244 18192 ? Sl Sep08 10888:12 runc --root /var/run/docker/runtime-runc/moby --log-format json delete --force 17ec165b597f44690943f79d94d9216d179dd6239be4419ab23e601e3ec39082
root 31474 0.0 0.0 112824 2316 pts/0 S+ 15:43 0:00 grep --color=auto 17ec165b597f
[root@-5-4-25 ~]# kill -9 6867
[root@-5-4-25 ~]# docker ps |grep kindling
[root@-5-4-25 ~]#
[root@-5-4-25 ~]#
二、
登录到master节点,强制删除节点异常的容器即可恢复
kubectl delete pod kindling-agent-9m8vn -n kindling --force --grace-period 0