Чому рекомендується запускати лише один процес у контейнері?


79

У багатьох публікаціях блогу та загальної думки є приказка, що йдеться про "один процес на контейнер".

Чому це правило існує? Чому б не запустити ntp, nginx, uwsgi та інші процеси в одному контейнері, у якому потрібно працювати всі процеси?

повідомлення в блозі, де згадується це правило:


Але - було б добре мати дуже "жирний" контейнер з десятками процесів для того, щоб поетапно розпочати роботу та роботу корпоративного сервера, який ще не може мати Docker?
Пітер

@ J.Doe, мабуть, це не буде добре. контейнери відрізняються від віртуальних машин, є навіть кілька невеликих проблем навіть для невеликого додатка - для розробки підприємства це буде дворічний проект, змушуючи його працювати все в контейнері.
Євгеній

Відповіді:


65

Давайте на хвилину забувати архітектурні та філософські аргументи високого рівня. Хоча можуть бути певні крайні випадки, коли декілька функцій в одному контейнері можуть мати сенс, є дуже практичні причини, чому ви можете розглянути як правило: "одна функція на контейнер":

  • Масштабування контейнерів горизонтально набагато простіше, якщо контейнер ізольований до однієї функції. Вам потрібен інший контейнер apache? Скрутіть одне кудись інше. Однак якщо в моєму контейнері apache також вбудовані мій БД, крон та інші шматки, це ускладнює справи.
  • Наявність однієї функції на контейнер дозволяє контейнеру легко використовувати його для інших проектів чи цілей.
  • Це також робить його більш портативним і передбачуваним для розробників, щоб витягнути компонент від виробництва до усунення несправностей локально, а не цілого середовища застосування.
  • Виправлення / оновлення (як ОС, так і програми) можна проводити більш ізольованим та контрольованим чином. Жонглювання декількома бітами та бобами у вашому контейнері не тільки створює більші зображення, але й зв'язує ці компоненти разом. Чому доводиться вимикати програми X і Y просто для оновлення Z?
    • Вище також справедливо для розгортання коду та зворотних зворотів.
  • Розщеплення функцій на декілька контейнерів забезпечує більшу гнучкість з точки зору безпеки та ізоляції. Ви можете хотіти (або вимагати) послуги бути ізольованими на рівні мережі - фізично або в межах накладених мереж - для підтримки міцної позиції безпеки або дотримання таких речей, як PCI.
  • Інші більш незначні фактори, такі як робота з stdout / stderr та надсилання журналів до журналу контейнерів, зберігаючи контейнери максимально ефемерними тощо.

Зауважте, що я кажу функцію, а не обробляти. Ця мова застаріла. Офіційна документація докера відступила від того, щоб сказати "один процес", а не рекомендувати "одну занепокоєння" на контейнер.


1
Але, здається, аргумент низького рівня проти ниток підходить тут ... web.stanford.edu/~ouster/cgi-bin/papers/threads.pdf
jeffmcneill

Чудова, вичерпна відповідь!
Роб Веллс

Чи ідея про те, що питання насправді не означає «процес» в сенсі ОС - що докер та пов'язані з ним записи використовували іншу термінологію, яка зараз була з'ясована при переході на слово «функція»? Бо в іншому випадку, хоча я визнаю, що це прийнята і найвища відповідь, я не думаю, що це відповідає на запитання, яке було задано.
Том

27

Забивши контейнер "два процеси" кілька днів тому, для мене виникли больові точки, які змусили мене використовувати два контейнери замість сценарію python, який запустив два процеси:

  1. Docker добре розпізнає розбиті контейнери. Це не може зробити, коли основний процес виглядає нормально, але якийсь інший процес загинув жахливою смертю. Звичайно, ви можете стежити за своїм процесом вручну, але навіщо це повторно виконувати?
  2. docker logs стає набагато менш корисним, коли кілька процесів виводять свої журнали до консолі. Знову ж таки, ви можете записати ім'я процесу в журнали, але і докер може це зробити.
  3. Тестування та міркування щодо контейнера набагато складніше.

Це має бути прийнятою відповіддю.
ClintM

Домовились. Хоча є деякі інші відповіді з великими моментами, ключовим моментом є те, що докер маніпулює PID 1.
Бретт Вагнер

13

Рекомендація випливає з мети та розробки віртуалізації на рівні Операційної системи

Контейнери були розроблені для того, щоб ізолювати процес для інших, надаючи йому власний простір користувачів та файлову систему.
Це логічна еволюція, chrootяка передбачала надання ізольованої файлової системи, наступним кроком було виділення процесів від інших, щоб уникнути перезапису пам'яті та дозволяти використовувати один і той же ресурс (наприклад, порт 8080 TCP) з декількох процесів без конфліктів.

Основний інтерес контейнера - це упакувати необхідну бібліотеку для процесу, не турбуючись про конфлікти версій. Якщо ви запускаєте декілька процесів, які потребують двох версій однієї бібліотеки в одній і тій же просторі користувачів і файлової системи, вам доведеться налаштувати принаймні LDPATH для кожного процесу, щоб спочатку була знайдена належна бібліотека, і деякі бібліотеки не можна підкоригувати таким чином, оскільки їх шлях важко закодований у виконуваному файлі під час компіляції, дивіться це запитання щодо більш детальної інформації.
На рівні мережі вам доведеться налаштувати кожен процес, щоб уникнути використання одних і тих же портів.

Запуск декількох процесів в одному контейнері вимагає серйозних налаштувань і в кінці дня перемогти мету ізоляції, якщо ви добре запускаєте кілька процесів в одному і тому ж просторі користувачів, обмінюючись одним файлом та мережевими ресурсами, то чому б не запустити їх на самого господаря?

Ось не вичерпний список важких налаштувань / підводних каменів, про які я можу придумати:

  • Обробка колод

    Будь то з встановленим томом або переплетеним на stdout це приносить деяке управління. Якщо ви використовуєте змонтований об'єм, ваш контейнер повинен мати власне "місце" на хості або два ж контейнери будуть боротися за один і той же ресурс. Якщо переплутати stdout, щоб скористатися ним, docker logsце може стати кошмаром для аналізу, якщо джерела неможливо легко визначити.

  • Остерігайтеся зомбі-процесів

    Якщо один із ваших процесів в результаті аварії контейнера, контрольний орган може не мати змоги очистити дітей у стані зомбі, і хост init ніколи їх не успадкує. Після того, як ви вичерпали кількість доступних підручників (2 ^ 22, тобто приблизно 4 мільйони), купу речей не вдасться.

  • Розділення проблем

    Якщо ви запускаєте дві окремі речі, наприклад, сервер apache та logstash в одному контейнері, це може полегшити обробку журналу, але вам доведеться вимкнути apache, щоб оновити logstash. (Насправді вам слід скористатися драйвером реєстрації Docker) Чи буде це витончена зупинка очікування завершення поточних сеансів чи ні? Якщо це витончена зупинка, може знадобитися колись і довго запустити нову версію. Якщо ви робите вбивство, ви впливатимете на користувачів вантажовідправника, чого слід уникати IMHO.

Нарешті, коли у вас є кілька процесів, ви відтворюєте ОС, і в цьому випадку використання апаратної віртуалізації звучить більше відповідно до цієї потреби.


3
Я вважаю ці аргументи непереконливими. Існує величезна різниця між процесом з кількома контейнерами та запуском на хості. Хоча пояснення початкового наміру контейнерів є дещо актуальним, це насправді не є переконливою причиною уникати багатопроцесорних контейнерів. IOW, ви відповідаєте "чому ні" на "чому так", що не так корисно, як могло б бути. Це може бути дуже зручно запускати кілька процесів в одному контейнері - ось чому так. Чому ні, залишається пояснити.
Ассаф Лав'є

1
Ви ще не докладно розглядали вигляд налаштувань, які мали на увазі. І ви не зробили висновок, що це налаштування - це більше робота, ніж налаштування декількох контейнерів. Візьмемо конкретний приклад: ви часто бачите упаковані зображення докера, які мають нагляд за виконанням якогось основного процесу та якогось допоміжного процесу. Це дуже просто налаштувати; Можливо, так само просто, як і розділення контейнерів. наприклад, вантажовідправник додатків та журналів. Отже, я вважаю, що з вашої сторони міркують, чому це не так.
Ассаф Лав'є

1
До речі, я вважаю, що є вагомі аргументи проти багатопроцесорних контейнерів, але ви не згадали жодного з них. Але в будь-якому випадку, це далеко не чіткий виріз. У деяких випадках цілком прийнятно допускати більше одного процесу. Чорт, деякі дуже популярні зображення породять кілька підпроцесів - це теж зло? Що я кажу - це компроміси, і ваша відповідь малює однобічну картину, у якій бракує нюансів і деталей.
Ассаф Лав'є

1
Цікаво ... Це звучить, як ми маємо подібну (однакову) думку з цього приводу. Можливо, вам слід просто проігнорувати це в цьому випадку, оскільки це було від когось, хто хотів заробити значок Критика ... і вирішив зловживати вашою відповіддю, щоб отримати цей знак ...
Pierre.Vriens

1
Я не "поспішаю" до висновку ... Я просто рекомендую вам проігнорувати це. Але "ти" не може змінити свою думку про те, що я бачив на власні очі про те, хто анонімний прихильник вашої відповіді. У будь-якому випадку, час рухатися далі ...
Pierre.Vriens

6

Як і в більшості випадків, це не все або нічого. Настанова "один процес на контейнер" випливає з ідеї, що контейнери повинні слугувати окремій меті. Наприклад, контейнер не повинен бути як веб-додатком, так і сервером Redis.

Бувають випадки, коли є сенс запускати кілька процесів в одному контейнері, якщо обидва процеси підтримують одну, модульну функцію.


2

Процес, який я викликав тут як сервіс, 1 служба ~ 1 служба , якщо будь-яка моя служба не виконана, я лише закручую відповідний контейнер і через секунди все знову починається. Отже, залежностей між службами не буде. Найкраще зберігати розмір контейнера менше 200 МБ та максимум 500 МБ (виняток становить лише вітчизняних контейнерів Windows понад 2 ГБ), інакше його буде таким же, як і віртуальна машина, не точно, але продуктивності вистачає. Крім того, врахуйте декілька параметрів, як масштабування, як я можу зробити мої послуги стійкістю, автоматичним розгортанням тощо.

І, суто, ви називаєте, як вам потрібно зробити свої архітектурні структури, такі як мікро-сервіс у поліготному середовищі, використовуючи технологію контейнерів, яка найкраще відповідає вашому середовищу та автоматизує речі для вас.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.