今天在逛大佬的博客时又学到好东西了,特此记录一下,关于K8s中Pod调试的奇技淫巧,虽然不一定能用到,但是值得记录
k8s的pod exit非0调试
pod一直crash的话,我们把command用下面这个,生存探针啥的全部注释掉。command用bash,tail之类的会在调试完成delete kill的时候阻塞住,参考 infinite blockings 。
["bash", "-c", "coproc { exec >&-; read; }; eval exec \"${COPROC[0]}<&-\"; wait"
解读
这个 Dockerfile 命令是一种巧妙的方法,用于保持 Pod 运行状态以进行调试。它做了以下几件事:
使用 bash -c 执行一个命令
coproc { exec >&-; read; } 在后台启动一个协程,并立即阻塞读取输入
eval exec “${COPROC[0]}<&-” 将 shell 的标准输入重定向到该协程
wait 等待 shell 命令结束这样的效果是:
- 启动一个一直阻塞读取输入的协程 - 将 shell 的标准输入重定向到那个协程 - shell 本身会一直 wait 等待,维持运行状态所以,Pod 中的这个 bash 命令会一直运行等待,不会退出。这就保证了 Pod 也不会因为命令退出而退出。这给我们时间在 Pod 内进行调试,而不必担心它会因为命令退出而退出:- 我们可以在其中运行其他调试命令 - 可以查看日志、事件等诊断信息 - 可以使用 kubectl exec 进入 Pod 交互调试 当调试完成,我们可以:
- 删除 Pod 让其退出 - 发送 SIGINT 给 bash 进程退出 wait 状态,从而退出 Pod - docker kill 杀死容器这种方法相比直接删除 Pod 的优点是:- 给我们时间在 “运行状态"下进行调试 - Pod 退出后,事件、日志等诊断信息也不会丢失,更有助于排查问题所以,总结来说,这是一个巧妙的方法来维持容器运行以进行调试。通过一个一直 wait 的 shell 命令,来防止 Pod 因为命令退出而直接退出。