Проблемы с перезапуском контейнеров
Я не уверен, правильно ли я понял упомянутые проблемы с перезапуском контейнеров. Таким образом, ниже я попытаюсь сосредоточиться на потенциальных проблемах, которые я вижу из сценария и сообщений об ошибках:
При запуске контейнеров без --rm
они останутся на месте после остановки. Если после этого попытаться run
выполнить контейнер с такими же отображениями портов или с тем же именем (оба случая здесь!), То это завершится неудачей из-за того, что контейнер уже существует. Фактически, ни один контейнер не будет запущен в процессе. Чтобы решить эту проблему, нужно либо заново создавать контейнеры (и сохранять все важные состояния вне контейнеров), либо обнаруживать существующий контейнер и запускать его, если он существует. С именами это может быть так же просто, как сделать:
if ! docker start hadoop-master; then
docker run -itd \
--net=hadoop \
-p 50070:50070 \
-p 8088:8088 \
-p 7077:7077 \
-p 16010:16010 \
--name hadoop-master \
--hostname hadoop-master \
spark-hadoop:latest &> /dev/null
fi
и аналогично для других записей. Обратите внимание, что я не понимаю, почему можно использовать комбинацию -itd
(интерактивно, назначить TTY, но перейти в фоновый режим) для такого контейнера услуг, как это? Я бы порекомендовал использовать только -d
здесь?
Другие общие рекомендации по написанию сценариев: Предпочитайте bash -e
(заставляет скрипт останавливаться на необработанных ошибках).
Docker-Compose вместо StartupСценарии
В вопросе есть некоторые сомнения относительно того, следует ли использовать docker-compose
или предпочитать сценарий запуска. С моей точки зрения, наиболее важными являются следующие различия:
Сценарии хороши с точки зрения гибкости: когда есть вещи, которые необходимо обнаружить из среды, которые выходят за пределы переменных среды, сценарииобеспечить необходимую гибкость для выполнения команд и быть зависимым от окружающей среды. Кто-то может возразить, что это частично противоречит духу изоляции контейнеров, чтобы зависеть от среды, подобной этой, но многие среды Docker используются для целей тестирования, где это не является главной задачей.
docker-compose
обеспечивает несколько явных преимуществ "из коробки". Существуют команды up
и down
(и даже радикальные, такие как down -v --rmi all
), которые позволяют быстро создавать и разрушать среды. При написании сценариев необходимо реализовывать все эти вещи отдельно, что часто приводит к менее полным решениям. Часто упускаемое из виду преимущество также связано с переносимостью: docker-compose
существует и для Windows. Еще одна интересная особенность (хотя и не такая «простая», как кажется) - это возможность развертывать файлы docker-compose.yml
в кластерах Docker. Наконец, docker-compose
также обеспечивает некоторую дополнительную изоляцию (например, все контейнеры становятся частью сети, специально созданной для этого экземпляра docker-compose
по умолчанию)
От сценария запуска до Docker-Compose
Имеющийся начальный скрипт уже в хорошей форме, чтобы рассмотреть возможность перехода к файлу docker-compose.yml
. Основная идея состоит в том, чтобы определить одну service
на docker run
инструкцию и преобразовать аргументы командной строки в их соответствующие docker-compose.yml
имена. Документация охватывает опции довольно тщательно.
Идея может быть следующей:
version: "3.2"
services:
hadoop-master:
image: spark-hadoop:latest
ports:
- 50070:50070
- 8088:8088
- 7077:7077
- 16010:16010
hadoop-slave1:
image: spark-hadoop:latest
ports:
- 8041:8042
hadoop-slave2:
image: spark-hadoop:latest
ports:
- 8042:8042
hadoop-slave2:
image: spark-hadoop:latest
ports:
- 8043:8042
Кстати. Я не смог протестировать файл docker-compose.yml
, так как изображение spark-hadoop:latest
, по-видимому, недоступно через docker pull
:
# docker pull spark-hadoop:latest
Error response from daemon: pull access denied for spark-hadoop, repository does not exist or may require 'docker login'
Но приведенного выше файла может быть достаточно, чтобы получить представление.