Gdy mówimy o konteneryzacji aplikacji, w zasadzie zawsze pojawiają się te same narzędzia: Docker i Kubernetes. Prawda jest taka, że w projektach wymagających „zapakowania” programu do kontenerów są one niezastąpione. A czy trzeba między nimi wybierać? W dzisiejszym wpisie wyjaśnimy, za co dokładnie odpowiadają oba narzędzia i w którym momencie projektu w ogóle warto zainteresować się Kubernetesem – zapraszamy do lektury.
Czym są kontenery i po co się je stosuje?
Zanim jednak przejdziemy do Kubernetes i Dockera, krótki wstęp dla początkujących.
Kontener to aplikacja zapakowana razem ze wszystkim, czego potrzebuje do działania – bibliotekami, zależnościami, plikami konfiguracyjnymi i odpowiednią wersją środowiska uruchomieniowego. Całość jest odizolowana od reszty systemu, więc zachowuje się tak samo niezależnie od tego, gdzie ją uruchomimy: na laptopie developera, na serwerze testowym czy na produkcji w chmurze.
Nie jest to zresztą pomysł zupełnie nowy, bo ten sam cel realizowały kiedyś maszyny wirtualne. Różnica polega na tym, że maszyna wirtualna emuluje… cały komputer razem z systemem operacyjnym, przez co potrafi ważyć kilka, nawet kilkanaście gigabajtów. Kontenery natomiast współdzielą jądro systemu z maszyną, na której działają (powiedzmy, serwerem), dodają jedynie sam kod aplikacji i pliki niezbędne do jego uruchomienia – dzięki temu są o wiele lżejsze.
Czym jest Docker?
Docker to open source’owa platforma, która pozwala budować i uruchamiać kontenery. Śmiało możemy powiedzieć, że właśnie dzięki niej koncepcja kontereneryzacji w ogóle wyszła ze swojej niszy i stała się standardem. Mechanizmy izolacji procesów istniały w Linuksie już od lat, tyle że korzystanie z nich wymagało sporej wiedzy, a Docker opakował je w dosyć proste narzędzia. W dużym skrócie:
- Dockerfile – zwykły plik tekstowy z „przepisem” na kontener. Zapisujemy w nim, na jakim systemie bazujemy, jakie pakiety trzeba doinstalować, gdzie skopiować kod aplikacji i jakim poleceniem ją uruchomić;
- Obraz (image) – gotowa paczka zbudowana na podstawie Dockerfile’a, zawierająca niezmienny szablon aplikacji: jej kod, biblioteki, niezbędne narzędzia i ustawienia. Obrazy buduje się warstwowo: każda instrukcja z Dockerfile tworzy osobną warstwę, a te są współdzielone między obrazami. Dlatego też druga aplikacja oparta na tym samym systemie bazowym nie będzie zajmowała drugi raz miejsca na dysku. Co ważne, z jednego obrazu można postawić wiele kontenerów i każdy będzie działał niezależnie od pozostałych.
- Rejestr (registry) – repozytorium, z którego pobiera się gotowe obrazy i do którego wysyła się własne. Domyślnym jest publiczny Docker Hub z tysiącami obrazów popularnych narzędzi – baz danych, serwerów, środowisk uruchomieniowych konkretnych języków programowania. Firmy zwykle prowadzą też własne, prywatne rejestry dla swoich aplikacji.
- Docker Compose – narzędzie do uruchamiania kilku kontenerów naraz. Większość aplikacji wymaga współdziałania różnych procesów; zwykle mamy back-end, bazę danych, cache, serwer proxy itd. Dzięki Docker Compose wszystkie te usługi (oraz połączenia między nimi) możemy opisać w jednym pliku YAML, a potem uruchomić całość jedną komendą.
I ten zestaw w zasadzie wystarczy, aby rozwiązać problem pod tytułem „aplikacja działa na jednym urządzeniu, a na innym nie”. Jeśli, na przykład, do zespołu dołączy nowy developer, nie będzie musiał poświęcić całego dnia pracy na konfigurowaniu środowiska – wystarczy, że sklonuje repozytorium, uruchomi jedno polecenie i po kilku minutach będzie miał u siebie dokładnie ten sam zestaw usług, na którym pracuje reszta zespołu.
Do czego służy Kubernetes (K8s)?
Z kolei Kubernetes działa jako narzędzie do orkiestracji kontenterów, to znaczy zarządza kontenerami działającymi na wielu maszynach naraz.
Wyobraźmy sobie taką sytuację – mamy dużą firmę, która hostuje swoją infrastrukturę na 20 serwerach, a na nich przechowuje 200 kontenerów. Kto decyduje, który kontener trafia na którą maszynę? Co się stanie, jeśli jeden z serwerów się zawiesi – kto w środku nocy przeniesie z niego usługi gdzie indziej? Da się to wszystko oskryptować samodzielnie… albo wykorzystać Kubernetesa.
K8s jest dosyć złożonym systemem, trudnym dla początkujących, ale przez doświadczonych DevOpsów bardzo cenionym, bo pozwala zautomatyzować w zasadzie cały proces zarządzania aplikacjami kontenerowymi. System działa w modelu deklaratywnym: nie wydajemy mu poleceń w stylu „uruchom kontener X na serwerze numer trzy”, zamiast tego w plikach YAML opisujemy po prostu stan docelowy – chcemy pięć kopii tej aplikacji, każda z takim limitem pamięci, dostępna pod tym adresem. Kubernetes przyjmuje taki opis i sam doprowadza do niego klaster (cały zbiór maszyn, którymi zarządza), a potem nieustannie porównuje stan faktyczny z tym zadeklarowanym i na bieżąco niweluje wszystkie różnice.
Efekt jest taki, że jeśli kontener padnie, nikt nie musi nic robić. System widzi, że zamiast pięciu kopii działają cztery, więc uruchamia piątą. A jeśli, powiedzmy, padnie cała maszyna, jej zadania zostaną rozdzielone na pozostałe.
Kubernetes a Docker – jak są ze sobą powiązane?
Kubernetes pracuje na kontenerach… a do ich uruchomienia potrzebny jest odpowiedni silnik. Przez długi czas system korzystał w tym celu właśnie z Docker Engine, przez warstwę pośredniczącą o nazwie Dockershim. Potem jednak została ona zastąpiona nieco lżejszymi silnikami, containerd (który zresztą sam wywodzi się z Dockera) oraz CRI-O. Natomiast jedno się nie zmieniło: ogromną większość kontenerów uruchamianych na Kubernetes cały czas buduje się na Dockerze.
Kubernetes vs Docker – gdzie się różnią?
W ramach podsumowania zebraliśmy najważniejsze różnice między Docker a Kubernetes w poniższej tabelce.
| Docker | Kubernetes | |
| Główne zadanie | budowanie i uruchamianie kontenerów | zarządzanie kontenerami w czasie ich działania |
| Zakres działania | pojedyncza maszyna (np. konkretny serwer) | klaster złożony z wielu maszyn |
| Sposób obsługi | polecenia w plikach Dockerfile i Compose | deklaracje w YAML – opisujemy stan docelowy, system sam do niego dąży |
| Skalowanie działania aplikacji | ręczne, w granicach jednego serwera | automatyczne, na podstawie tego, jak obciążone są maszyny w ramach klastra |
| Reakcja na awarię | konieczna ręczna interwencja zespołu | tzw. self-healing: system sam restartuje kontenery i przenosi zadania maszyn, które uległy awarii na pozostałe |
| Aktualizacje aplikacji | konieczny restart aplikacji | nowa wersja aplikacji wdrażana kopia po kopii, bez przerwy w działaniu usługi |
| Próg wejścia | niski, do opanowania w kilka dni | wysoki |
| Typowe zastosowania | środowisko lokalne, CI/CD, mniejsze wdrożenia | projekty o dużej skali i wysokich wymaganiach co do dostępności |
Kiedy wystarczy Docker, a kiedy potrzebny jest Kubernetes?
Wbrew temu, jak dużo i często mówi się o Kubernetesie przy temacie konteneryzacji, spora część projektów… nigdy go nie potrzebuje. Tym bardziej, że od pewnego już czasu Docker oferuje własne, wbudowane narzędzie do orkiestracji kontenerów – Docker Swarm – które bez problemu radzi sobie z mniejszymi klastrami składającymi się z kilku-kilkunastu maszyn. Z drugiej strony, przy większych wdrożeniach Kubernetes naprawdę pozostaje niezastąpiony.
Kiedy sam Docker w zupełności wystarczy:
- w codziennej pracy w środowisku lokalnym – nawet firmy, które na produkcji korzystają z Kubernetesa, u siebie na laptopach pracują z Dockerem i Compose;
- w pipeline’ach CI/CD – np. do uruchamiania testów w izolowanych kontenerach na środowisku produkcyjnym; do takich zadań orkiestracja nie jest do niczego potrzebna;
- przy rozwoju aplikacji hostowanych na jednym serwerze – jeśli firmowy system spokojnie mieści się na jednej maszynie, budowanie całego klastra nie ma w praktyce większego sensu.
Kiedy trzeba już sięgnąć po Kubernetesa:
- przy architekturze mikroserwisowej – trudno jest ręcznie zarządzać kilkunastoma czy kilkudziesięcioma niezależnymi usługami, z których każda ma własny cykl wdrożeniowy;
- przy mocno zmiennym ruchu i wysokich wymaganiach co do dostępności – tak jak mówiliśmy, Kubernetes oferuje automatyczne skalowanie liczby kopii aplikacji w obrębie klastra do wielkości ruchu, w razie problemów sam też restartuje kontenery i dzieli zadania między działające maszyny;
- przy pracy w kliku środowiskach równolegle – na przykład gdy aplikacja hostowana jest w chmurze u różnych dostawców, powiedzmy, w AWS i w Azure.
Docker i Kubernetes, czyli nie „albo-albo”, tylko „najpierw-potem”
Wróćmy na koniec do pytania z tytułu. Prawda jest taka, że nie musimy wybierać między Kubernetesem a Dockerem, bo jedno narzędzie kontenery tworzy, a drugie nimi zarządza – mają więc swoje miejsce na dwóch różnych etapach tego samego procesu. Trzeba byłoby raczej zadać sobie inne pytanie: czy projekt urósł już na tyle, żeby dokładać do niego warstwę orkiestracji? Jeśli nie, to praktycznie wszystkie problemy projektowe powinien rozwiązać sam Docker.
Zainteresował Cię ten temat? Zapraszamy do lektury kolejnych tekstów na naszym blogu – piszemy nie tylko o narzędziach dla developerów, ale też specjalistów SEO i marketerów.
swój potencjał z
polityką prywatności