Dlaczego zaleca się uruchomienie tylko jednego procesu w kontenerze?

79

W wielu postach na blogu i w ogólnej opinii istnieje powiedzenie „jeden proces na kontener”.

Dlaczego ta reguła istnieje? Dlaczego nie uruchomić ntp, nginx, uwsgi i innych procesów w jednym kontenerze, który musi mieć wszystkie procesy do działania?

posty na blogu wspominające o tej regule:

Jewgienij
źródło
Ale - czy dobrze byłoby mieć bardzo „gruby” kontener z dziesiątkami procesów, aby wprowadzić na rynek i działać serwer korporacyjny, który wciąż nie może mieć Dockera?
Peter
@ J.Doe prawdopodobnie nie będzie w porządku. kontenery różnią się od maszyn wirtualnych, istnieje wiele drobnych problemów nawet w przypadku małej aplikacji - w przypadku wdrożenia w przedsiębiorstwie będzie to projekt dwuletni, w którym wszystko będzie działać w kontenerze.
Evgeny,

Odpowiedzi:

65

Zapomnijmy na chwilę o argumentach architektonicznych i filozoficznych wysokiego poziomu. Chociaż mogą występować pewne przypadki skrajne, w których wiele funkcji w jednym kontenerze może mieć sens, istnieją bardzo praktyczne powody, dla których warto rozważyć zastosowanie zasady „jedna funkcja na kontener”:

  • Skalowanie kontenerów w poziomie jest znacznie łatwiejsze, jeśli kontener jest izolowany do jednej funkcji. Potrzebujesz innego kontenera Apache? Zakręć jeden gdzie indziej. Jednak jeśli mój kontener Apache ma również DB, cron i inne elementy, to komplikuje to wszystko.
  • Posiadanie jednej funkcji na pojemnik pozwala na łatwe ponowne wykorzystanie pojemnika do innych projektów lub celów.
  • To sprawia, że ​​jest bardziej przenośny i przewidywalny dla deweloperów, którzy ściągają komponenty z produkcji, aby rozwiązywać problemy lokalnie, a nie całe środowisko aplikacji.
  • Patchowanie / aktualizacje (zarówno systemu operacyjnego, jak i aplikacji) można wykonywać w bardziej izolowany i kontrolowany sposób. Żonglowanie wieloma drobiazgami w kontenerze nie tylko zapewnia większe obrazy, ale także łączy te elementy razem. Dlaczego trzeba zamykać aplikacje X i Y tylko w celu aktualizacji Z?
    • Powyższe dotyczy również wdrożeń i wycofań kodu.
  • Podział funkcji na wiele kontenerów zapewnia większą elastyczność z punktu widzenia bezpieczeństwa i izolacji. Możesz chcieć (lub wymagać), aby usługi były izolowane na poziomie sieci - fizycznie lub w sieciach nakładkowych - w celu utrzymania silnej pozycji bezpieczeństwa lub zgodności z takimi rzeczami, jak PCI.
  • Inne drobniejsze czynniki, takie jak radzenie sobie ze standardowym wyjściem / stderr i wysyłanie dzienników do dziennika kontenera, utrzymywanie kontenerów tak efemerycznych, jak to możliwe itp.

Zauważ, że mówię o funkcji, a nie przetwarzaniu. Ten język jest przestarzały. Oficjalna dokumentacja doker został odsunięty od powiedzenia „jeden proces” zamiast polecenia „jeden” za troskę pojemniku.

Jon
źródło
1
Wydaje się jednak, że argument niskiego poziomu przeciwko wątkom pasuje tutaj ... web.stanford.edu/~ouster/cgi-bin/papers/threads.pdf
jeffmcneill
Świetna, kompleksowa odpowiedź!
Rob Wells
Czy idea, że ​​pytanie tak naprawdę nie oznaczało „procesu” w sensie systemu operacyjnego - że doker i powiązane pisma używają innej terminologii, która została teraz wyjaśniona poprzez przejście do słowa „funkcja”? Ponieważ w przeciwnym razie, chociaż potwierdzam, że jest to odpowiedź zaakceptowana i najwyżej oceniona, nie sądzę, aby odpowiadała na zadane pytanie.
Tom
27

Po zabiciu kontenera „dwóch procesów” kilka dni temu pojawiły się dla mnie pewne problemy, które spowodowały, że użyłem dwóch kontenerów zamiast skryptu Pythona, który rozpoczął dwa procesy:

  1. Docker dobrze rozpoznaje uszkodzone pojemniki. Nie można tego zrobić, gdy główny proces wygląda dobrze, ale jakiś inny proces umarł straszliwą śmiercią. Jasne, możesz monitorować swój proces ręcznie, ale po co to reimplementować?
  2. dzienniki dokowane stają się o wiele mniej przydatne, gdy wiele procesów wyrzuca swoje dzienniki do konsoli. Znów możesz zapisać nazwę procesu w dziennikach, ale doktor też może to zrobić.
  3. Testowanie i rozumowanie kontenera staje się znacznie trudniejsze.
Christian Sauer
źródło
To powinna być zaakceptowana odpowiedź.
ClintM,
Zgoda. Podczas gdy istnieją inne odpowiedzi z kilkoma świetnymi punktami, kluczowym punktem jest obsługa dokerów PID 1.
Brett Wagner
13

Zalecenie wynika z celu i projektu wirtualizacji na poziomie systemu operacyjnego

Kontenery zostały zaprojektowane tak, aby odizolować proces dla innych, dając mu własną przestrzeń użytkownika i system plików.
Jest to logiczna ewolucja chrootzapewniająca izolowany system plików. Kolejnym krokiem było odizolowanie procesów od innych, aby uniknąć nadpisywania pamięci i umożliwienie korzystania z tego samego zasobu (np. Port 8080 TCP) z wielu procesów bez konfliktów.

Zainteresowanie pojemnikiem to spakowanie potrzebnej biblioteki do procesu bez martwienia się o konflikty wersji. Jeśli uruchamiasz wiele procesów wymagających dwóch wersji tej samej biblioteki w tej samej przestrzeni użytkownika i systemie plików, musiałbyś dostosować przynajmniej LDPATH dla każdego procesu, aby najpierw znaleźć właściwą bibliotekę, a niektórych bibliotek nie można zmienić w ten sposób, ponieważ ich ścieżka jest zakodowana na stałe w pliku wykonywalnym w czasie kompilacji, zobacz to pytanie SO, aby uzyskać więcej szczegółów.
Na poziomie sieci musisz skonfigurować każdy proces, aby uniknąć używania tych samych portów.

Uruchamianie wielu procesów w tym samym kontenerze wymaga pewnych drobnych poprawek, a na koniec pokonaj cel izolacji, jeśli możesz uruchamiać wiele procesów w tej samej przestrzeni użytkownika, współużytkując ten sam system plików i zasoby sieciowe, to dlaczego nie uruchomić ich na samym hoście?

Oto niewyczerpująca lista ciężkich poprawek / pułapek, o których mogę myśleć:

  • Obsługa dzienników

    Będąc z zamontowanym woluminem lub przeplatanym na standardowym wyjściu, przyniesie to pewne zarządzanie. Jeśli używasz zamontowanego woluminu, twój kontener powinien mieć własne „miejsce” na hoście lub dwa takie same kontenery będą walczyć o ten sam zasób. Podczas przeplatania na standardowe wyjście, aby z docker logsniego skorzystać , może stać się koszmarem do analizy, jeśli źródeł nie można łatwo zidentyfikować.

  • Uważaj na procesy zombie

    Jeśli jeden z twoich procesów ulegnie awarii kontenera, superwizor może nie być w stanie wyczyścić dzieci w stanie zombie, a inicjator hosta nigdy ich nie odziedziczy. Po wyczerpaniu liczby dostępnych ofert (2 ^ 22, czyli około 4 milionów), wiele rzeczy zawiedzie.

  • Rozdzielenie obaw

    Jeśli uruchomisz dwie oddzielne rzeczy, takie jak serwer apache i logstash w tym samym kontenerze, może to ułatwić obsługę logów, ale musisz wyłączyć apache, aby zaktualizować logstash. (W rzeczywistości powinieneś użyć sterownika rejestrującego Dockera). Czy będzie to wdzięczne przestanie czekać na zakończenie bieżących sesji, czy nie? Jeśli jest to pełen wdzięku przystanek, nowa wersja może zająć trochę czasu. Jeśli zabijesz, wpłyniesz na użytkowników dla nadawcy dziennika i tego należy unikać IMHO.

Wreszcie, gdy masz wiele procesów, odtwarzasz system operacyjny, a w tym przypadku wirtualizacja sprzętu brzmi bardziej zgodnie z tą potrzebą.

Tensibai
źródło
3
Uważam te argumenty za nieprzekonujące. Istnieje ogromna różnica między procesem z wieloma kontenerami a uruchomieniem na hoście. Wyjaśnienie pierwotnego zamiaru kontenerów jest dość istotne, ale tak naprawdę nie jest to istotny powód, aby unikać kontenerów wieloprocesowych. WOW, odpowiadasz „dlaczego nie” pytaniem „dlaczego tak”, co nie jest tak pomocne, jak mogłoby być. Uruchomienie wielu procesów w tym samym kontenerze może być bardzo wygodne - właśnie dlatego tak. Dlaczego nie wyjaśniono.
Assaf Lavie
1
Nie rozwodziłeś się nad poprawkami, które miałeś na myśli. I nie udowodniłeś, że to ulepszenie wymaga więcej pracy niż konfigurowanie wielu kontenerów. Weźmy konkretny przykład: często widzisz spakowane obrazy dokerów, w których nadzór uruchamia jakiś proces główny i proces pomocniczy. Jest to bardzo łatwe do skonfigurowania; prawdopodobnie równie łatwe jak oddzielanie pojemników. np. nadawca aplikacji i dziennika. Tak więc, moim zdaniem, spoczywa na tobie ciężar sporu, dlaczego tak nie jest.
Assaf Lavie
1
BTW, uważam, że istnieją uzasadnione argumenty przeciwko kontenerom wieloprocesowym, ale nie wspomniałeś o żadnym z nich. Ale w każdym razie daleki jest od jasnego cięcia. W niektórych przypadkach dopuszcza się więcej niż jeden proces. Do licha, niektóre bardzo popularne obrazy odradzają kilka podprocesów - czy to też jest złe? Mówię, że istnieją kompromisy, a twoja odpowiedź maluje jednostronny obraz pozbawiony niuansów i szczegółów.
Assaf Lavie
1
ciekawe ... Wygląda na to, że mamy podobne (identyczne) zdanie na ten temat. Może powinieneś po prostu zignorować to w tym przypadku, ponieważ pochodziło od kogoś, kto chciał zdobyć odznakę Krytyczną ... i postanowił nadużyć twojej odpowiedzi, aby zdobyć tę odznakę ...
Pierre.Vriens
1
Nie spieszę się do konkluzji ... Po prostu polecam zignorować to. Ale „ty” nie może zmienić mojego zdania na to, co widziałem na własne oczy, kto jest anonimowym zwolennikiem twojej odpowiedzi. W każdym razie czas ruszyć dalej ...
Pierre.Vriens
6

Jak w większości przypadków, nie jest to wszystko albo nic. Wytyczne dotyczące „jednego procesu na pojemnik” wynikają z idei, że pojemniki powinny służyć odrębnemu celowi. Na przykład, pojemnik nie powinien być zarówno aplikację internetową i serwer Redis.

Są przypadki, w których sensowne jest uruchamianie wielu procesów w jednym kontenerze, o ile oba procesy obsługują jedną modułową funkcję.

Dave Swersky
źródło
2

Proces, który nazywam tutaj usługą, 1 usługa kontenera ~ 1 , jeśli którakolwiek z moich usług nie powiedzie się, wtedy rozkręcę tylko ten kontener i po kilku sekundach wszystko znów będzie działać. Tak więc nie będzie żadnych zależności między usługami. Najlepszą praktyką jest utrzymywanie rozmiaru kontenera mniejszego niż 200 MB i maksymalnie 500 MB (wyjątek od natywnych kontenerów systemu Windows to więcej niż 2 GB), w przeciwnym razie będzie podobny do maszyny wirtualnej, ale nie do końca, ale wystarczająca wydajność. Weź również pod uwagę kilka parametrów, takich jak skalowanie, w jaki sposób mogę zwiększyć odporność moich usług, automatyczne wdrażanie itp.

A to, jak chcesz, tworzyć wzorce architektoniczne, takie jak mikrousługa w środowisku Polygot, przy użyciu technologii kontenerów, która najlepiej pasuje do Twojego środowiska i zautomatyzuje te rzeczy za Ciebie.

mohan08p
źródło