Operacje na kontenerach

Operacje na kontenerach Docker, ich uruchamianie, budowanie własnych obrazów oraz obsługa repozytorium – tymi oto rzeczami zajmiemy się w dzisiejszym wpisie. W poprzednim tekście omawialiśmy podstawowe założenia ekosystemu Docker oraz związane z nim terminy, pozwalające zrozumieć budowę, architekturę oraz podstawowe operacje przeprowadzane podczas uruchamiania kontenerów. Czas więc na rozwinięcie tematu Docker-a!

 

Operacje na kontenerach Docker. Wprowadzenie

Przypomnijmy, że kontener to efekt ujednolicenia warstw tylko do odczytu oraz pojedynczej warstwy do odczytu i zapisu, dzięki której możliwe jest funkcjonowanie wymaganych zadań. Jego uruchomienie następuje z poziomu klienta, za pomocą komendy docker run. W podstawowej wersji wystarczające jest podanie obrazu (nazwy bądź ID), z którego następuje uruchomienie. Jednak polecenie to może przyjąć wiele argumentów, a jego składnia przedstawia się następująco: docker run [OPCJE] OBRAZ[:TAG] [POLECENIE] [ARGUMENTY].

Najprostszą formą powyższej komendy, pozwalającą na uruchomienie kontenera Ubuntu, będzie więc: docker run ubuntu. Warto jednak, dla własnej wygody, dodać opcje:

  •  –name <NAZWA>, nadającą kontenerowi łatwą do zapamiętania nazwę
  •  –restart unless-stopped, restartującą kontener w przypadku jego awarii, czy restartu maszyny,
  •  –rm, usuwająca kontener po zakończeniu działania

 

Sam kontener może zostać uruchomiony w formie pierwszoplanowej (domyślnie) bądź „w tle”, za pomocą dodatkowego przełącznika —detach. Warto zauważyć, iż w przypadku nienadania nazwy zostanie ona wygenerowana.

Użyty do uruchomienia obraz definiujemy poprzez element :TAG. Pozwala on określić dokładną wersję oprogramowania, które ma zostać załadowane. W przypadku jego braku użyta zostaje najnowsza dostępna w repozytorium wersja.

Ostatnie dwa, niewymagane elementy to: polecenie oraz argumenty. Ich podanie określa dokładną komendę wraz z argumentami, która ma zostać wykonana po uruchomieniu kontenera. Nadpisują one domyślne, zastosowane w obrazie wartości. W przypadku istnienia tzw. entrypoint-u są one traktowane jako jego argumenty.

Zatrzymanie kontenera następuje poprzez wydanie polecenia docker stop NAZWA/ID. Usunięcie jest możliwe z użyciem docker rm NAZWA/ID. Nie przewidziano jednak opcji pozwalającej na usunięcie wszystkich kontenerów, więc aby to uzyskać należy usunąć każdy kontener oddzielnie.

Listę oraz stan kontenerów otrzymujemy poprzez docker ps –-all. W przypadku zakończenia z powodu błędu otrzymamy jego numer, co pozwoli na sprawdzenie przyczyny, np. błąd 126 oznacza niepoprawną komendę uruchomieniową lub jej brak w obrazie.

Dostęp do sieci kontener uzyskuje domyślnie poprzez mostek z wykorzystaniem interfejsu Docker-a (veth) na hoście gospodarza (bridge). Jest jednak możliwość uruchomienia sieci z wykorzystaniem network-ingu innego, już działającego, kontenera (współdzielenie) czy bezpośrednio z hosta (host). Ostatnia opcja jest najwydajniejsza z punktu widzenia szybkości funkcjonowania sieci, jednak daje kontenerowi pełne prawa do usług hosta (np. DBus), co nie jest do końca bezpieczne i może przez to stanowić ewentualną lukę bezpieczeństwa.

Celem zapewnienia odpowiedniego poziomu wydajności podczas uruchamiania wielu kontenerów, możemy zastosować opcje ograniczające użycie zasobów – CPU, RAM czy dysku twardego. Najpopularniejsze z nich to:

  • –memory, ograniczająca zużycie pamięci operacyjnej,
  • –cpu-shares, ograniczająca użycie CPU,
  • –device-read-bps, limitująca odczyt z urządzenia (bps),
  • –device-write-bps, limitująca zapis na urządzeniu (bps).

 

Możliwe jest jeszcze użycie wielu innych opcji, np. healtcheck-ów, przekazywania zmiennych środowiskowych, dołączenia wolumenu czy przekierowywania portów. Ich użycie zależy jednak od konkretnego przypadku i wymagań projektu, a samo zastosowanie powoduje nadpisanie opcji zapisanych w Dockerfile.

Po uruchomieniu kontenera jest on widoczny na liście procesów (docker ps). Wykonuje on zadanie zapisane w obrazie bądź nadpisane przy jego uruchomieniu. Podgląd zachodzących procesów, a raczej ich wyników, jest możliwy przy pomocy polecenia docker attach <ID lub NAZWA>. Należy jednak zauważyć, iż odłączenie z konsoli następuje poprzez kombinacje klawiszy <CTRL + C>, powodując jednocześnie przerwanie uruchomionego w kontenerze procesu. Zapobiec temu można poprzez dodanie opcji –sig-term=false, która to spowoduje, iż proces nie otrzyma sygnału kończącego działanie.

Jednak zabezpieczyć się przed ewentualnym przerwaniem głównego procesu można już na poziome uruchamiania kontenera – poprzez dodanie opcji —tty, która spowoduje zaalokowanie powłoki (terminala).

Poza samym podglądem stanu kontenera możliwe jest podłączenie się do niego, uzyskując pełny dostęp, np. do systemu plików czy wysłanie polecenia, które zostanie przetworzone wewnątrz kontenera. Uzyskanie tego jest możliwe poprzez komendę docker exec [OPCJE] <KONTENER> <KOMENDA> [ARGUMENTY]. Poprzez zastosowanie opcji —interactive oraz —tty możliwe jest „przelogowanie” do kontenera i wykonywanie poleceń bezpośrednio wewnątrz niego.

Informacje te odnoszą się do uruchamiania kontenera, bądź jego obsługi. Mimo obszernego wsparcia użytkowników, którzy udostępniają wiele obrazów, jak i dużej dostępności oficjalnych wersji przeznaczonych dla Docker-a, może zaistnieć potrzeba użycia obrazu, który na chwilę obecną nie jest dostępny w repozytorium. Zbudowanie własnego obrazu jest możliwe na dwa sposoby:

  • poprzez zapisanie zmodyfikowanego obrazu,
  • przy użyciu Dockerfile.

 

Pierwsza z opcji polega na uruchomieniu obrazu z repozytorium, naniesieniu wymaganych zmian i ich zapisaniu przy pomocy komendy docker commit [OPCJE] <KONTENER> [REPOZYTORIUM[:TAG]]. Zmiany w obrazie mogą zostać dokonane przy pomocy przedstawionej wcześniej możliwości dostępu do strumieni wejścia/wyjścia (docker exec –it <KONTENER>).

Druga opcja zakłada użycie pliku konfiguracyjnego – Dockerfile – który to jest de facto skryptem złożonym z odpowiednich instrukcji, a ich przetworzenie daje w efekcie gotowy do użycia obraz. Należy zauważyć, iż kolejność komend ma znaczenie – są one wykonywane zgodnie z zapisem w Dockerfile. Najważniejsze z nich to:

  • FROM <obraz>, użycie obrazu jako bazowego dla kontenera,
  • MAINTAINER <autor>, zapisanie informacji o autorze obrazu,
  • ADD <źródło> <cel>, powoduje umieszczenie pliku/katalogu wewnątrz kontenera (kopii),
  • RUN <komenda>, polecenie wykonywane podczas budowania obrazu, celem jego ostatecznego uformowania,
  • CMD <komenda>, komenda wykonywana podczas uruchomienia kontenera,
  • ENTRYPOINT <aplikacja>, zdefiniowanie domyślnej aplikacji dla obrazu,
  • EXPOSE <port>, przekierowanie portu.

 

Przykładowy Dockerfile dla instalacji serwera WWW Apache poniżej.

FROM ubuntu
MAINTAINER Hostersi
RUN apt-get update
RUN apt-get install -y apache2
EXPOSE 80
CMD [„/usr/sbin/apache2”, „-D”, „FOREGROUND”]

Budowanie polega na wydaniu komendy docker build [OPCJE] LOKALIZACJA|URL. Dla przedstawionego przykładu, jeśli plik został zapisany w aktualnym katalogu, polecenie przyjmie postać „docker build –t myfirstimage .„. Dodana opcja –t pozwoli na łatwe odnalezienie obrazu w momencie uruchamiania kontenera.

Z czasem, kiedy obrazów zaczyna przybywać, warto usuwać te stare, już nieużywane (docker rmi) bądź odpowiednio je tagować (docker tag). W wielu przypadkach przeniesienie obrazów z lokalnej maszyny do zdalnego repozytorium pozwoli na ich szybszy rozwój, poprzez współpracę z innymi osobami. Najpopularniejszą biblioteką obrazów jest DockerHub. Posiada ona przydatną opcję automatycznego (prze)budowania obrazu w przypadku zmiany w kodzie.

Użycie repozytorium z poziomu klienta jest możliwe poprzez komendę docker login.

 

Operacje na kontenerach. Shipyyard – manager Dockera

Podstawowe operacje wykonywane w ekosystemie Docker-a, mimo iż nie są trudne, mogą zostać w pewien sposób „ułatwione”, zwłaszcza na początku. Podczas codziennej pracy z Docker-em, zarówno jeśli chodzi o uruchamianie kontenerów, jak i usuwanie starych obrazów, można się wspomóc menedżerem zarządzanym z poziomu przeglądarki WWW. Jednym z takich menedżerów jest Shipyard.

Oprogramowanie jest w pełni zgodne z API Docker-a. Zbudowane w oparciu o Docker Swarm pozwala na zarządzanie kontenerami i obrazami, a także na obsługę repozytorium. Poza dostępem do listy kontenerów oraz podstawowych operacji możliwych do przeprowadzenia na nich (stop, restart, destroy) mamy dostęp do logów oraz możliwość uruchomienia konsoli, a ich statystyki pozwolą określić czy przypisane zasoby są wystarczające. Oprogramowanie zapewnia obsługę wielu użytkowników, z zapewnieniem wsparcia dla serwerów LDAP.

 

operacje na kontenerach
Instalacja narzędzia jest możliwa przy pomocy przygotowanego skryptu, bądź poprzez ręczne utworzenie wymaganych zasobów. Sam Shipyard jest uruchamiany jako kontener Docker-a, co pozwala na jego uruchomienie w dowolnym środowisku.

 

operacje na kontenerach

 

Operacje na kontenerach Docker. Podsumowanie

Przedstawione do tej pory informacje pozwalają na uruchamianie kontenerów, zarówno z gotowych obrazów, jak i przygotowanych zgodnie z zaistniałymi potrzebami oraz ich podstawową obsługę. Jednak w środowisku produkcyjnym ważną rolę odgrywa redundancja zasobów – zapewnienie wysokiej dostępności. Jest to możliwe do osiągnięcia z wykorzystaniem środowisk przeznaczonych do tego celu, tzw. klastrach wysokiej dostępności (HA).

Niebawem przybliżymy także rozwiązania, pozwalające zapewnić HA aplikacji zbudowanej w oparciu o mikroserwisy. Ale to już w następnym wpisie 🙂

 

Zobacz również:

Obsługa środowiska Docker. Wprowadzenie #1
Infrastruktura serwerowa bez tajemnic. Serwer dedykowany, VPS, czy chmura?
Skąd się bierze wysoka dostępność (HA) w chmurze?

 

PYTANIA