Dockerの実行がプログラムで成功したかどうかを検出する方法は?


82

非常に単純なbashスクリプトを作成して、コンテナーがまだビルドされて正しく起動していることと、内部のアプリがリクエストに応答していることをすばやく確認します。

docker runコンテナをバインドしようとしているポートがすでに割り当てられているなどの理由で、失敗することがあります。しかし、これが発生した場合、docker runの終了コードはまだ0であるため、終了コードを使用できません。コンテナが正しく起動したことをプログラムで確認するにはどうすればよいですか?

私が検討している解決策は次のとおりです。

  • エラーの出力を解析します
  • docker ps コンテナが実行されているかどうかを確認する

しかし、これらは両方とも少しやり過ぎで醜いようです。docker run成功したかどうかを確認するためのより良い方法がありませんか?


1
ここで何が問題なのかわかりません。問題のプロセスが通常の方法で動作する場合は、終了コードを確認するだけです。失敗した場合でも終了コード0が出力される場合は、それがバグかどうかを調べてみてください。いずれにせよ、プログラムが終了コード0を返す場合は、出力を解析する以外に選択肢がない可能性があります。
devnull 2014

@devnullが言ったように、docker run失敗時にゼロ以外のリターンコードを返すと信頼できない場合は、出力を解析するか(複雑または壊れやすい可能性があります)、別のコマンドを使用するだけです(つまり、ps提案)最初のコマンドの結果を確認します。dockerでチケットを提出して、リターンコードrunも修正できるかどうかを確認することをお勧めします。
Etan Reisner 2014

最新バージョンであることを確認してください。
ooga 2014

コンテナで実行されているのはカスタムコードですか?その場合、Dockerfileのポートをエクスポートできます。プログラムが安定した実行状態にあるときに、そのポートで「OK」メッセージを送信します。クライアントコードは「OK」メッセージを待ちます。
rexposadas 2014

3
dockerの実行方法とバージョンの例を教えてください。簡単なテストショードッキングウィンドウの終了コードは私のために1になるようにdocker run -d -p 9010:9010 busybox true ; echo $?
アベルMuiño

回答:


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

trueまたはを返しfalseます。

sleep 1コンテナを起動してから起動しているかどうかを確認するまでの間に、おそらく(またはそれ以上)やりたいことに注意してください。セットアップに問題がある場合、実際に終了する前に、非常に短い時間「実行中」と表示される可能性があります。


11
なぜ使用しないdocker inspect -f {{.State.Running}} <container-id>と使うjq代わりに?ただ疑問に思う。
ダーミット2014

2
私は検査に気づかなかったので、これを直接行うことができます!@DharmitShahに感謝します。これはすばらしい提案です。回答を更新します。
ジュールオレオン2014

2
そのようなコンテナがない場合にエラーメッセージを抑制するには、stderrを2> /dev/null。でリダイレクトします。
thSoft 2016年

これを変数に割り当てると、2> /dev/null何も評価されないため、使用時にエラーが発生します。falseコンテナが存在しない場合、どうすればデフォルトにすることができますか?
ジェイクサンキー2016年

1
ただし、これは、再起動ポリシーのために常に再起動しているコンテナには対応していません...つまり、コンテナに再起動ポリシーが指定されている場合、-stopped / alwaysの場合、.State.Runningは常にtrueを返します。飽きて!
geekscrap 2016

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

このコマンドは、「dockertop」のようにstdoutに書き込みません。コンテナが実行されていないときにstderrに書き込みます。これは、「dockertop」と同じメッセージです。


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": []

これは、実行が成功したかどうかを示しません。コンテナが実行されてから失敗する可能性があるためです。
ヴィーノ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.