2

我有一个在 Docker 容器中运行的已部署应用程序,它实际上是一个永远运行的 websocket 客户端。每次部署我都在重建容器并docker run使用Dockerfile.

现在,我注意到该进程偶尔会在没有重新启动的情况下死掉。运行时docker ps,我可以看到容器已启动,并且已经启动了 2 周,但是在其中运行的进程已经死亡,而主机没有更聪明

我是否需要在 docker 容器内有一个进程管理器来管理容器化进程?

编辑:

Dockerfile:https ://github.com/DVG/catpen-edi/blob/master/Dockerfile

4

3 回答 3

3

我们开发了一个为 Docker 容器量身定制的流程管理器,并且已经成功地使用它来解决您所描述的问题。最好的起点是查看 github 上的 chaperone-docker。第一页上的自述文件包含一个指向最小基础镜像以及完全配置的 LAMP 堆栈的快速链接,因此您可以尝试一下,看看完全配置的镜像会是什么样子。它是开源的并且有完整的文档记录。

于 2015-06-28T21:36:36.907 回答
1

这是一个非常有趣的问题,它与 PID1 以及 docker 用CMDor中指定的命令替换 PID1 的事实有关ENTRYPOINT。发生的情况是,如果父进程死亡并且它成为孤儿,则子进程不会自动被任何东西采用(因为没有像您习惯的传统 init 系统意义上的 PID1)。这里有一些优秀的读物,可以给你一些想法。你可能会从他们那里获得一些里程baseimage-docker带有简化的初始化系统(“my_app”)的图像,它将为您解决一些问题。但是,我强烈警告您不要为所有容器自动采用 Phusion 思维方式,因为该领域存在一些意识形态摩擦。我不记得在 Docker 的 Github 上讨论过任何关于解决这个问题的潜在最小初始化系统的讨论,但我无法想象这将是一个永远的问题。祝你好运!

于 2015-05-12T19:54:38.253 回答
0

如果您有两个 ruby​​ 进程,听起来孩子还没有退出,应用程序刚刚停止工作。EventMachine 反应器很可能就在后台。

EDI 应用程序真的需要生成额外的 Ruby 进程吗?这只会在 Docker 和您的应用程序之间添加另一层。直接运行服务器CMD [ "ruby", "boot.rb" ]。如果您发现问题仍然存在于单个进程中,那么您将需要找出导致您的应用程序挂起的原因。

当一个进程作为 PID 1 是 docker 运行时,它也需要处理SIGINTSIGTERM信号。

# Trap ^C 
Signal.trap("INT") { 
  shut_down 
  exit
}

# Trap `Kill `
Signal.trap("TERM") {
  shut_down
  exit
}

Docker 还具有针对容器实际死亡时间的重启策略

docker run --restart=always
  • no 容器退出时不要自动重启。这是默认设置。
  • on-failure[:max-retries] 仅当容器以非零退出状态退出时才重新启动。(可选)限制 Docker 守护程序尝试重新启动的次数。
  • always 无论退出状态如何,始终重新启动容器。当您指定 always 时,Docker 守护程序将尝试无限期地重新启动容器。无论容器的当前状态如何,容器也将始终在守护程序启动时启动。
  • unless-stopped 无论退出状态如何,始终重新启动容器,但如果容器之前已进入停止状态,则不要在守护进程启动时启动它。
于 2017-10-18T01:15:22.920 回答