Подтвердить что ты не робот

Почему я не могу использовать Docker CMD несколько раз для запуска нескольких сервисов?

Я создал базовое изображение из Dockerfile с именем centos + ssh. В файле centos + ssh Dockerfile я использую CMD для запуска службы ssh.

Затем я хочу создать образ, запускающий другую службу с именем rabbitmq, файл Docker:

FROM centos+ssh
EXPOSE 22
EXPOSE 4149
CMD /opt/mq/sbin/rabbitmq-server start

Чтобы запустить контейнер rabbitmq, запустите:

docker run -d -p 222:22 -p 4149:4149 rabbitmq

но служба ssh не работает, это означает, что crbitmq Dockerfile CMD переопределяет centos CMD.

  • Как CMD работает внутри изображения докеров?
  • Если я хочу запустить несколько сервисов, как это сделать? Использование диспетчера?
4b9b3361

Ответ 1

Несмотря на то, что CMD записан в файле Docker, это действительно информация о времени выполнения. Так же, как EXPOSE, но, вопреки, например, RUN и ADD. Под этим я подразумеваю, что вы можете переопределить его позже, в расширении Dockerfile или просто в вашей команде запуска, что и есть то, что вы испытываете. Во все времена может быть только один CMD.

Если вы хотите запускать несколько служб, я бы использовал супервизор. Вы можете создать файл конфигурации супервизора для каждой службы, добавить их в каталог и запустить диспетчер с supervisord -c /etc/supervisor, чтобы указать на файл конфигурации супервизора, который загружает все ваши службы и выглядит как

[supervisord]
nodaemon=true

[include]
files = /etc/supervisor/conf.d/*.conf

Если вы хотите получить более подробную информацию, я написал здесь блог на эту тему: http://blog.trifork.com/2014/03/11/using-supervisor-with-docker-to-manage-processes-supporting-image-inheritance/

Ответ 2

Вы правы, второй файл Docker будет перезаписывать команду CMD первой. Докер всегда будет запускать одну команду, а не больше. Поэтому в конце вашего Dockerfile вы можете указать одну команду для запуска. Не более.

Но вы можете выполнять обе команды в одной строке:

FROM centos+ssh
EXPOSE 22
EXPOSE 4149
CMD service sshd start && /opt/mq/sbin/rabbitmq-server start

Что вы могли бы сделать, чтобы сделать Dockerfile немного более чистым, вы могли бы поместить ваши команды CMD в дополнительный файл:

FROM centos+ssh
EXPOSE 22
EXPOSE 4149
CMD sh /home/centos/all_your_commands.sh

И файл вроде этого:

service sshd start &
/opt/mq/sbin/rabbitmq-server start

Ответ 3

В то время как я уважаю ответ от qkrijger, объясняющий, как вы можете обойти эту проблему, я думаю, что мы можем многое узнать о том, что происходит здесь...

Чтобы ответить на ваш вопрос " почему"... Я думаю, вам было бы полезно понять, как работает команда docker stop и что все процессы должны быть отключены, чтобы предотвратить проблемы когда вы пытаетесь перезапустить их (повреждение файлов и т.д.).

Проблема: что, если docker запустил SSH из этой команды и запустил RabbitMQ из вашего файла Docker? "Команда остановки docker пытается остановить запущенный контейнер сначала, отправив сигнал SIGTERM в корневой процесс (PID 1) в контейнере." Какой процесс отслеживается докерером как PID 1, который получит SIGTERM? Будет ли это SSH или кролик? "В соответствии с моделью процесса Unix процесс init - PID 1 - наследует все осиротевшие дочерние процессы и должен пожинать их. Большинство контейнеров Docker не имеют процесса инициализации, который делает это правильно, и в результате их контейнеры со временем заполняются зомбическими процессами" .

Ответ: Docker просто берет последний CMD как один, который будет запущен как корневой процесс с PID 1 и получит SIGTERM от docker stop.

Предлагаемое решение: вы должны использовать (или создавать) базовое изображение, специально созданное для запуска более одной службы, например phusion/baseimage

Полезно знать: