如何调查在Docker容器中停止的主进程失败

63次阅读
没有评论

问题描述

有时候你需要调查一个已停止的容器,或者一个在启动后很快失败并停止的容器。使用 docker exec -ti <id> bash 命令只能在运行中的容器上使用,一旦它完成,bash 提示符也会终止。使用 docker start 命令不能提供一个不同的命令,如果容器再次突然停止,你将没有足够的时间进入容器进行调查。你可以使用 docker commit,然后使用新镜像上的 docker run 命令来运行不同的命令,但我想知道是否还有其他选择。需要注意的是,docker logs 只会返回应用程序打印到 stdout/stderr 的内容,这可能不足以找出问题所在。

解决方案

请注意以下操作可能存在版本差异及风险,请在实际操作前谨慎备份。

使用 strace 跟踪进程失败原因

一种常用的方法是在Linux中使用 strace 跟踪进程的系统调用,这通常会指出进程失败的原因。你可以创建一个名为 Dockerfile 的文件,内容如下:

FROM original_image
RUN apt-get -y update && apt-get install -y strace

使用 docker build -t debug_version 命令构建新的镜像,然后使用 docker run debug_version strace original_cmd 命令运行你的新镜像,其中 original_cmd 是原始容器中的命令。对于那些会 fork 子进程然后退出的进程,你可以使用 strace-ff 选项来运行。你还可以使用 Docker 数据卷来映射一些文件,并使用 strace-o 选项将输出写入其中。一般情况下,strace 会将输出留在 stdout 中,可以使用 docker log 来查看。

修改容器入口命令

如果容器在启动时立即失败,你可以使用 docker run 命令来指定替代的 --entrypointCMD。通常,我会将其设置为一个不会自行退出的循环或类似的内容。一旦进入容器,你可以手动运行失败的步骤,然后在容器不退出的情况下检查结果。

其他注意事项

请注意,尽管你可以使用上述方法来调查进程失败的原因,但在一些情况下,容器的日志和输出可能不足以解决问题。在处理容器问题时,确保你了解应用程序的行为,可能需要根据具体情况进行调整和扩展。

参考链接:Linux process terminates mysteriously

总结

无论是使用 strace 跟踪系统调用,还是修改容器入口命令,都可以帮助你调查容器中主进程失败的原因。通过这些方法,你可以更好地理解进程失败的原因,并采取适当的措施来解决问题。在处理容器问题时,要特别注意容器的日志和输出,以及应用程序本身的行为。

正文完