为什么docker容器会立即退出

时间:2015-01-29 10:30:21

标签: docker

我使用

在后台运行一个容器
 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

17 个答案:

答案 0 :(得分:162)

这对我有用:

docker run -dit ubuntu

之后,我使用以下方法检查了运行的进程:

docker ps -a

再次附加容器

docker attach CONTAINER_NAME

提示:要在不停止容器类型的情况下退出:^P^Q

答案 1 :(得分:96)

当主进程完成时,docker容器退出。

在这种情况下,当start-all.sh脚本结束时它将退出。我不太了解hadoop在这种情况下告诉你如何做到这一点,但是你需要在前台运行一些东西或者使用一个进程管理器(如runit或supervisord)来运行这些进程。

如果你没有指定-d,我认为你必须弄错它。它应该具有完全相同的效果。我怀疑你使用稍微不同的命令或使用-it来启动它会改变一些事情。

一个简单的解决方案可能是添加类似的内容:

while true; do sleep 1000; done

到脚本的末尾。我不喜欢这样,因为脚本应该真正监视它启动的过程。

(我应该说我偷了https://github.com/sequenceiq/hadoop-docker/blob/master/bootstrap.sh的代码)

答案 2 :(得分:50)

我想延伸或敢说,改进camposer提到的答案

运行时

docker run -dit ubuntu

您基本上是以交互模式在后台运行容器。

当您通过CTRL + D(最常见的方式)连接和退出容器时,您停止容器,因为您刚刚使用上述命令杀死了启动容器的主进程。

利用已经运行的容器,我只需要分叉另一个bash进程并通过运行获取伪TTY:

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

答案 3 :(得分:19)

每当我想要一个容器在完成脚本执行后熬夜我就添加

&& tail -f /dev/null

在命令结束时。所以它应该是:

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

答案 4 :(得分:14)

一个很好的方法是启动在后台运行它们的进程和服务,并在脚本末尾使用wait [n ...]命令。在bash中,wait命令强制当前进程:

  

等待每个指定的进程并返回其终止状态。如果未给出n,则等待所有当前活动的子进程,并且返回状态为零。

我从SébastienPujadas'start script for his elk build获得了这个想法。

从原始问题开始,你的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 :(得分:4)

  

为什么Docker容器会立即退出?

如果要强制映像徘徊(以便调试某些内容或检查文件系统的状态),可以覆盖入口点以将其更改为shell:

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

答案 6 :(得分:3)

如果你只需要运行一个容器而不退出,直接运行

docker run -dit --name MY_CONTAINER MY_IMAGE:latest

然后

docker exec -it MY_CONTAINER /bin/bash

并且您将处于容器的 bash shell 中,并且不应退出。

或者如果退出发生在 docker-compose 期间,使用

command: bash -c "MY_COMMAND --wait"

答案 7 :(得分:3)

您需要使用-d标志运行它,以使其在后台作为守护程序运行。

docker run -d -it ubuntu bash

答案 8 :(得分:3)

我的实践是在Dockerfile中启动一个shell,它不会立即退出CMD [ "sh", "-c", "service ssh start; bash"],然后运行docker run -dit image_name。这样(ssh)服务和容器就会运行起来。

答案 9 :(得分:2)

添加

exec&#34; $ @&#34;

我的shell脚本末尾的

是我的修复!

答案 10 :(得分:1)

例如,如果您从容器中检查Dockerfile, fballiano / magento2-apache-php

您会看到他在文件末尾添加了以下命令: 虽然是真的睡1完成

现在,我建议您这样做

docker container ls --all | grep 127

然后,您将看到docker映像是否有错误,如果以0退出,那么它可能需要这些将永远休眠的命令之一。

答案 11 :(得分:0)

有许多方法可以让docker立即退出。对我来说,这是Dockerfile的问题。该文件中存在错误。我有ENTRYPOINT ["dotnet", "M4Movie_Api.dll]而不是ENTRYPOINT ["dotnet", "M4Movie_Api.dll"]。正如你所看到的那样,我最后错过了一个引号(&#34;)。

为了分析问题,我启动了我的容器并快速连接了我的容器,以便我可以看到确切的问题。

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


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

其中4ea373efa21b是我的容器ID。这让我想到了实际的问题。

enter image description here

找到问题后,我不得不再次构建,恢复,发布我的容器。

答案 12 :(得分:0)

将其添加到Dockerfile的末尾:

CMD tail -f /dev/null

示例Docker文件:

FROM ubuntu:16.04

# other commands

CMD tail -f /dev/null

Reference

答案 13 :(得分:0)

我在末尾添加了read shell语句。这样可以保持容器的主要过程-启动外壳脚本-运行。

答案 14 :(得分: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 ]之类的愚蠢的东西碰巧可以正常工作是很常见的,但这并不意味着作者可能想象的那样应该是这个意思。)

答案 15 :(得分:-2)

您可以使用此重新启动标志运行容器。

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

答案 16 :(得分:-8)

由于映像是linux,因此要检查的一件事是确保容器中使用的任何shell脚本都具有unix行结尾。如果他们最后有一个^ M,那么他们就是windows line endings。修复它们的一种方法是使用/usr/local/start-all.sh上的dos2unix将它们从windows转换为unix。以交互模式运行docker可以帮助找出其他问题。你可能有一个文件名拼写错误或其他东西。见https://en.wikipedia.org/wiki/Newline