2017-09-05 76 views
0

我有一个docker容器,它运行node.js应用程序。此应用程序运行一个无头镀铬实例。僵尸里面的码头

,一切顺利,但如果我杀了镀铬的实例,并检查拼命地跑进程列表,我会看到2个(实际上是3 + 2的猫过程)僵尸铬工艺(解散)仍处于系统。我知道这个程序是一个儿童 (死亡父母铬工艺),这是未完成正确并附init过程。

我试图直接杀死它 - 拒绝。另外我试图用detached:true标志产生铬,并直接杀死所有子进程,当主铬接收到“退出”信号时,无论如何ps -A | grep chrome显示两个不存在给我。有任何想法吗?

UPD: 谢谢大家的帮助。添加--init完全解决了我的问题。使用另一个基本图像也很好,但我决定这种方法不是必须的。也可以找到根本原因的好描述here

回答

-1

larsks几乎是钉子的原因,linux系统上的init(或systemd)在其父母死亡时收获僵尸进程。父母应该使用wait系统调用清理自己的僵尸进程。但是,该自动清理不会传递容器的名称空间边界。因此,无论您作为入口点运行的进程是否为pid 1,都需要为您处理这些僵尸。

使用最新版本的docker,只需将--init传递给docker run命令即可包含init进程。如果您使用的是版本2.2撰写文件,则可以在服务上定义一个选项init: true以获得相同的结果。

除了dumb-init之外,还有tini,这是docker在封面下用作他们自己的docker-init的东西。

1

您需要一个过程,将调用wait()以获得任何zombie processes。在常规系统上,这由/sbin/init处理,但在容器内部,您需要提供自己的工具。如果您正在开发自己的应用程序,请考虑定期在循环中调用wait()

或者,您可以考虑特定容器init,如dumb-init,看看是否可以解决问题。

+0

你是指在码头终端内运行“root @ daf1ccd11aaa:〜/ myapp#** wait **”(或者调用node.js exec('wait',()= {...})) ?如果是的话,它没有帮助,如果我理解错误 - 请解释你的建议 –

+0

阅读关于僵尸进程的链接文章。您需要在容器中调用[等待系统调用](http://man7.org/linux/man-pages/man2/waitpid.2.html)的PID 1。使用'dumb-init'(或'supervisord'或其他进程管理器)之类的东西可以为你做到这一点。 – larsks