Docker w linuksie

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 EuroLinux, Red Hat® Enterprise Linux®, 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.

Autorzy

Artykuły na blogu są pisane przez osoby z zespołu EuroLinux. 80% treści zawdzięczamy naszym developerom, pozostałą część przygotowuje dział sprzedaży lub marketingu. Dokładamy starań, żeby treści były jak najlepsze merytorycznie i językowo, ale nie jesteśmy nieomylni. Jeśli zauważysz coś wartego poprawienia lub wyjaśnienia, będziemy wdzięczni za wiadomość.