【发布时间】:2015-09-14 14:02:04
【问题描述】:
我已经设置了一个 Kippo 服务器以在 docker 容器中运行。一切运行良好,直到你杀死容器。杀死容器(通过重新启动机器或通过 docker kill)使其无法使用 STDERR“另一个扭曲的服务器正在运行,PID 1”。我怎么解决这个问题?我没有重置容器的文件系统或类似的问题,因为我想要的所有内容都记录到数据库中。非常感谢
【问题讨论】:
标签: docker containers twisted pid
我已经设置了一个 Kippo 服务器以在 docker 容器中运行。一切运行良好,直到你杀死容器。杀死容器(通过重新启动机器或通过 docker kill)使其无法使用 STDERR“另一个扭曲的服务器正在运行,PID 1”。我怎么解决这个问题?我没有重置容器的文件系统或类似的问题,因为我想要的所有内容都记录到数据库中。非常感谢
【问题讨论】:
标签: docker containers twisted pid
在 Docker 中,每个容器都在自己的 PID 命名空间中运行。这意味着 dockerfile 启动的进程将始终为 PID 1,并且 PID 将从那里向上计数。
twistd 期望 PID 具有足够的不确定性,它可以通过简单地比较 PID 是否相同来检查另一个twistd 是否“已经在运行”。因为,在 Docker 中,PID 总是 1,所以这个检查总是成功的,twistd 认为它不应该启动。如果容器不干净地退出,twistd 将没有机会清理其.pid 文件,并且状态将保留在容器的文件系统中。
由于 Docker 守护进程将命名容器并阻止两个匹配的twistd 进程同时启动,.pid 文件及其相关检查实际上根本没有用,因此您应该禁用它。您可以通过更改命令行以在插件名称前包含 --pidfile= 选项(完全如此,“=”之后没有任何内容)来禁用它。我不熟悉 Kippo,但对于 twistd web,这将是 twistd --pidfile= web。
我希望这会有所帮助!
【讨论】:
twistd 命令行,无需删除 pid 文件,因为它们既不会被写入也不会被检查。
听起来你在容器中的 pid1 在被告知停止后没有正确清理。这可能意味着它不会删除其 pidfile,因此当您再次启动容器时,它会拒绝启动。
解决这个问题的一种方法可能是引入类似 supervisord 的东西,它可以处理接收停止信号,然后优雅地关闭 kippo 服务器。
另一种解决方案可能是简单地以只读模式启动容器。在只读模式下,容器没有写入层,根文件系统只是只读的。但是,如果 Kippo 无法创建一个 pidfile 以作为开始,它可能会拒绝启动。 (见docker run --read-only)
另一种解决方案是设置一个 ENTRYPOINT 脚本,在调用 kippo 上的 exec 之前删除 pidfile。
【讨论】: