Во многих блогах и общем мнении есть поговорка, которая гласит: «один процесс на контейнер».
Почему существует это правило? Почему бы не запустить ntp, nginx, uwsgi и другие процессы в одном контейнере, в котором должны работать все процессы?
сообщения в блоге, упоминающие это правило:
- «Один процесс на контейнер - это рекомендуемый шаблон проектирования для приложений Docker».
- «Docker предназначен только для создания контейнеров с одним процессом или с одним сервисом».
- «лучше использовать один процесс на контейнер»
- «Запустить один сервис как контейнер»
- «Один процесс на контейнер»
- «один процесс на контейнер»
docker
containers
Евгений
источник
источник
Ответы:
Давайте на мгновение забудем архитектурные и философские аргументы высокого уровня. Хотя могут быть некоторые крайние случаи, когда несколько функций в одном контейнере могут иметь смысл, есть очень практические причины, по которым вам может потребоваться следовать принципу «одна функция на контейнер»:
Обратите внимание, что я говорю функция, а не процесс. Этот язык устарел. Официальная докерская документация перешла от слов «один процесс» к рекомендациям «один вопрос» для каждого контейнера.
источник
Несколько дней назад, убив контейнер с «двумя процессами», я столкнулся с некоторыми болевыми точками, из-за которых мне пришлось использовать два контейнера вместо сценария Python, который запускал два процесса:
источник
Рекомендация исходит из цели и дизайна виртуализации на уровне операционной системы.
Контейнеры были разработаны, чтобы изолировать процесс для других, предоставляя ему свое собственное пространство пользователя и файловую систему.
Это логическая эволюция,
chroot
которая заключалась в предоставлении изолированной файловой системы, следующим шагом была изоляция процессов от других, чтобы избежать перезаписи памяти и позволить использовать один и тот же ресурс (например, TCP-порт 8080) из нескольких процессов без конфликтов.Основной интерес в контейнере заключается в том, чтобы упаковать нужную библиотеку для процесса, не беспокоясь о конфликтах версий. Если вы запускаете несколько процессов, которым требуются две версии одной и той же библиотеки в одном и том же пользовательском пространстве и файловой системе, вам пришлось бы настроить как минимум LDPATH для каждого процесса, чтобы сначала найти нужную библиотеку, и некоторые библиотеки нельзя настроить таким образом, поскольку их путь жестко задан в исполняемом файле во время компиляции, см. этот вопрос SO для более подробной информации.
На уровне сети вам нужно будет настроить каждый процесс, чтобы избежать использования одних и тех же портов.
Запуск нескольких процессов в одном и том же контейнере требует серьезной настройки, и, в конце концов, победит цель изоляции, если вы можете запускать несколько процессов в одном и том же пользовательском пространстве, совместно используя один и тот же файловый ресурс и сетевые ресурсы, то почему бы не запустить их? на самом хосте?
Вот не полный список тяжелых настроек / ловушек, о которых я могу думать:
Обработка журналов
Либо с подключенным томом, либо с чередованием на stdout, это приносит некоторое управление. Если вы используете подключенный том, у вашего контейнера должно быть свое «место» на хосте, или два одинаковых контейнера будут бороться за один и тот же ресурс. Если использовать stdout для чередования,
docker logs
это может стать кошмаром для анализа, если источники не могут быть легко идентифицированы.Остерегайтесь зомби-процессов
Если один из ваших процессов потерпел крах в контейнере, супервизор не сможет очистить дочерние элементы в состоянии зомби, и хост init никогда не унаследует их. Как только вы исчерпали количество доступных pids (2 ^ 22, то есть примерно 4 миллиона), куча вещей потерпит неудачу.
Разделение интересов
Если вы запускаете две разные вещи, такие как сервер apache и logstash в одном и том же контейнере, это может упростить обработку журналов, но для обновления logstash вам необходимо отключить apache. (На самом деле, вы должны использовать драйвер ведения журнала Docker) Будет ли это изящная остановка в ожидании завершения текущих сеансов или нет? Если это изящная остановка, это может занять некоторое время и стать долгим, чтобы накатить новую версию. Если вы сделаете уничтожение, вы окажете влияние на пользователей за доставку журналов, и этого следует избегать ИМХО.
Наконец, когда у вас есть несколько процессов, вы воспроизводите ОС, и в этом случае использование аппаратной виртуализации более соответствует этой потребности.
источник
Как и в большинстве случаев, это не все или ничего. Руководство "один процесс на контейнер" основано на идее, что контейнеры должны служить определенной цели. Например, контейнер не должен быть одновременно веб-приложением и сервером Redis.
В некоторых случаях имеет смысл запускать несколько процессов в одном контейнере, если оба процесса поддерживают одну модульную функцию.
источник
Процесс, который я буду называть здесь службой, 1 контейнер ~ 1 служба , если какой-либо из моих сервисов не будет выполнен, тогда я только раскручиваю соответствующий контейнер, и через несколько секунд все снова работает. Таким образом, не будет никаких зависимостей между сервисами. Рекомендуется, чтобы размер вашего контейнера не превышал 200 МБ и не превышал 500 МБ (за исключением того, что собственные контейнеры Windows превышают 2 ГБ), в противном случае он будет аналогичен виртуальной машине, но не совсем, но производительности будет достаточно. Кроме того, примите во внимание несколько параметров, таких как масштабирование, как я могу повысить устойчивость своих служб, автоматическое развертывание и т. Д.
И это просто ваш призыв, как вам нужно сделать свои архитектурные шаблоны, такие как микро-сервис в полиготной среде, используя технологию контейнеров, которая лучше всего подходит для вашей среды и автоматизирует все для вас.
источник