Dockerコンテナがすぐに終了する理由


239

を使用してバックグラウンドでコンテナを実行します

 docker run -d --name hadoop h_Service

すぐに終了します。しかし、フォアグラウンドで実行すると、正常に動作します。私は使用してログをチェックしました

docker logs hadoop

エラーはありませんでした。何か案は?

DOCKERFILE

 FROM java_ubuntu_new
 RUN wget http://archive.cloudera.com/cdh4/one-click-install/precise/amd64/cdh4-repository_1.0_all.deb
 RUN dpkg -i cdh4-repository_1.0_all.deb
 RUN curl -s http://archive.cloudera.com/cdh4/ubuntu/precise/amd64/cdh/archive.key | apt-key add -
 RUN  apt-get update
 RUN apt-get install -y hadoop-0.20-conf-pseudo
 RUN dpkg -L hadoop-0.20-conf-pseudo
 USER hdfs
 RUN hdfs namenode -format
 USER root
 RUN apt-get install -y sudo
 ADD . /usr/local/
 RUN chmod 777 /usr/local/start-all.sh
 CMD ["/usr/local/start-all.sh"]

start-all.sh

 #!/usr/bin/env bash
 /etc/init.d/hadoop-hdfs-namenode start
 /etc/init.d/hadoop-hdfs-datanode start
 /etc/init.d/hadoop-hdfs-secondarynamenode start
 /etc/init.d/hadoop-0.20-mapreduce-tasktracker start
 sudo -u hdfs hadoop fs -chmod 777 /
 /etc/init.d/hadoop-0.20-mapreduce-jobtracker start
 /bin/bash

1
最も重要なルールは、Docker化されたサーバーがデーモン化しないようにすることです。デーモン化が通常のケースであるため、ほとんどのサーバーパッケージには、フォアグラウンドで強制するオプションがあります。
Arnaud Meuret 2015

あなたが達成したいと思っていることは何でも、安全chmod 777はなく間違っています。正常な権限(この場合はおそらく755)に戻す必要があります。
tripleee

回答:


125

Dockerコンテナーは、そのメインプロセスが終了すると終了します。

この場合、start-all.shスクリプトが終了すると終了します。この場合、hadoopの使い方を説明するのに十分な知識はありませんが、何かをフォアグラウンドで実行したままにするか、runitやスーパーバイザなどのプロセスマネージャを使用してプロセスを実行する必要があります。

あなたが指定しない場合、あなたはそれが機能していると誤解されていると思います-d。まったく同じ効果があるはずです。わずかに異なるコマンドまたはそれを使用し-itて変更したもので起動したと思います。

簡単な解決策は、次のようなものを追加することです。

while true; do sleep 1000; done

スクリプトの最後まで。ただし、スクリプトは実際に開始されたプロセスを監視しているはずなので、これは好きではありません。

(私はhttps://github.com/sequenceiq/hadoop-docker/blob/master/bootstrap.shからそのコードを盗んだと言うべきです)


217

これは私のためのトリックをしました:

docker run -dit ubuntu

その後、次を使用して実行中のプロセスを確認しました。

docker ps -a

コンテナを再度取り付けるため

docker attach CONTAINER_NAME

ヒント:コンテナータイプを停止せずに終了するには: ^P^Q


15
@Tommyは、からdocs.docker.com/engine/reference/commandline/run -d、--detach一戸建てモード:バックグラウンドで実行するコマンド、-i、--interactiveキープSTDINは、接続されていない場合でも、-tを開きます- -tty疑似TTYの割り当て-ditは省略形です

3
@ am17torres右、申し訳ありませんが、紛らわしい質問を明確にさせてください。dは切り離されており、iはインタラクティブなので、dとiの組み合わせは私を混乱させます。私はそれをバックグラウンド(非インタラクティブ)プロセスとして起動することだと思いました。
トミー

2
@Tommyこれらのオプションを組み合わせると、コンテナはバックグラウンドでインタラクティブモードに入ります
Yon

2
@ Tommy、@ am17torres -diが最低限必要です。正しく理解-tして-dいれば、このオプションを使用すると冗長になります
Renaud

2
-t有効にせずに再接続すると、実際にはプロンプトを表示できません...しかし、私は通常exec、気付かないたびに新しいbashを使用するためです。私は問題のMacから取り外しおそらく、私はこの間違ってやってる..持っていた
ルノー

65

私は拡張するか、あえて言って、camposerによって言及された回答を改善したいと思います

あなたが走るとき

docker run -dit ubuntu

基本的に、インタラクティブモードでコンテナをバックグラウンドで実行しています。

CTRL + D(最も一般的な方法)でコンテナーをアタッチして終了すると、上記のコマンドでコンテナーを開始したメインプロセスを強制終了したため、コンテナーを停止します。

すでに実行中のコンテナーを利用して、bashの別のプロセスをフォークし、次のコマンドを実行して疑似TTYを取得します。

docker exec -it <container ID> /bin/bash

29

追加したスクリプトの実行が終了した後もコンテナを稼働させたい場合

&& tail -f /dev/null

コマンドの最後。だからそれはする必要があります:

/usr/local/start-all.sh && tail -f /dev/null

19

なぜDockerコンテナはすぐに終了するのですか?

(何かをデバッグしたり、ファイルシステムの状態を調べたりするために)イメージを強制的に停止させたい場合は、エントリポイントを上書きしてシェルに変更できます。

docker run -it --entrypoint=/bin/bash myimagename

18

良いアプローチは、バックグラウンドで実行しているプロセスとサービスを起動し、wait [n ...]スクリプトの最後でコマンドを使用することです。bashでは、waitコマンドは現在のプロセスに次のことを強制します。

指定された各プロセスを待機し、その終了ステータスを返します。nが指定されていない場合、現在アクティブなすべての子プロセスが待機され、戻りステータスはゼロです。

セバスチャンプハダスのエルクビルドの開始スクリプトからこのアイデアを得ました

元の質問から、start-all.shは次のようになります...

 #!/usr/bin/env bash
 /etc/init.d/hadoop-hdfs-namenode start &
 /etc/init.d/hadoop-hdfs-datanode start &
 /etc/init.d/hadoop-hdfs-secondarynamenode start &
 /etc/init.d/hadoop-0.20-mapreduce-tasktracker start &
 sudo -u hdfs hadoop fs -chmod 777 /
 /etc/init.d/hadoop-0.20-mapreduce-jobtracker start &
 wait

5

これをDockerfileの最後に追加します。

CMD tail -f /dev/null

Dockerファイルの例:

FROM ubuntu:16.04

# other commands

CMD tail -f /dev/null

参照


CMD tail -f /dev/nullそれを実行しますsh -c "..."exec代わりにフォームを使用できますか?すなわちCMD ["tail", "-f", "/dev/null"]
メッリオ

4

私の利点はDockerfileにあり、すぐCMD [ "sh", "-c", "service ssh start; bash"]には終了しないシェルを開始してから実行しdocker run -dit image_nameます。これにより、(ssh)サービスとコンテナーが稼働します。


1

read最後にshell文を追加しました。これにより、コンテナーのメインプロセス(起動シェルスクリプト)が実行され続けます。



1

コンテナーからDockerfileを確認する場合(例:fballiano / magento2-apache-php)

彼のファイルの最後に次のコマンドを追加しているのがわかります。寝る1; 終わった

さて、私がお勧めするのは、これを行うことです

docker container ls --all | grep 127

次に、Dockerイメージにエラーがあるかどうか、0で終了するかどうかを確認します。おそらく、永遠にスリープするこれらのコマンドの1つが必要です。


0

Dockerをすぐに終了させる方法はたくさんあります。私にとって、それは私の問題でしたDockerfile。そのファイルにバグがありました。私が持っていたENTRYPOINT ["dotnet", "M4Movie_Api.dll]の代わりに、ENTRYPOINT ["dotnet", "M4Movie_Api.dll"]。ご覧のとおり、最後に1つの引用符( ")がありませんでした。

問題を分析するために、私は自分のコンテナーを開始し、すぐにコンテナーを接続して、正確な問題が何であるかを確認できるようにしました。

C:\SVenu\M4Movie\Api\Api>docker start 4ea373efa21b


C:\SVenu\M4Movie\Api\Api>docker attach 4ea373efa21b

ここで、4ea373efa21bは私のコンテナーIDです。これは私を実際の問題に駆り立てます。

ここに画像の説明を入力してください

問題を見つけた後、私は自分のコンテナーを再度ビルド、復元、公開する必要がありました。


0

重複から来ているので、メインワークロードをバックグラウンドジョブとして実行するという非常に一般的なアンチパターンに対処し、Dockerが終了する理由を疑問視する答えはここにはありません。

簡単に言えば、

my-main-thing &

次に、を取り出して&ジョブをフォアグラウンドで実行するか、または

wait

スクリプトの最後で、すべてのバックグラウンドジョブを待機します。

その後、メインのワークロードが終了しても終了します。これをwhile trueループで実行して、強制的に再起動させます。

while true; do
    my-main-thing &
    other things which need to happen while the main workload runs in the background
    maybe if you have such things
    wait
done

(の書き方にも注意while trueしてください。のように、while [ true ]またはwhile [ 1 ]偶然に偶然に機能するようなばかげたことを見るのは一般的ですが、作者がおそらく彼らが意味するはずだと想像したことを意味するものではありません。)


0

バックグラウンドでデーモンとして実行したままにするには、-dフラグを指定して実行する必要があります。

docker run -d -it ubuntu bash


-5

この再起動フラグを使用してコンテナを実行できます。

docker run -d --name=<some-name> -p xxxx:xxxx ... <image-name> --restart=unless-stopped

-8

イメージはLinuxであるため、チェックする必要があるのは、コンテナで使用されているシェルスクリプトにUNIXの行末があることを確認することです。末尾に^ Mがある場合、ウィンドウの行末です。それらを修正する1つの方法は、/ usr / local / start-all.shでdos2unixを使用して、ウィンドウからUNIXに変換することです。対話モードでdockerを実行すると、他の問題を理解するのに役立ちます。あなたはファイル名のタイプミスか何かを持つことができます。https://en.wikipedia.org/wiki/Newlineを参照してください

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.