1.背景:
(1)胖容器ssh登录报错:handshake error
(2)登录宿主机后,观察pod状态为running,但是kubectl exec 和docker exec 均无法进入该容器,报错如下
2.原因:
这种情况可能是容器内的业务进程发生线程泄露,通常是java程序引起
3.处理方式:
(1)登录实例的宿主机上
(2)先检查下有没有登录错机器,执行 kubectl get namespaces | grep 那台实例的ns,有记录就是没错。例如:kubectl get namespaces | grep lc-test
(3)cd /sys/fs/cgroup/pids/kubepods && find -name pids.current |grep pod |xargs -I file sh -c 'echo -e file" c" && cat file'|awk '$2 > 10000' 找出线程数高的容器
(4)进入对应容器的pid相关目录,记住,是进入搜索得到的目录。搜索到的是两个目录,需要到第二个记录操作,就是pod的目录下。而不是没有cd直接就echo,此操作有风险,须知!!!
若不确定自己容器的pids.max在哪个目录下,可查找poduid定位
(5)echo 16000 >pids.max 修改线程数限制,记得分清楚目录,如果搞成修改宿主机的线程数,可能会导致该宿主机上的实例全部挂了,有风险。
(6)如果可以停止或者重启,可以登录实例手动处理一下。命令:kubectl exec -it -n podns podname /bin/bash eg:kubectl exec -it -n poseidon-monitor poseidon-monitor /bin/bash
备注:确认容器哪个进程的线程数较多:ps -ef |grep -v PID |awk '{print $2}' |xargs -I file sh -c 'echo -e file" c" && cat /proc/file/status 2>/dev/null|grep Threads'|sort -unr -t : -k 2
然后直接kill -9
(7)echo 15000 >pids.max 待修正后恢复该容器的最大线程限制为15000
总结:这种案例的表现通常为,pod状态running, kubectl,docker exec都无法进入容器,或者存在docker ps 卡住现象