1

我想在我的 Docker 容器中启动两个不同的服务,并在其中一个退出后立即退出容器。我查看了主管,但我找不到如何在其中一个托管应用程序退出后立即退出。它尝试重新启动它们最多三次,就像标准设置一样,然后就坐在那里什么也不做。主管是否能够做到这一点,或者是否有任何其他工具可以做到这一点?如果还有一种方法可以让两个托管程序都写入标准输出,并标有它们的应用程序名称,那将是一个好处,例如:

[Program 1] Some output
[Program 2] Some other output
[Program 1] Output again

4

2 回答 2

2

既然你问是否有其他工具......我们设计并编写了一个强大的替代品supervisord,专为 Docker 设计。它会在所有应用程序退出时自动终止,并具有特殊的服务设置来控制此行为,此外还将使用标记的 syslog 兼容输出行重定向标准输出。它是开源的,正在生产中使用。

这是 Docker 的快速入门:http: //garywiz.github.io/chaperone/guide/chap-docker-simple.html

还有一整套经过测试的基础图像,这是一个很好的例子:https ://github.com/garywiz/chaperone-docker ,但这些可能有点过头了,早期的快速入门可能会奏效。

于 2015-09-10T01:48:38.027 回答
1

通过阅读更多文档,我找到了满足我这两个要求的解决方案。

在应用程序退出时退出 supervisord
这可以通过使用自定义事件监听器来实现。我必须将以下部分添加到我的 supervisord 配置文件中:

[eventlistener:shutdownevent]
command=/shutdownhandler.sh
events=PROCESS_STATE_EXITED

supervisord 将启动引用的脚本,并在触发给定事件时(在其中一个托管程序退出后触发 PROCESS_STATE_EXITED 并且它不会自动重新启动)将在脚本 stdin 上发送包含有关事件数据的行。
引用的 shutdownhandler-script 包含:

#!/bin/bash
while :
do
    echo -en "READY\n"
    read line
    kill $(cat /supervisord.pid)
    echo -en "RESULT 2\nOK"
done

脚本必须通过在其标准输出上发送“READY\n”来指示准备就绪,之后它可能会在其标准输入上接收到一个事件数据行。对于我在收到一行时的用例(意味着其中一个托管程序已退出),一个 SIGTERM 被发送到由它留在其 pid 文件中的 pid 找到的 supervisord 进程(默认情况下位于根目录中)。为了技术的完整性,我还为事件监听器提供了一个肯定的答案,尽管这个答案并不重要。

在标准输出上标记输出
我通过在启动 supervisord 之前在后台启动一个尾部进程来完成此操作,拖尾程序输出日志并通过 ts (来自 moreutils 包)将行通过管道添加到它前面。通过这种方式,它通过 docker logs 显示出来,并以一种简单的方式来查看哪个程序实际编写了该行。

tail -fn0 /var/log/supervisor/program1.log | ts '[Program 1]' &
于 2015-09-10T18:18:34.210 回答