Почему контейнер докера выходит сразу
Я запускаю контейнер в фоновом режиме, используя
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