如何知道我的程序是不是完全在我的 docker 中使用 compose 启动

Posted

技术标签:

【中文标题】如何知道我的程序是不是完全在我的 docker 中使用 compose 启动【英文标题】:How to know if my program is completely started inside my docker with compose如何知道我的程序是否完全在我的 docker 中使用 compose 启动 【发布时间】:2016-12-31 06:40:02 【问题描述】:

在我的 CI 链中,我在“docker-compose up”之后执行端到端测试。不幸的是,我的测试经常失败,因为即使容器正确启动,我的容器中包含的程序也没有。

在运行我的测试之前,是否有一种优雅的方式来验证我的设置是否已完全启动?

【问题讨论】:

对此没有一个简单的答案 - 这取决于您的设置。我认为现在最好的做法是在你的服务中设置健康检查 - 简单的 http 服务运行测试并以 Ok / not-ok 回复进行响应。 感谢您的提示! Healthcheck 似乎是执行我想要的事情的好方法。但是,docker-compose 似乎并不关心健康状况。那么,您如何利用它呢? 【参考方案1】:

如果您在 CI 设置中控制了 docker 引擎,则可以执行 docker logs [Container_Name] 并读出您的应用程序可能发出的最后一行。

RESULT=$(docker logs [Container_Name] 2>&1 | grep [Search_String])

日志输出示例:Agent pid 13Enter passphrase (empty for no passphrase): Enter same passphrase again: Identity added: id_rsa (id_rsa)#host SSH-2.0-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2.6#host SSH-2.0-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2.6

解析特定行:RESULT=$(docker logs ssh_jenkins_test 2>&1 | grep Enter)

结果:Enter passphrase (empty for no passphrase): Enter same passphrase again: Identity added: id_rsa (id_rsa)

【讨论】:

【参考方案2】:

您可以在运行测试之前轮询所需的服务以确认它们正在响应。

curl 内置了retry logic,或者围绕其他类型的服务测试构建重试逻辑相当简单。

#!/bin/bash

await()
  local url=$1
  local seconds=$2:-30
  curl --max-time 5 --retry 60 --retry-delay 1 \
       --retry-max-time $seconds "$url" \
  || exit 1


docker-compose up -d
await http://container_ms1:3000
await http://container_ms2:3000
run-ze-tests

轮询的替代方案是基于事件的系统。 如果您的所有服务都将通知推送到外部服务,scaeda gave the example of a log file 或者您可以使用 Amazon SNS 之类的东西。您的服务会发出“启动”事件。然后,您可以订阅这些事件并在一切开始后运行您需要的任何内容。

Docker 1.12 确实添加了HEALTHCHECK 构建命令。也许这可以通过Docker Events 获得?

【讨论】:

感谢您的回答!这是我考虑过的解决方案。这可行,但您必须维护您的“等待脚本”,并且您将在生产中面临同样的问题。您必须创建一个启动 docker-compose 并等待脚本的脚本,而不是仅仅执行“docker-compose up”。 Docker 已经摆脱了传统的 unix 守护进程,在传统的 Unix 守护进程中,他们至少可以选择一个点作为进程的后台,并且脚本将继续运行。 mongodb 就是一个很好的例子,只有在它准备好接受连接时才这样做。轮询的替代方案是事件系统,您可以在其中将通知从应用程序推送到应用程序启动的外部。然后您可以订阅这些事件并对其采取行动。

以上是关于如何知道我的程序是不是完全在我的 docker 中使用 compose 启动的主要内容,如果未能解决你的问题,请参考以下文章

如何检查 docker daemon 是不是正在运行?

我如何知道用户是不是以相同的 ID 登录了其他设备,我在我的应用程序中使用了 XMPP

如何在我的 docker ubuntu 映像中获取 nvidia 驱动程序?

如何在我的 docker 镜像中安装 postgresql?

响应跳板的终止而终止如何影响我的应用程序

如何在我的应用程序上显示来自 Firebase 存储的图像?