Я создал базовый образ из файла Docker с именем centos + ssh. В файле Dockerfile centos + ssh я использую CMD для запуска службы ssh.
Затем я хочу создать образ, запускающий другую службу с именем rabbitmq, Dockerfile:
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 не работает, это означает, что CMD Dockerfile rabbitmq переопределяет CMD centos.
- Как CMD работает внутри образа докера?
- Если я хочу запустить несколько служб, как это сделать? Используете супервизора?
Вы правы, второй Dockerfile перезапишет
CMD
команду первого. Докер всегда будет запускать одну команду, не более того. Итак, в конце вашего Dockerfile вы можете указать одну команду для запуска. Не более.Но вы можете выполнить обе команды в одной строке:
Что вы также можете сделать, чтобы сделать ваш Dockerfile немного чище, вы можете поместить свои команды CMD в дополнительный файл:
И такой файл:
источник
&&
Техника будет работать только с неинтерактивными службами (которые могут запускаться в фоновом режиме), в противном случае будет работать только первая.Хотя я уважаю ответ qkrijger, объясняющий, как можно обойти эту проблему, я думаю, что мы можем узнать гораздо больше о том, что здесь происходит ...
Чтобы на самом деле ответить на ваш вопрос « почему » ... Я думаю, вам было бы полезно понять, как
docker stop
работает команда, и что все процессы должны завершаться аккуратно, чтобы предотвратить проблемы, когда вы пытаетесь их перезапустить (повреждение файлов и т. Д.).Проблема: Что делать , если докер сделал запуск SSH от его команды и начал RabbitMQ из файла Докер? « Команда docker stop пытается сначала остановить работающий контейнер, отправив сигнал SIGTERM корневому процессу (PID 1) в контейнере. » Какой процесс отслеживает докеры как PID 1, который получит SIGTERM? Будет ли это SSH или Rabbit ?? «Согласно модели процессов Unix, процесс init - PID 1 - наследует все потерянные дочерние процессы и должен их получить. Большинство контейнеров Docker не имеют процесса инициализации, который делает это правильно, и в результате их контейнеры заполняются зомби-процессы с течением времени ".
Ответ: Docker просто принимает этот последний CMD как тот, который будет запущен как корневой процесс с PID 1 и получит SIGTERM от
docker stop
.Предлагаемое решение: вы должны использовать (или создать) базовый образ, специально созданный для запуска более чем одной службы, например phusion / baseimage.
Важно отметить, что tini существует именно по этой причине, и начиная с Docker 1.13 и выше, tini официально является частью Docker, что говорит нам, что выполнение более одного процесса в Docker ДЕЙСТВИТЕЛЬНО ... поэтому даже если кто-то утверждает, что быть более опытным в отношении Docker и настаивать на том, что вы абсурдны, думая об этом, знайте, что это не так. Для этого есть вполне допустимые ситуации.
Хорошо знать:
источник
Официальный докер-ответ на запуск нескольких служб в контейнере .
Он объясняет, как это можно сделать с помощью системы инициализации (systemd, sysvinit, upstart), скрипта (
CMD ./my_wrapper_script.sh
) или подобного супервизораsupervisord
.&&
Обходной путь может работать только за услуги , которые начинаются в фоновом режиме (демоны) , или что будет быстро выполняться без взаимодействия и отпустите приглашение. Это делается с помощью интерактивной службы (которая сохраняет подсказку), и запускается только первая служба.источник
Чтобы понять, почему CMD предназначен для запуска только одной службы на контейнер, давайте просто поймем, что произойдет, если вторичные серверы, запущенные в одном контейнере, будут не тривиальными / вспомогательными, а «основными» (например, хранилище, связанное с приложением внешнего интерфейса). Во-первых, это нарушит несколько важных функций контейнеризации, таких как горизонтальное (автоматическое) масштабирование и перепланирование между узлами, оба из которых предполагают наличие только одного приложения (источника загрузки ЦП) на контейнер. Затем возникает проблема уязвимостей - большее количество серверов, открытых в контейнере, означает более частое исправление CVE ...
Итак, давайте признаем, что это «подталкивание» разработчиков Docker (и Kubernetes / Openshift) к передовым методам, и нам не следует изобретать обходные пути (SSH не нужен - мы
docker exec / kubectl exec / oc rsh
разработали его замену)./devops/447/why-it-is-recommended-to-run-only-one-process-in-a-container
источник