Docker w Linuksie cz. I – podstawowe komendy
Rozpoczynamy nową serię artykułów tym razem poświęconych Dockerowi. Dziś omówimy związane z nim najprostsze komendy. Zaczniemy od instalacji i konfiguracji, następnie dodamy użytkownika do grupy i zaimportujemy obraz kontenera. Na końcu wylistujemy i zniszczymy kontener wraz z obrazami.
Rozpoczynamy nową serię artykułów tym razem poświęconych Dockerowi. Dziś omówimy związane z nim najprostsze komendy. Zaczniemy od instalacji i konfiguracji, następnie dodamy użytkownika do grupy i zaimportujemy obraz kontenera. Na końcu wylistujemy i zniszczymy kontener wraz z obrazami.
Wbrew błędnemu i niestety dosyć często spotykanemu mniemaniu Docker nie oznacza kontenera. Docker jest po prostu aplikacją w architekturze klient-serwer. Przy czym klientem jest z reguły konsolowa komenda docker
. Pod spodem Docker wykorzystuje standardowe mechanizmy jądra opisane w teoretycznych podstawach, by tworzyć odizolowane środowiska uruchomienia (ang. runtime). W niektórych dystrybucjach (z wyszczególnieniem dystrybucji Enterprise Linuksa) dodatkowym mechanizmem zabezpieczającym kontenery jest SELinux, który tworzy odpowiednie konteksty dla kontenerów działających w naszym systemie.
Na początku należy wytłumaczyć następujące pojęcia:
- obraz – jest to wzorzec kontenera zawierający w sobie środowisko uruchomieniowe (niezbędne biblioteki i struktury systemu). Obrazy są tylko do odczytu. By stworzyć (zmienić) obraz, trzeba stworzyć następną warstwę plików. Z jednego obrazu może zostać uruchomione potencjalnie nieskończenie wiele kontenerów. Obrazy po pobraniu są z reguły od razu gotowe do uruchomienia;
- rejestr (registry) obrazów – zawiera w sobie obrazy gotowe do pobrania i uruchomienia. Istnieją zarówno publiczne, jak i prywatne rejestry. Najbardziej znanym publicznym rejestrem obrazów jest Docker Hub. Większość organizacji posiada swój prywatny rejestr obrazów, w którym znajdują się obrazy tworzone przez zespoły utrzymania. Obrazy te zawierają z reguły wewnętrzne aplikacje firmy i pozwalają na błyskawiczne rozlokowanie oraz stosunkowo proste zarządzanie skonteneryzowaną aplikacją w infrastrukturze. Należy jednak pamiętać, że konteneryzacja nie zawsze jest procesem prostym i opłacalnym.
Komendą uruchamiającą deamona Dockera jest dockerd
. Daemon Dockera odpowiada między innymi za budowanie kontenerów (obrazów), importowanie i zarządzanie obrazami czy uruchamianie oraz zarządzanie kontenerami. Natomiast polecenie docker
jest konsolowym interfejsem służącym do komunikacji z daemonem Dockera.
Instalacja Dockera w wersji community
Od dłuższego czasu Docker jest dostępny w dwóch wersjach – Enterprise i Community. Zmienił się też sposób wersjonowania projektu, dlatego w niektórych materiałach można znaleźć wersje oznaczone jako 1.xy, podczas gdy obecna rozwojowa wersja community to już 19.
Tak nagła zmiana wersjonowania projektu to zabieg psychologiczny mający na celu osiągniecie efektu nowszej wersji. Dla przykładu zmiana wersji z 2.0 na 2.3 wydaje się mniej inwazyjna niż z 20.0 na 23.0. Wracając jednak do tematu wyboru wersji Dockera – do celów deweloperskich w zupełności wystarcza wersja społecznościowa.
By dodać repozytorium dla Enterprise Linuksów (dotyczy systemów RHEL, Oracle® Linux, CentOS, czy Scientific Linux) można wykonać:
curl https://download.docker.com/linux/centos/docker-ce.repo | sudo tee /etc/yum.repos.d/docker-ce.repo sudo yum install -y docker-ce
Istnieje też możliwość zainstalowania Dockera z repozytorium Extras, jednak nie polecam tego sposobu, gdyż pakiety dostarczane przez firmę Docker są po prostu świeższe i de facto lepiej wspierane.
By sprawdzić, czy Docker został zainstalowany, wystarczy wywołać komendę:
> docker -v Docker version 18.09.6, build 481bc77156
Krótkie omówienie konfiguracji dockerd
By uruchomić daemona Dockera, należy wykonać:
systemctl start docker
By daemon Dockera był dostępny po starcie systemu, należy go włączyć:
systemctl enable docker
Daemona Dockera można też uruchomić ręcznie przy pomocy polecenia:
dockerd
Uruchomiony w ten sposób daemon nie ma jednak zaczytanej niezbędnej konfiguracji, przez co nie działa w oczekiwany sposób i jest praktycznie bezużyteczny. Wynika to z faktu, iż systemd uruchamiając Dockera jako usługę, wczytuje szereg plików, w tym oczywiście pliki konfiguracyjne. Plik odpowiedzialny za usługę (service) Dockera realizowaną przez Systemd to /usr/lib/systemd/system/docker.service
.
By znaleźć pliki konfiguracyjne (środowiskowe), można wykonać następującą komendę:
> grep 'File' /usr/lib/systemd/system/docker.service EnvironmentFile=-/run/containers/registries.conf EnvironmentFile=-/etc/sysconfig/docker EnvironmentFile=-/etc/sysconfig/docker-storage EnvironmentFile=-/etc/sysconfig/docker-network
Zaczytane z zadanych plików środowisko jest wykorzystywane przez ExecStart
, które mówiąc prostym językiem, jest programem uruchamianym przez systemd.
ExecStart=/usr/bin/dockerd-current \ --add-runtime docker-runc=/usr/libexec/docker/docker-runc-current \ --default-runtime=docker-runc \ --exec-opt native.cgroupdriver=systemd \ --userland-proxy-path=/usr/libexec/docker/docker-proxy-current \ --init-path=/usr/libexec/docker/docker-init-current \ --seccomp-profile=/etc/docker/seccomp.json \ $OPTIONS \ $DOCKER_STORAGE_OPTIONS \ $DOCKER_NETWORK_OPTIONS \ $ADD_REGISTRY \ $BLOCK_REGISTRY \ $INSECURE_REGISTRY \ $REGISTRIES
Wiedząc już, w jaki sposób działa wczytywanie konfiguracji Dockera w Enterprise Linuksie, czytelnik może się domyślić, iż edycja ustawień startu daemona Dockera odbywa się przez edycję odpowiednich plików /etc/sysconfig/docker\*
.
Dodanie użytkownika do grupy Docker
Jeśli chcemy, by nieuprzywilejowany użytkownik mógł korzystać z dobrodziejstw Dockera bez konieczności podnoszenia swoich uprawnień (np. przez sudo), należy go dodać do grupy Docker. W tym celu można użyć między innymi komendy usermod
:
usermod -a -G docker user
W przypadku modyfikacji grup działającego w systemie użytkownika, najłatwiejszym rozwiązaniem jest jego wylogowanie w celu przeładowania grup. Jeśli jest to jednak niewskazane lub niemożliwe, istnieje też możliwość użycia komendy newgrp
w celu przeładowania lub dodania grupy w lokalnej sesji.
newgrp -
lub
newgrp docker
Wyszukiwanie i importowanie kontenerów
Po uruchomieniu daemona Dockera możemy przejść do zarządzania kontenerami przy pomocy konsolowego klienta, czyli komendy docker
. Na sam początek proponuję wyszukać obraz przy pomocy komendy docker search
. Szukany obraz jest obrazem zawierający w sobie Pythona w wersji 3. Zatem 2. argumentem komendy docker search
, którym jest wyszukiwana fraza, będzie Python. By ograniczyć wyniki, pozwoliłem sobie na dodanie do potoku komendy head -4
.
> docker search python | head -4 NAME DESCRIPTION STARS OFFICIAL AUTOMATED python Python is an interpreted, interactive, objec… 4319 [OK] django Django is a free web application framework, … 850 [OK] pypy PyPy is a fast, compliant alternative implem… 194 [OK]
Do importowania kontenera służy komenda docker pull
. Docker domyślnie pobierze najnowszą wersję kontenera (tagowaną jako latest
). Nas interesuje jednak ta oznaczona jako 3. O tagowaniu (wersjonowaniu) kontenerów dowiemy się więcej w następnym artykule dotyczącym Dockera. Wykonanie komendy docker pull
powinno zwrócić podobne wyjście.
> docker pull python:3 3: Pulling from library/python 6f2f362378c5: Pull complete ...(wyjście ucięte) c8514b1c6524: Pull complete Digest: sha256:9e0b4f32487ca1863b45383420b8db77990debae748e2e875d2f86fa9510d4a5 Status: Downloaded newer image for python:3:
Uruchomienie pierwszego kontenera z Dockerem
By uruchomić kontener, używa się polecenia docker run
. Nasz kontener Pythona uruchomimy także z innymi parametrami:
-i
uruchamia kontener interaktywnie-t
alokuje terminal (tty) w kontenerze.
docker run -it python:3 Python 3.7.3 (default, Jun 11 2019, 01:05:09) [GCC 6.3.0 20170516] on linux Type "help", "copyright", "credits" or "license" for more information. >>>
W ten sposób mamy dostęp do Pythona uruchomionego w kontenerze. By zmienić komendę, która zostanie uruchomiona wewnątrz kontenera, można dodać następny argument do poprzedniego polecania lub użyć opcji --entrypoint
.
docker run -it python:3 bash docker run -it --entrypoint '/bin/bash' python:3
Listowanie kontenerów Dockera
Działające kontenery listuje się przy pomocy komendy docker ps
. Domyślnie pokazuje ona tylko uruchomione kontenery. U mnie w tym momencie działają dwa obrazy:
> docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES faf92be3b289 python:3 "python3" 3 seconds ago Up 3 seconds zealous_shirley 2a688789b5f7 python:3 "/bin/bash" 3 minutes ago Up 3 minutes gallant_mahavira
Jeśli chcemy zobaczyć wszystkie zapisane kontenery, należy użyć docker ps
z przełącznikiem -a
lub dłuższą wersją --all
.
> docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES faf92be3b289 python:3 "python3" 4 minutes ago Up 4 minutes zealous_shirley 2a688789b5f7 python:3 "/bin/bash" 7 minutes ago Exited (0) 2 seconds ago gallant_mahavira f8618196f0e2 python:3 "bash" 7 minutes ago Exited (0) 4 minutes ago affectionate_babbage 93fad0d3e0ee python:3 "bash" 10 minutes ago Exited (0) 9 minutes ago determined_cori 7a5e7a241689 python:3 "python3" 15 minutes ago Exited (0) 12 minutes ago cranky_hermann
Zniszczenie kontenera
By zniszczyć kontener, należy użyć komendy docker rm
. Jako argumenty można podać zarówno ID kontenera, jak i jego nazwę. Docker domyślnie generuje nazwę kontenera z listy losowych przymiotników i rzeczowników. Niemniej możemy sami nadać kontenerowi nazwę.
Korzystając z wyjścia poprzedniej komendy docker ps -a
, wybrałem obrazy do usunięcia.
> docker rm faf92be3b289 gallant_mahavira affectionate_babbage 93fad0d3e0ee 7a5e7a241689 faf92be3b289 gallant_mahavira affectionate_babbage 93fad0d3e0ee 7a5e7a241689
Po tym zabiegu ponownie wykonana komenda docker ps -a
zwróci nam pustą listę.
Listowanie i usuwanie obrazów kontenerów
Do listowania obrazów służy polecenie docker images
.
> docker images REPOSITORY TAG IMAGE ID CREATED SIZE python 3 34a518642c76 3 weeks ago 929MB python latest 34a518642c76 3 weeks ago 929MB
By usunąć obraz kontenera, należy użyć docker rmi
wraz z ID obrazu.
> docker rmi 34a518642c76 Untagged: python:latest Untagged: python@sha256:9e0b4f32487ca1863b45383420b8db77990debae748e2e875d2f86fa9510d4a5 Deleted: sha256:34a518642c76e77f0cace72bd993352ac99802c3295931f70a407b735ecb6e27 ...(wyjście skrócone) Deleted: sha256:0db06dff9d9aeb9bed4edde7bd772ad0f3aea497c129d48ed587664d098c6c41
Zakończenie
W artykule udało się przedstawić prosty, lecz pełny scenariusz korzystania z Dockera. Oprócz prostych i podstawowych informacji, jak na przykład instalacja Dockera-CE, poruszyliśmy też bardziej zaawansowane tematy, jak konfiguracja serwisu daemona dockerd z poziomu systemd.
W następnej części przyjrzymy się jeszcze bardziej zaawansowanym tematom związanym z Dockerem. Między innymi wypuszczaniem zadanego portu kontenera na świat, montowaniem volumenów czy wersjonowaniem obrazów.
Chcesz być na bieżąco? Obserwuj nasz profil w serwisie LinkedIn.