如何检测Docker是否以编程方式成功运行?


82

我正在编写一个非常简单的bash脚本,以快速检查我的容器仍在构建并正确启动,并且其中的应用程序能够响应请求。

有时会docker run失败,例如因为我尝试将容器绑定到的端口已分配。但是当发生这种情况时docker run,退出代码仍为0,因此我无法使用退出代码。如何以编程方式检查容器是否已正确启动?

我正在考虑的解决方案是:

  • 解析输出中的错误
  • docker ps 查看容器是否正在运行

但是这些似乎都有些过分和丑陋。我是否缺少更好的方法来检查是否docker run成功?


1
我不确定这是什么问题。如果所讨论的进程行为正常,那么您只需检查退出代码即可。如果即使在失败的情况下也发出退出代码0,请尝试确定是否是错误。如果程序在任何情况下都返回退出代码0,那么您可能别无选择,只能解析输出。
devnull 2014年

就像@devnull所说的,如果您不信任docker run会在失败时返回一个非零的返回码,那么您所能做的就是解析输出(可能很复杂或脆弱)或使用另一个命令(即您的ps建议) )检查第一个命令的结果。您可能要考虑向docker提交票证,以查看他们是否也可以修复返回码run
伊坦·赖斯纳

确保您具有最新版本。
ooga 2014年

是在容器中运行的自定义代码吗?如果是这样,则可以在Dockerfile中导出端口,当程序处于稳定运行状态时,在该端口上发送“ OK”消息。您的客户代码等待“确定”消息。
rexposadas 2014年

3
您能否提供一个示例说明如何运行docker以及哪个版本?快速测试显示docker出口代码对我来说是1docker run -d -p 9010:9010 busybox true ; echo $?
AbelMuiño2014年

Answers:


116

正如AbelMuiño在评论中所建议的那样,这可能已在较新的Docker版本中修复(我当前正在运行0.9.1)。

但是,如果您像我一样暂时停留在较旧的版本上,我确实找到了一种不错的解决方法来检查容器是否通过使用开始docker inspect

docker inspect返回一个JSON对象,其中包含有关容器的大量信息,尤其是容器当前是否正在运行。该-f标志使您可以轻松提取所需的位:

docker inspect -f {{.State.Running}} $CONTAINER_ID

要么

docker inspect -f "{{.State.Running}}" $CONTAINER_ID

将返回truefalse

请注意,您可能想要sleep 1(或者更多)在启动容器和检查容器是否正常之间。如果您的设置有问题,则可能会在实际退出之前的很短时间内显示为“正在运行”。


11
为什么不使用docker inspect -f {{.State.Running}} <container-id>jq改用?就是想。
Dharmit

2
因为我还没有意识到检查可以让您直接这样做!感谢@DharmitShah这是一个很好的建议,我将更新我的答案。
JulesOlléon,2014年

2
要在没有这样的容器的情况下抑制错误消息,请使用重定向stderr 2> /dev/null
thSoft

如果我将其分配给var,则在使用时会收到错误消息,2> /dev/null因为它没有任何结果。如何将其默认设置为false不存在的容器?
杰克·桑基

1
但是,这不能容纳由于重启策略而不断重启的容器……也就是说,如果容器被赋予了除非重启/总是停止的重启策略,.State.Running将始终返回true...。厌倦!
geekscrap '16

22

为了避免解析任何内容,可以使用docker top,如果容器未运行,则返回1:

id=$(docker run mycontainer)
if ! docker top $id &>/dev/null
then
    echo "Container crashed unexpectedly..."
    return 1
fi

10

我们可以使用docker exec $id true 2>/dev/null || echo not running

该命令不会像“ docker top”那样写入stdout。当容器未运行时,它将写入stderr,与“ docker top”相同。


2

将上述建议应用于脚本。

1-创建一个脚本keepMyDockerUp.sh

vi keepMyDockerUp.sh


#!/bin/bash
Container_ID=INSERT_YOUR_CONTAINER_ID HERE
result=$( docker inspect -f {{.State.Running}} $Container_ID)
echo "result is" $result
if [ $result = "true" ]
then
echo "docker is already running"
else
systemctl restart docker
docker start $Container_ID
fi

2-然后只需将其添加到cron中,以便您的脚本验证Docker容器是否不时启动:

crontab -e

转到最后一行并添加脚本文件。例如:

* * * * * /root/keepMyDockerUp.sh

3-保存crontab,不必担心Docker容器再次关闭。

希望能帮助到你...

;-)


1

我不得不使用:

$ docker inspect -f {{.State.Health.Status}} xxx

(容器处于运行状态,但容器内的服务尚未完全启动。

检查输出的一部分:

"State": {
    "Status": "running",
    "Running": true,
    "Paused": false,
    "Restarting": false,
    "OOMKilled": false,
    "Dead": false,
    "Pid": 1618,
    "ExitCode": 0,
    "Error": "",
    "StartedAt": "2019-03-08T10:39:24.061732398Z",
    "FinishedAt": "0001-01-01T00:00:00Z",
    "Health": {
        "Status": "starting",
        "FailingStreak": 0,
        "Log": []

这不会说明运行是否成功。因为容器可能会运行然后失败。
维诺
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.