Zastosowanie kontenerów

3
andrzejlisek napisał(a):

Czy kontener zapewnia wyizolowane środowisko tak, że jak wewnątrz kontenera zainstaluję wirusa, to on może co najwyżej zniszczyć zawartość kontenera, a danych systemu hosta nie ruszy?

Niestety nie. Kontener może mieć zmapowany wolumen z hosta albo jakiegoś dysku sieciowego.

Do jakich aplikacji najczęściej są używane kontenery? Destkopowe, konsolowe, webowe, może jeszcze inne?

Do backendu. Dzięki kontenerom bardzo łatwo uruchomić aplikację, zrestartować jeżeli apka padła (startuje od zera, na "czystym" systemie), zrobić upgrade no nowej wersji systemu (odpalasz nowy kontener i przekierowujesz ruch). Nie wiem czy ktoś na poważnie używa kontenerów bez orkiestracji, bo dopiero jak połączysz to z czymś jak kubernetes, osiągniesz odpowiednią skalę swojej aplikacji, zaczniesz wszystko automatyzować i traktować komponenty jak stado, w którym co jakiś czas coś może paść, a nie jak ukochane i rozpieszczone zwierzaczki domowe, to dostrzeżesz zalety. Kontenery czynią takie podejście łatwiejszym niż na VMkach czy gołym sprzęcie.

Do infry, gdyż kontener może zawierać systemy realizujące jakieś funkcje w systemie, jak load balancer, api gateway, DNS, agent metryk i logów, agenta monitorującego, runnera do systemu CI/CD. Tak opakowane systemy z łatwością wpinasz w swoją infrastrukturę. Nic nie instalujesz, po prostu deklaratywnie konfigurujesz i uruchamiasz. Oczywiście można to zrobić przy pomocy VM, ale kontener ma tą zaletę, że zazwyczaj szybciej się uruchamia, co czasami jest niezbędne.

2
andrzejlisek napisał(a):

To nie jest pytanie, co to jest kontener, jak działa i jak się konfiguruje, na to pytanie można znaleźć odpowiedź bez większego problemu.

Natomiast to jest pytanie, gdzie znajduje praktyczne zastosowanie i jaką ma przewagę nad rozwiązaniami wieloplatformowymi lub z możliwością łatwego dostosowania?

Najbardziej podstawową przewagą kontenerów nad VM, jest ich wielkość. Na tej samej maszynie odpalisz więcej kontenerów, niż VM,

Jak potrzebuję napisać program działający na wielu komputerach z różnymi systemami operacyjnymi, to skorzystam z technologii wieloplatformowej, bardzo popularną technologią jest Java. Technologii wieloplatformowej jest tak dużo, że jest w czym wybierać i zmiana Windows na Linux lub odwrotnie nie stanowi większego problemu w wielu przypadkach.

Wieloplatformowość jest skutkiem ubocznym, nie celem. Plusem jest to, że jesteś w stanie ten sam obraz kontenera, z wszystkimi ustawionymi tam zmiennymi systemowymi, konfiguracjami odpalić w wielu różnych miejscach.

Jak potrzebuję zmienić komputer, na którym pracuje program, to na nowym komputerze instaluję to, co potrzebuję i już. Jeżeli jest to dość częsta czynność, to w niektórych przypadkach da się zrobić skrypt, który uruchomiony poinstaluje i pokonfiguruje wszystko, co potrzeba. Taka sytuacja zachodzi, jak mam aplikację webową z bazą danych i chce zmienić hosting, po prostu kopiuję bazę danych do pliku, przenoszę wszystko, a na nowym hostingu instaluję serwer baz danych, wgrywam dane, i program i śmiga.

Ile zajmie ci to konfigurowanie? Albo postawienie środowiska testowego? W jaki sposób sprawisz, że to co przetestowałeś, jest dokładnie tym samym co pójdzie na produkcję? Akurat stawianie baz danych w kontenerach, to trochę bardziej złożone zagadnienie.

Podobnie, jak jest np. firma, w której na kilkudziesięciu komputerach trzeba zaisntalować i skonfigurować program.

Do tego (aplikacje desktopowe) kontenery nadają się trochę słabo.

Z tego, co czytałem, kontener to takie w dużym skrócie coś prostszego od maszyny wirtualnej (nie ma wirtualizacji całego sprzętu, jest tylko system operacyjny). Jego zaletą jest to, że chcąc przenieść z komputera na komputer, po prostu kopiuję cały kontener, podobnie, jak z maszyną wirtualną.

Tak, tylko potrzebujesz mniej tych komputerów do uruchomienia 100 kontenerów, niż potrzebowałbyś do uruchomienia 100 VM.

Patrząc po tematach na forum, kontenery to rzecz bardzo popularna (często jest mowa o Docker i Kubernetes), w takim razie zapytam: Do jakich aplikacji i gdzie znajdują zastosowanie. Chodzi głównie takie prawdziwe, np. w firmach. Nie chodzi o to, że ktoś zainstaluje sobie Dockera czy Kubernetes i się bawi, patrzy jak to działa.

Mikroserwisy. Jak masz system skłądający się z iluśtam dziesięciu usług, z których część może się skalować horyzontalnie (kilka instancji tej samej usługi), to bardzo ciężko to zrobić bez kontenerów. Druga sprawa - wygoda użycia. Potrzebujesz linuksa z Javą 11 i uruchomioną na tym twoją aqplikacją? Piszesz plik konfiguracyjny na 5 linijek, odpalasz dockera, obraz sam się pobierze z publicznego repozytorium, dockerfile ustawi to co trzeba ustawić, następnie skopiuje twoją aplikację i ją uruchomi. To jest dosłownie 5 minut roboty w takim prostym przypadku. W ramach eksperymentu, zrób prostą stronkę html, następnie zmierz sobie czas jaki zajmie ci Postawienie od zera wirtualki, na tej wirtualce serwera https://www.docker.com/blog/how-to-use-the-official-nginx-docker-image/amo działanie używając kontenera. Tutaj masz opisane jak to zrobić: https://www.docker.com/blog/how-to-use-the-official-nginx-docker-image/ Myślę, że zrozumiesz na czym polega zaleta konteneryzacji.

Instalacja różnych bibliotek, jak JRE, DotNet, system bazy danych to z jednej strony niewzdzięczna, ale niezbędna czynność, ale z drugiej strony wykonuje się od czasu do czasu, więc to nie problem.

Niby te kombajny fajne, ale od pokoleń kosimy, zbieramy i młócimy i to nie problem.

Załóżmy, że mam system Linux, a potrzebuję uruchomić aplikację w Windows. Skorzystam z prawdziwej maszyny wirtualnej w tym celu. Czy kontener też się do tego nadaje? Z tego co czytałem i rozumiem to tak i to jeszcze z lepszą wydajnością (brak wirtualizacji).

VM to obsłuży, kontener nie. W drugą stronę potencjalnie coś by się dało zrobić, ale też jest to raczej nadmierna gimnastyka. Kontener właściwie z definicji wystawia na zewnątrz jakieś tam porty i to wszystko.

Czy kontener zapewnia wyizolowane środowisko tak, że jak wewnątrz kontenera zainstaluję wirusa, to on może co najwyżej zniszczyć zawartość kontenera, a danych systemu hosta nie ruszy?

Pomijając czaasmi odkrywane podatności jest to prawda

Do jakich aplikacji najczęściej są używane kontenery? Destkopowe, konsolowe, webowe, może jeszcze inne?

Webowe. Konsolowe - jeszcze jakoś się da, desktopowe - zapomnij.

2

Tak jeszcze dodam, że czym więcej programistów pracuje nad danym projektem/systemem tym bardziej rozmywa się wiedza na temat jak postawić całość systemu, jeżeli masz zdockeryzowaną chociaż część to jest szansa na to ze nie bedziesz się jebać z tym tydzien tylko ew dzien. Np teraz mam takie zleconko żeby odtworzyć wiedzę w jednej firmie na temat jednego produktu bo maja kod ale dokumentacja to śmietnik a instrukcji jak to postawić nie ma. Dzięki kontenerom jest szansa na odtworzenie tego w rozsądnym czasie bo przynajmniej ci pojedyncze serwisy wstaja bez wiedzy na temat samego serwisu. Więc nie muszę doktoryzować się w tym konkretnym przypadku z samego webrtc i bridgy do niego a tylko szukać np jak sieciowo się to komunikuje z innymi serwisami i co trzeba ustawic (np jakie porty) aby działało.

0

Z tego, co rozumiem, kontener to bardziej sandbox niż VM, który kontaktuje się z "resztą świata" w ściśle określony sposób, czyli przede wszystkim może zapisywać lub odczytywać pliki, a także może mieć interfejsy w postaci gniazd. Nie ma bezpośredniego dostępu poprzez klawiaturę i monitor (co jest rzeczą bardzo oczywistą w przypadku zwykłych aplikacji bez kontenera), ewentualnie standardowe strumienie wejścia i wyjścia też można przekierować na gniazdo sieciowe.

Na przykład instaluję pierwszy kontener z silnikiem bazy danych. Ten kontener ma dostęp do określonego katalogu na dysku i wystawia nasłuch na określonym porcie sieciowym, przez który można połączyć się z baza danych. Potem instaluję drugi kontener, w którym tworzę aplikację z logiką biznesową. Ten drugi kontener podłącza się przez sieć lub localhost do kontenera z bazą danych, a z drugiej strony wystawia nasłuch na jakimś porcie, na którym jest REST API lub SOAP, czyli jest klientem bazy danych i serwerem HTTP. Potem instaluję trzeci kontener, na którym jest serwer HTTP, który wystawia aplikację webową, a sam kontener podłącza się do pierwszego lub drugiego kontenera przez gniazdo sieciowe.

Czy to to tak rzeczywiście jest? To by pasowało do stwierdzenia, że nie ma możliwości uruchomienia aplikacji z GIU, a aplikacje konsolowe można zorganizować w taki sposób, że kontener jest serwerem i ma prostą aplikację pośredniczącą, która przekierowuje wszystko co otrzyma na strumień wejścia aplikacji konsolowej, strumień wyjścia z aplikacji konsolowej jest podobnie przekierowany w drugą stronę i do takiego kontenera można się podłączyć klientem telnet.

W takim razie kontener można sobie wyobrazić jako puszkę, do której dostęp jest możliwy tylko na określone sposoby, a i sama puszka może dostać się do użytkownika i OS też tylko na określone sposoby.

1
andrzejlisek napisał(a):

Z tego, co rozumiem, kontener to bardziej sandbox niż VM, który kontaktuje się z "resztą świata" w ściśle określony sposób,

Zależy jak rozumiesz "sandbox". VM, czy PC też kontaktuje się z resztą świata w ściśle określony sposób.

czyli przede wszystkim może zapisywać lub odczytywać pliki, a także może mieć interfejsy w postaci gniazd. Nie ma bezpośredniego dostępu poprzez klawiaturę i monitor (co jest rzeczą bardzo oczywistą w przypadku zwykłych aplikacji bez kontenera), ewentualnie standardowe strumienie wejścia i wyjścia też można przekierować na gniazdo sieciowe.

Zapisywanie i odczytywanie plików nie jest czymś, co kontener może z automatu robić. Większość kontenerów nie ma dostępu do systemu plików hosta, a jedynie do włąsnego, który jest ulotny (po restarcie znowu w stanie początkowym). Można natomiast udostępnić jakiś zewnętrzny wolumen do zapisu i montować go przy starcie kontenera. Na ogół raczej się unika tego rozwiązania, bo istnieją lepsze alternatywy. Ale tak, możesz mieć kontener i "plik bazy" wewnątrz (ale będzie ulotna, co bywa przydatne w testach), albo kontener trzymający pliki z danymi na zewnątrz.

Ten drugi kontener podłącza się przez sieć lub localhost do kontenera z bazą danych, a z drugiej strony wystawia nasłuch na jakimś porcie, na którym jest REST API lub SOAP, czyli jest klientem bazy danych i serwerem HTTP. Potem instaluję trzeci kontener, na którym jest serwer HTTP, który wystawia aplikację webową, a sam kontener podłącza się do pierwszego lub drugiego kontenera przez gniazdo sieciowe.

Tak, chociaż są lepsze sposoby orkiestracji kontenerów. Masz do tego np. Kubenetes, gdzie zapodajesz wszystkie te kontenery, informację jak mają się łączyć, jakie kintenery w jakiej liczbie mają zostać uruchomione i w efekcie jednym poleceniem jesteś w stanie postawić cały system składający się z wielu takich kawałków.

Czy to to tak rzeczywiście jest? To by pasowało do stwierdzenia, że nie ma możliwości uruchomienia aplikacji z GIU, a aplikacje konsolowe można zorganizować w taki sposób, że kontener jest serwerem i ma prostą aplikację pośredniczącą, która przekierowuje wszystko co otrzyma na strumień wejścia aplikacji konsolowej, strumień wyjścia z aplikacji konsolowej jest podobnie przekierowany w drugą stronę i do takiego kontenera można się podłączyć klientem telnet.

Docker pozwala na dostanie się do konsoli kontenera. Jeżeli w kontenerze zainstalujesz serwer X11, to możesz się do niego połączyć jakimś linuxem. Jeżeli będzie to kontener Windows, to być może da się do niego połączyć przez RDP (nigdy nie próbowałem). Ale to są bardzo skrajne przypadki.

W takim razie kontener można sobie wyobrazić jako puszkę, do której dostęp jest możliwy tylko na określone sposoby, a i sama puszka może dostać się do użytkownika i OS też tylko na określone sposoby.

Analogia wydaje się dobra, ale jak z każdą analogią - nie do końca wiadomo, czy jest prawdziwa.

Patrzysz na kontenery, za bardzo przez pryzmat aplikacji desktopowej. Można, ale nie wymyślono ich w tym celu. załóżmy, że masz ten serwer www z OPA, jakąś aplikację w springu i bazę danych, które mają działać jako całość.
Wrzucasz to wszystko w kontenery, opisujesz jak mają się łączyć i w swoich pipelinach budujesz takie artefakty po każdym commicie. Jak się zbudują to wrzucasz je do jakiegoś cintainer registry (wyobraź to sobie jako katalog).
Możesz w dowolnej chwili uruchomić sobie całość "lokalnie" jakimś minikube, możesz dokładnie te same kontenery wrzucić na jakąś chmurowe kubernetes, możesz przygotować sobie różne konfiguracje systemu, np. lokalnie uruchamiasz wszystko. ale produkcyjnie baza danych to już usługa zarządzalna.
Co również istotne - definicja kontenera to plik, który ma w sobie dosłowie kilka linijek:

  • weź standardowy obraz z debianem i Java 11
  • wrzuć do katalogu plik "moja_aplikacja.jar"
  • przy starcie kontenera wuwołaj komendę "java -jar moja_aplikacja.jar"

To nie jest żadna wielka binarka, więc możesz trzymać ten plik w gicie i pracować z nim jak z każdym innym kawałkiem kodu. Możesz tez stworzyć plik opisujący wzajemne relacje kontenerów i również trzymać go w gicie.

W rezultacie, możesz łatwo stworzyć pipeline, która każdą usługę wrzuci do kontenera, kontener trafia do rejestru, do tego masz plik mówiący z czego składa się cały system i wystarczy go przekazać do czegoś, co te kontenery obsługuje, np. jakiegoś minikube, albo kubernetesa działającego jako usługa w chmurze. Wtedy ta usługa go sobie przeczyta, pobierze odpowiednie kontenery, uruchomii, w razie potrzeby zrestartuje, albo będzie skalować.

1

Kontenery to super sprawa jeśli chodzi o budowanie oprogramowania, które docelowo nawet nie będzie działać w kontenerze.

Przykładowo, mogę zbudować swój program bezpośrednio na systemie, na którym pracuję, czyli na Ubuntu 22.04 i tak opublikować paczkę binarna. I wszystko fajnie bedzie działać dopóki ktoś nie zechce tego uruchomić np. na Ubuntu 18.04. Nawet jeśli to nieskomplikowany program, to zapewne ma on zależność od glibc, który zwykle jest linkowany dynamicznie. Zbudowanie na nowym glibc spowoduje, że paczka nie zainstaluje się na tych starszych, bo manager pakietu stwierdzi, że wersja glibc jest zbyt niska.

Rozwiązanie? Budować i testować na starszych systemach. I tu się przydają kontenery.
Robię mały kontener oparty o starą wersję systemu ze starymi bibliotekami i buduje i testuje wszystko na nim. W ten sposób wiem, że mój program zainstaluje się i będzie działał poprawnie na większości popularnych linuksów.

Podobnie, tylko w nieco większej skali kontenery i maszyny wirtualne są wykorzystywane w CI. Umożliwiają szybkie sprawdzenie oprogramowania na N platformach i M wersjach/konfiguracjach, zużywając możliwie małą ilość zasobów.

Systemy wykonawcze takie jak Java/.NET nie rozwiązują w sumie tego problemu, bo to że program zadziała na Java 17 nie gwarantuje że pójdzie na Java 11 (w drugą stronę zresztą też). Analogicznie z Pythonem i jego wersjami, a tang dochodzi jeszcze problem kompatybilności bibliotek. skłaniam się ku twierdzeniu, że te wynalazki nie są wcale wieloplatformowe, a po prostu same są platformami. Więc realnie z tą przenośnością jest podobnie jak z przenośnością między różnymi linuksami. Brak przenośności został przeniesiony po prostu na inną warstwę (zamiast martwić się kompatybilnością z N wersjami OSa, musisz martwić się kompatybilnością z M wersjami Javy/.NET/Pythona/PHO itp)

1

Przede wszystkim w systemach na duza skale. Jak masz 3-4 serwerki na krzyz to sobie to bez problemu Ansiblem ogarniesz. Jak stawiasz mala apke webowa, przezyjesz bez kontenerow. Ale jesli masz system na duza skale czyli kilkaset albo kilka tysiecy boxow to trzeba sobie pomoc -> np. idac w Kubernetesa w polaczeniu z Helmem. Wtedy jak potrzebujesz n p. podmienic wersje aplikacji, zmieniasz tylko tag w odpowiednim miejscu i tyle. Najlepiej jesli w dodatku aplikacja jest stateless, wtedy to ogolnie zarzadzanie tym to bajka.

UPDATE: fajny link https://semaphoreci.com/blog/deploy-microservices

1 użytkowników online, w tym zalogowanych: 0, gości: 1