Почему контейнер докера выходит сразу

Я запускаю контейнер в фоновом режиме, используя

 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

Контейнер-докер заканчивается, когда заканчивается его основной процесс.

В этом случае он выйдет, когда закончится ваш start-all.sh script. Я не знаю достаточно о хауопе, чтобы рассказать вам, как это сделать в этом случае, но вам нужно либо оставить что-то на переднем плане, либо использовать диспетчер процессов, такой как runit или supervisord для запуска процессов.

Я думаю, вы должны ошибаться в этом, если не укажете -d; он должен иметь точно такой же эффект. Я подозреваю, что вы запустили его с немного другой командой или с помощью -it, который изменит ситуацию.

Простым решением может быть добавить что-то вроде:

while true; do sleep 1000; done

до конца script. Мне это не нравится, так как script должен действительно контролировать процессы, которые он запускал.

(я должен сказать, что я украл этот код из https://github.com/sequenceiq/hadoop-docker/blob/master/bootstrap.sh)

Ответ 2

Это помогло мне:

docker run -dit ubuntu

После этого я проверил процессы, запущенные с использованием:

docker ps -a

Для прикрепления контейнера

docker attach CONTAINER_NAME

СОВЕТ: Для выхода без остановки типа контейнера: ^P^Q

Ответ 3

Я хотел бы расширить или осмелиться сказать, улучшить ответ, упомянутый camposer

При запуске

docker run -dit ubuntu

вы в основном используете контейнер в фоновом режиме в интерактивном режиме.

Когда вы прикрепляете и выходите из контейнера с помощью CTRL + D (наиболее распространенный способ сделать это), вы останавливаете контейнер, потому что вы просто убили основной процесс, с которого вы начали свой контейнер с указанной выше командой.

Используя уже запущенный контейнер, я бы просто разблокировал еще один процесс bash и получил псевдо TTY, выполнив:

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

Ответ 4

всякий раз, когда я хочу, чтобы контейнер оставался после завершения выполнения script, я добавляю

&& tail -f /dev/null

в конце команды. Поэтому это должно быть:

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

Ответ 5

Хорошим подходом было бы запустить ваши процессы и службы, выполняющие их в фоновом режиме, и использовать команду 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

Ответ 6

Почему Docker контейнер выходит немедленно?

Если вы хотите заставить изображение зависать (для того, чтобы что-то отладить или проверить состояние файловой системы), вы можете переопределить точку входа, чтобы изменить его на оболочку:

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

Ответ 7

Моя пракция находится в файле Dockerfile, запускает оболочку, которая не будет немедленно выходить CMD [ "sh", "-c", "service ssh start; bash"], а затем запустите docker run -dit image_name. Таким образом, служба (ssh) запущена.

Ответ 8

Добавьте это в конец Dockerfile:

CMD tail -f /dev/null

Пример файла Docker:

FROM ubuntu:16.04

# other commands

CMD tail -f /dev/null

Ссылка

Ответ 9

Добавление

exec "$ @"

в конце моего сценария оболочки было мое исправление!

Ответ 10

Если вы проверяете Dockerfile из контейнеров, например, fballiano/magento2-apache-php

вы увидите, что в конце своего файла он добавляет следующую команду: while true; спать 1; сделанный

Теперь, что я рекомендую, это то, что вы делаете это

docker container ls --all | grep 127

Затем вы увидите, если в вашем образе докера произошла ошибка, если он завершается с 0, то, вероятно, ему нужна одна из этих команд, которая будет спать вечно.

Ответ 11

Существует множество возможных способов немедленного выхода из докера. Для меня это была проблема с моим Dockerfile. В этом файле была ошибка. У меня было ENTRYPOINT ["dotnet", "M4Movie_Api.dll] вместо ENTRYPOINT ["dotnet", "M4Movie_Api.dll"]. Как вы можете видеть, я пропустил одну цитату (") в конце.

Чтобы проанализировать проблему, я запустил свой контейнер и быстро прикрепил свой контейнер, чтобы понять, в чем именно заключалась проблема.

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


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

Где 4ea373efa21b - мой идентификатор контейнера. Это сводит меня к актуальной проблеме.

enter image description here

После обнаружения проблемы мне пришлось снова собирать, восстанавливать, публиковать свой контейнер.

Ответ 12

Вы можете запустить контейнер, используя этот флаг перезапуска.

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

Ответ 13

Поскольку изображение представляет собой linux, нужно проверить, что любые сценарии оболочки, используемые в контейнере, имеют окончание строк unix. Если в конце у них есть ^ M, то они являются окончаниями окон. Один из способов исправить их - с dos2unix на /usr/local/start -all.sh, чтобы преобразовать их из окон в unix. Запуск докера в интерактивном режиме может помочь выяснить другие проблемы. У вас может быть опечатка имени файла или что-то в этом роде. см. https://en.wikipedia.org/wiki/Newline