Kot Źródłowy

Początki pracy z Dockerem (dla opornych)

Cześć, na dzisiaj przygotowałam coś ekstra. Temat modny i od dłuższego czasu bardzo lubiany, więc swoistym obciachem jest nic o nim nie wiedzieć. Żartuję, przecież każdy, zanim się czegoś dowiedział i nawet jeśli jest w tym ekspertem, to miał w swoim życiu etap, kiedy nie wiedział nic. Tak często o tym zapominamy, kiedy przychodzi nam się spotkać z kimś początkującym.

Przechodząc do wpisu: jeśli już coś wiesz o Dockerze, to twoja wiedza może się co najwyżej ugruntować. To też jest bardzo ważne. Kot jednak w tajemnicy planuje więcej niż jeden taki wpis, bo to fajny temat i puchate łapki aż rwą się do pisania. Jak nie wiesz nic, to myślę, że znajdziesz tutaj dobry punkt startowy. No ale zacznijmy od samego początku.

Co to jest Docker?

Wikipedia mówi kotom i ludziom:

Docker – otwarte oprogramowanie służące jako „platforma dla programistów i administratorów do tworzenia, wdrażania i uruchamiania aplikacji rozproszonych”

Docker jest określany jako narzędzie, które pozwala umieścić program oraz jego zależności w lekkim, przenośnym, wirtualnym kontenerze, który można uruchomić na prawie każdym serwerze z systemem Linux

Źródło: Wikipedia

No to już wszystko jasne, prawda? Tak, wiem, przecież miało być dla początkujących, a ja tu wyjeżdżam z jakąś wiedzą tajemną. Ale prawdą jest, że Docker jest otwartym oprogramowaniem, które pozwala nam lepiej wykorzystać możliwości systemu Linux jako serwera dla naszych aplikacji (piszcie w komentarzach i na priv, czy chcecie więcej wpisów linuksowych). Co to są aplikacje rozproszone i jak działają, to może kiedyś napiszę, na razie ta wiedza nie jest nam niezbędna do szczęścia (możecie też wygooglować). No ale co z tego, że mogę uruchamiać aplikacje? Przecież tworzę je, wpisuję npm init albo inne podobne zaklęcie i moja aplikacja działa.

To wszystko prawda. Problem pojawia się, gdy takich aplikacji mamy dużo, a one wymagają dużo gotowych komponentów. Fajnie wtedy jest dać każdej aplikacji wyizolowane środowisko i po prostu uruchamiać ją w nim. Nie boimy się wtedy ani straszliwych węży, ani zależności naszych narzędzi, ani nawet tego, że tuńczyka nam zabraknie (chociaż to nie ma nic wspólnego z Dockerem). Poza tym, jeśli chcemy naszą aplikację wynieść gdzieś w świat, to fajnie, jakby w tym świecie spokojnie sobie działała. A jeszcze lepiej, żeby jej instalacja była tak prosta, jak się tylko da. W tym wszystkim Docker może nam pomóc. Bo to jest takie oprogramowanie, które tworzy nam zamknięte, jakby osobne środowisko do działania naszej aplikacji. Trochę tak, jak maszyna wirtualna, tylko bardziej skrojone na miarę. Jednak w zamyśle to rozwiązanie znacznie się różni od maszyn wirtualnych, a pod wieloma względami jest nawet lepsze.

W skrócie, bo wiem, że nie każdy może wiedzieć, co to jest ta maszyna wirtualna (mogę kiedyś o tym szerzej napisać). Spróbuję to zobrazować jako przykład, bo tak jest się najłatwiej czegoś nauczyć. Teraz kiedy mnie czytasz, to prawdopodobnie siedzisz przy komputerze (albo smartfonie, tablecie, one z technicznego punktu widzenia też są komputerami). Twoja maszyna jest fizyczna, bo ma prawdziwy dysk twardy, procesor i prawdziwą pamięć RAM. Jak będziesz ciekawy, to możesz ostrożnie komputer rozkręcić i zajrzeć do środka. Jednak czasem lepiej zostawić to specjalistom. Standardowo masz na tym komputerze jakiś system operacyjny, a na nim oprogramowanie potrzebne do różnych zadań. Możesz też za pomocą specjalnego oprogramowania stworzyć sobie wirtualny komputer na swoim fizycznym. Przykładowym oprogramowaniem do zarządzania maszynami wirtualnymi jest VirtualBox. Tak naprawdę to jeden z łatwiejszych sposobów, żeby mieć Linuxa na Windowsie. Wtedy przydzielasz takiej VM (virtual machine) część zasobów swojego komputera (oddajesz część RAM-u, miejsca na dysku, itp), żeby wirtualny komputer mógł działać. Wadą tego rozwiązania jest to, że zasoby są przydzielane na sztywno, a nie zawsze wiesz, ile będziesz potrzebować. Wydajność takiego rozwiązania jest też mocno ograniczona.

A teraz, czym jest konteneryzacja. Instalujesz nowy kontener i on ma wszystko, czego mu potrzeba. Jest to sobie takie pudełko, w którym jest system operacyjny (jakaś dystrybucja linuxa) i potrzebne zainstalowane aplikacje i biblioteki. Jeśli chodzi o zasoby, kontener korzysta z ogólnych zasobów twojego komputera i bierze tyle, ile potrzebuje. Nawet jądro linuxa jest współdzielone. To oszczędza nam sporo zasobów i zwiększa wydajność.

Po co to wszystko?

O tym trochę pisałam powyżej, ale jeszcze jeden przykład mi przychodzi na myśl. Załóżmy, że piszesz ze swoją drużyną jakiś superpoważny projekt (taki, że robicie testy jednostkowe). Niestety, nikt (oprócz ciebie) nie rozumie potrzeb kotów i nie chce zezwolić, żeby mocha --reporter=nyan była waszą oficjalną konwencją odnośnie testów jednostkowych. Nic prostszego niż postawić sobie odpowiedni kontener Dockera i skryptem wrzucać tam kod, żeby sprawdzić, czy testy przechodzą. Wtedy już nie musisz się martwić o żadne warczenie niezadowolonej współbraci. Zbyt abstrakcyjnie? To pomyśl sobie, że tworzysz aplikację, która wymaga bazy danych. I w teorii możesz taką bazę postawić samodzielnie. Zależnie od używanej bazy danych, ten narzut pracy jest bardzo różny, a my chcemy po prostu napisać aplikację. Z Dockerem to wystarczy ściągnąć odpowiedni obraz i uruchomić kontener używając jednego prostego skryptu. Brzmi fajnie, prawda?

No ale konkret

Żeby móc korzystać z Dockera, musisz go zainstalować na swoim linuksie. Sprawdź na stronie Dockera, jak to zrobić. Standardowo wszystkie polecenia związane z Dockerem wydajemy z poziomu uprawnień roota, więc komenda sudo może się okazać nieodzowna. Przechodząc do rzeczy, żeby stworzyć kontener, musisz mieć obraz Dockera. Obraz to inaczej taki szkielet, gotowe środowisko dla naszej aplikacji. Najprostsze obrazy to po prostu dystrybucje Linuxa, zwane też obrazami bazowymi. Ale skoro o tym wspominam, to znaczy, że istnieją też obrazy znacznie bardziej rozbudowane. Jak to wszystko działa? Pozwól, że ci wytłumaczę (oczywiście na przykładzie). Pamiętasz Shreka? On o sobie mówił, że ogry są jak cebula (nie jak tort) i że mają warstwy. To obrazy Dockera też mają warstwy, tylko chyba bardziej jak tort. Tak sobie właśnie uświadomiłam, że wśród moich czytelników mogą być osoby, które nie znają Shreka. Z pewnością musicie to nadrobić. Można powiedzieć, że obrazy składają się z warstw potrzebnych narzędzi, bibliotek i pakietów. Sprawa wygląda tak, że obraz jest tylko do odczytu. Żeby móc coś w nim namieszać, to potrzebujemy zrobić z niego kontener, czyli dodajemy warstwę, którą możemy odczytać i zapisać. Z kolei gotowy kontener możemy zapisać jako obraz, tym samym dokładając kolejną warstwę.

Skąd brać takie obrazy? To proste! Jest sobie serwis hub.docker.com, który pozwoli nam odnaleźć dużo fajnych obrazów. Są oczywiście też inne miejsca, ale na razie skupmy się na tym konkrentym. Teraz kilka zaklęć dotyczących obrazów, bo nie wiem, czy wspominałam, ale z Dockerem dogadujemy się poprzez konsolę:

# pobranie najnowszej wersji obrazu
sudo docker pull nazwa_obrazu
# pobranie konkretnej wersji obrazu
sudo docker pull nazwa_obrazu:wersja
# wyszukanie obrazu w dockerhubie
sudo docker search nazwa_obrazu
# pokazanie wszystkich pobranych obrazów
sudo docker images
# usunięcie obrazu
sudo docker rmi id_obrazu

Teraz kontenery, czyli coś, nad czym będziemy często pracować. Tak naprawdę to jest całe sedno Dockera, nasze interaktywne środowisko. To właśnie w kontenerze będziemy uruchamiać naszą aplikację. I kontener działa, dopóki aplikacja uruchomiona w nim działa. Gdy jej proces się zakończy, to działanie kontenera też się kończy. Dlatego właśnie Docker często jest używany do uruchamiania mikroserwisów. Przy tworzeniu kontenera, możesz mu nadać nazwę poprzez parametr --name, w przeciwnym razie silnik Dockera wybierze sam nazwę składającą się z jednego angielskiego przymiotnika i jednego rzeczownika. Ciekawe, czy ktoś natrafi na nazwę sweet_cat

# pokazanie wszystkich aktywnych kontenerów
sudo docker ps
# pokazanie wszystkich stworzonych kontenerów
sudo docker ps -a
# stworzenie kontenera 
sudo docker create nazwa_obrazu
# uruchamianie kontenera
sudo docker run <nazwa_kontenera>
# start kontenera
sudo docker start
# zatrzymanie kontenera
sudo docker stop
# kopiowanie do/z kontera (działa podobnie jak cp lub scp)
sudo docker cp <źródło> <cel>
# wejście do kontenera w celu uruchomienia w nim jakiś rzeczy
sudo docker exec -it <nazwa_kontenera> bash

Oczywiście wszystkie te polecenia mają bardzo dużo opcji, o których możesz poczytać w dokumentacji albo w następnym kocim wpisie (no, przynajmniej w jednym z następnych). Na razie myślę, że taka dawka wiedzy wystarczy, jak na jeden raz. Jeśli twoja ciekawość jest zbyt wielka i chcesz wiedzieć wszystko już i teraz, to odsyłam do dokumentacji.

No to na dzisiaj tyle. Mam nadzieję, że się podobało i wrócisz po więcej. Zaglądaj tu czasem, ale nie zapomnij o kocim fejsbuku, z którego jako pierwszy dowiesz się ciekawostek i nowinek. Pozdrawiam i jedz dużo owoców.

Miau!