Как правильно обращаться с зависимостями контейнера Docker?
Я только начал изучать Docker и подумал о том, чтобы заменить инфраструктуру на основе виртуальных машин инфраструктурой Docker. Меня интересует, как бороться с зависимостями между контейнерами и как решить, когда / нужно ли перезапуск зависимого контейнера, и если да, то как минимизировать время простоя.
Чтобы быть более точным, я обнаружил такие инструменты, как fig или decking для управления контейнерами и зависимостями, поэтому (если мне повезет) я получил ориентированный ациклический граф, который сообщает мне, в каком порядке запускать или удалять контейнеры. Например, контейнер mongodb должен запускаться до контейнера веб-сервера и т. Д.
Поэтому, если я обновлю MongoDB или изменим какой-либо параметр, я думаю, что мне следует также отключить веб-сервер, потому что он не очень хорошо справляется с отсутствием базы данных. В этом случае, как я могу минимизировать время простоя, вызванное выключением и перезапуском контейнеров, включая повторное развертывание веб-приложения Jetty и т. Д.?
Но затем, если я просто обновлю свой SMTP-сервер (от которого более или менее зависят все другие контейнеры), я не хочу, чтобы это инициировало перезапуск всей моей контейнерной инфраструктуры. Итак, после перезапуска контейнера почтового сервера смогут ли другие контейнеры по-прежнему достигать ранее связанных портов?
Как вы справляетесь с этой ситуацией? Нужно ли / возможно ли добавить контейнер-посол ABC_amb для каждого контейнера ABC, который никогда не будет отключаться и удерживать соединения во время перезапуска ABC и т. Д.?
1 ответ
Поэтому я думаю, что в первую очередь я разделю зависимости между контейнерами на "hard" и "soft".
"Жесткая зависимость" означает, что B настолько зависит от A, что, если A перезапускается, B также должен быть перезапущен. (Возможно, потому что есть сетевое соединение, которое зависит от состояния B во время загрузки.) В этом случае я перезапущу контейнеры с учетом зависимости: выключите B, затем A, затем запустите A и, наконец, B. что рис и настил может сделать очень хорошо.
"Мягкая зависимость" означает, что B использует сервисы от A, но не настолько, чтобы при перезапуске A требовался перезапуск B. (Типичный вариант использования - веб-прокси на B для веб-приложения на A.) В этом случае я только перезапущу A и продолжу работу B.
Для мягких зависимостей я не могу использовать Docker --link
параметр, потому что после перезагрузки A DNS-имя A, известное B, будет указывать на никуда (IP-адреса меняются при перезапуске контейнера). Поэтому я буду использовать serf для регистрации и отмены регистрации A после загрузки / перед выключением и буду использовать обработчик событий serf для запуска изменения конфигурации на B, т. Е. Обновлять IP-адрес A в файлах конфигурации и перезагружать службы. ( Это сообщение в блоге дает представление о том, как это работает, но имейте в виду, что их настройки отличаются от моих.)
Однако, чтобы избежать необходимости делать это на каждом хосте, я буду использовать HA-прокси-сервер с включенным сервоприводом, который функционирует как посол между A и B. B будет связан с этим прокси с помощью --link
, так что программное обеспечение, работающее на B, не должно ничего знать о serf, но вместо этого может полагаться на DNS для соединения с послом, который прокси-соединение с A.
A (webapp) <--[soft]-- A_ambassador (haproxy) <--[hard]-- B (nginx)
Это выглядит как выполнимый подход, чтобы контейнер работал, пока (мягкий) зависимый контейнер может перезапуститься. Приятным побочным эффектом является то, что (если сценарии обработчика событий написаны хорошо), HAproxy может работать как фактический балансировщик нагрузки, если существует несколько экземпляров A.
Открытые вопросы:
- Как HAproxy может удерживать соединения, пока прокси-служба не работает?
- В некоторых случаях B также придется перезагрузить (скажем, пароль, необходимый для подключения к A, изменился). Или A_amb Ambassador и B должны быть перезапущены (скажем, изменился порт, используемый A). Как выявлять эти случаи и правильно с ними бороться?
- Затраты на добавление одного дополнительного экземпляра HAproxy для каждой службы незначительны? Есть ли более легкое решение?