Red Hat 7.x / CentOS 7.x
Docker to nowe spojrzenie na wirtualizację. Zamiast tradycyjnych maszyn wirtualnych wprowadza on niezależnie działające kontenery usług oparte o środowisko gospodarza, co zwiększa wydajność i elastyczność środowiska. Teorię można sobie doczytać w internecie, a nic tak nie przybliża do technologii, jak ćwiczenia praktyczne, więc bez zbędnych wstępów zaczynamy.Instalacja
Jako środowiska bazowego używać będę systemu CentOS 7.2. Poza lokalizacją plików konfiguracyjnych dockera i procesem instalacji samo używanie go w tym srodowisku nie róźni się od innych platform.Instalację możemy wykonać na trzy sposoby
- używając yum oraz systemowego repozytorium - yum install docker - w ten sposób instalujemy wersję zatwierdzoną przez CentOSa/Red Hata
- używając yum i konfigurując repozytorium dockera
- korzystając ze skryptu instalacyjnego dockera, który doda nam repozytorium i zainstaluje binaria curl -fsSL https://get.docker.com/ | sh
Jeśli zależy nam na aktualnej wersji najlepiej będzie użyć metody trzeciej, a jeśli wystarczy nam wersja wcześniejsza, ale "wygrzana" skorzystać możemy z metody pierwszej. Ja skorzystam z pierwszej.
[root@docker-base ~]# yum install docker
Możemy zweryfikować wersję zainstalowanego pakietu poprzez:
[root@docker-base ~]# docker --version
Docker version 1.8.2-el7.centos, build a01dc02/1.8.2
Docker version 1.8.2-el7.centos, build a01dc02/1.8.2
Aby nie działać na koncie root-a, ale z drugiej strony nie robić wszystkiego przez sudo możemy dodać swojego użytkownika do grupy docker poprzez usermod -aG docker nasz_user. Jeśli grupa nie istnieje, należy ją utworzyć (groupadd docker).
Domyślnie serwis dockera nie jest wystartowany, więc trzeba do wystartować i zadbać, żeby startował wraz z systemem:
[root@docker-base ~]# systemctl enable docker
[root@docker-base ~]# systemctl start docker
[root@docker-base ~]# systemctl start docker
I tu w zasadzie kończy się pierwszy etap - docker jest gotowy do użycia.
Zarządzanie kontenerami
Podstawowym poleceniem dockera, którego używać będziemy najczęściej jest wyświetlanie kontenerów działających na naszym hoście:
[docker@docker-base ~]$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
W wyniku jego wywołania uzyskamy listę działających w środowisku kontenerów. Lista jest wyświetlana w postaci kolumn, które oznaczają odpowiednio:
CONTAINER_ID - identyfikator uruchomionego kontenera
IMAGE - identyfikator obrazu z którego kontener został uruchomiony (o obrazach później)
COMMAND - polecenie wykonywane wewnątrz kontenera podczas jedo inicjalizacji
CREATED - czas utworzenia kontenera
STATUS - obecny status kontenera
PORTS - wykaz mapowanych do kontenera portów (opiszę przy okazji sieci w ramach kontenerów)
NAMES - nazwa naszego kontenera
Polecenie to posiada jeszcze jeden często używany przełącznik docker ps -a, który wyświetla wszystkie kontenery w systemie - również te z różnych powodów nieaktywne.
Jako, że temat zarządzania kontenerami jest ściśle powiązany z innym aspektem - zarządzaniem obrazami - na pierwszy rzut oka polecenia mogą nasuwać wiele pytań. Póki co przyjmij składnię jako pewnego rodzaju kanon, a wszystko rozjaśni się po poznaniu tematu obrazów. Temat ten jest szeroki, więc pewnie pojawi się w osobnym wpisie.
Na początek całą naszą pracę oprzemy o kontener, który dostarczy nam niewielki system operacyjny o nazwie busybox. Rozpocznijmy więc naszą przygodę.
Uruchamianie nowego kontenera
Jako, że tekst jest początkiem początków przygody z Dockerem nie będę tu przedstawiał wszystkich przydatnych opcji uruchomienia kontenera (pewnie później pojawi się zbiorówka tych opcji w osobnym tekście), a jedynie te niezbędne do uruchomienia najprostrzego funkcjonalnego kontenera.
Każdy kontener uruchamiany jest w naszym systemie na bazie posiadanych przez nas obrazów. Obrazy takie - jeśli jeszcze nie istnieją w lokalnym repozytorium są pobierane przez serwer dockera z oficjalnego repozytorium. Proces ten powoduje, że uruchomienie pierwszej instancji kontenera może trwać dość długo, ale nie należy się tym zrażać.
Podstawowa składnia uruchamiająca kontener wyglądanastępująco: docker run nazwa_obrazu. Zastosujmy ją więc praktycznie, opierając się o rzeczywisy obraz systemu wymienianego wcześniej:
[docker@docker-base ~]$ docker run busybox
Unable to find image 'busybox:latest' locally
Trying to pull repository docker.io/library/busybox ... latest: Pulling from library/busybox
56ed16bd6310: Extracting [==================================================>] 676 kB/676 kB
bc744c4ab376: Download complete
Unable to find image 'busybox:latest' locally
Trying to pull repository docker.io/library/busybox ... latest: Pulling from library/busybox
56ed16bd6310: Extracting [==================================================>] 676 kB/676 kB
bc744c4ab376: Download complete
Jak zaobserwujemy docker pobiera sobie obraz busybox, aby uruchomić kontener. Po zakończeniu procesu moglibyśmy się spodziewać, że zastaniemy uruchomiony kontener z systemem busybox - sprawdźmy zatem:
[docker@docker-base ~]$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
Pusto. Pomimo tego co mogłoby się wydawać, proces uruchomienia kontenera przebiegł właściwie. Wyjaśnienie sytuacji jest proste i widoczne w listingu wszystkich kontenerów:
[docker@docker-base ~]$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cf7e33398159 busybox "sh" 3 minutes ago Exited (0) 3 minutes ago dreamy_morse
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cf7e33398159 busybox "sh" 3 minutes ago Exited (0) 3 minutes ago dreamy_morse
Zrzut ten pokazuje nam, że kontener został utworzony 3 minuty wcześniej, a w chwili obecnej ma status Exited(0). Kontener wyłączył się, ponieważ operacją jaką miał za zadanie wykonać była egzekucja komendy sh. Udało się ją wykonać, więc kontener zrobił co miał do zrobienia i przestał być potrzebny.
Mój pierwszy kontakt z kontenerami opraty był na tym przykładzie, i szczerze mówiąc bardziej oddalał mnie od tej technologii niż do niej zbliżał. Po co komu "twór", który po uruchomieniu wchodzi do sh i się wyłącza? Kolejny wykopany przykład użycia był równie bezsensowny:
[docker@docker-base ~]$ docker run busybox echo "Echo kontrolne"
Echo kontrolne
[docker@docker-base ~]$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2033115ffe8c busybox "echo 'Echo kontrolne" 3 minutes ago Exited (0) 3 minutes ago berserk_brown
cf7e33398159 busybox "sh" 13 minutes ago Exited (0) 13 minutes ago dreamy_morse
Echo kontrolne
[docker@docker-base ~]$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2033115ffe8c busybox "echo 'Echo kontrolne" 3 minutes ago Exited (0) 3 minutes ago berserk_brown
cf7e33398159 busybox "sh" 13 minutes ago Exited (0) 13 minutes ago dreamy_morse
Przykład demonstruje jak przekazywać parametry do kontenera - nakazujemy tu odpalenie kontenera i wykonanie w nim echa... po co to komu? i jak to się ma do maszyny wirtualnej? Kontener znów się wyłączył - wykonał swoje zadanie, więc nie jest już do niczego przydatny....
Przykłady te są chyba najsłabszą reklamą technologii jaką widziałem, dlatego warto o nich szybko zapomnieć. Zróbmy więc coś, co przekona nas do Dockera, i udowodni słuszność koncepcji. Założeniem działania Dockera jest szybkie i niskozasobowe dostarczanie usługi, a dobrym przykładem jego realizacji może być prosty serwer www.
Warto tu poznać pierwsze przydatne opcje komendy docker run, a mianowicie -d - pozwala ona uruchomić kontener w tzw. detached mode, czyli oddzielić działanie kontenera od naszej powłoki shell, oraz -P, które mapuje wszystkie porty kontenera na porty naszego hosta.
Stwórzmy zatem wspomiany kontener hostujący stronę www.
[docker@docker-base ~]$ docker run -d -P httpd
Unable to find image 'httpd:latest' locally
Trying to pull repository docker.io/library/httpd ... latest: Pulling from library/httpd
d8bd0657b25f: Pull complete
a582cd499e0f: Pull complete
4d035354d707: Pull complete
152d136f2b33: Pull complete
36c9fec13bf5: Pull complete
2e56fcbe3fad: Pull complete
ceef08ecfd76: Pull complete
a023717bbace: Pull complete
1fcf3155d7dc: Pull complete
698af7c24a15: Pull complete
cca3d6822dae: Pull complete
c7c39c3750a6: Pull complete
ee4a5faa57f7: Pull complete
Digest: sha256:4aba8de9c396e4f20d682fbc9ee8e06fd91700fdbb88ed36157d6f6487a99da7
Status: Downloaded newer image for docker.io/httpd:latest
22b8aba2db983f1ef6340118ab797a3f8e88680a24e680d3e77c1090264e5357
[docker@docker-base ~]$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
22b8aba2db98 httpd "httpd-foreground" 8 seconds ago Up 6 seconds 0.0.0.0:32768->80/tcp jolly_meitner
Unable to find image 'httpd:latest' locally
Trying to pull repository docker.io/library/httpd ... latest: Pulling from library/httpd
d8bd0657b25f: Pull complete
a582cd499e0f: Pull complete
4d035354d707: Pull complete
152d136f2b33: Pull complete
36c9fec13bf5: Pull complete
2e56fcbe3fad: Pull complete
ceef08ecfd76: Pull complete
a023717bbace: Pull complete
1fcf3155d7dc: Pull complete
698af7c24a15: Pull complete
cca3d6822dae: Pull complete
c7c39c3750a6: Pull complete
ee4a5faa57f7: Pull complete
Digest: sha256:4aba8de9c396e4f20d682fbc9ee8e06fd91700fdbb88ed36157d6f6487a99da7
Status: Downloaded newer image for docker.io/httpd:latest
22b8aba2db983f1ef6340118ab797a3f8e88680a24e680d3e77c1090264e5357
[docker@docker-base ~]$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
22b8aba2db98 httpd "httpd-foreground" 8 seconds ago Up 6 seconds 0.0.0.0:32768->80/tcp jolly_meitner
Analogicznie do poprzedniego kontenera, obrazu httpd nie było w lokalnym repozytorium, więc został pobrany z sieci. Co się zmieniło w stosunku do poprzedniego przykładu? Po pierwsze, kontener działa, po drugie mamy wpis w kolumnie PORTS.
Kontener działa, więc powinien dostarczać nam usługę httpd. Do sprawdzenia tej teorii potrzebny jest nam drugi element - mapowanie portów. Powyższa forma wpisu oznacza, że port 32768 naszego serwera dockerowego jest mapowany na port 80 kontenera. Weryfikacja jest prosta - otwórz przeglądarkę i udaj się pod adres <ip_serwera_docker>:<port_mapowany> - u mnie to 192.168.1.150:32768. Voila. Apache działa!.
Interakcja z kontenerem
Pierwszym pytaniem jakie mi się nasunęło po uruchomieniu kontenera z httpd było mniej więcej "jak się dostać do środka i zmienić domyślną zawartość index.html". Okazuje się, że są przynajmniej dwie metody podłączenia się z systemem w kontenerze (patrząc z poziomu dockera).
Pierwszą z nich jest docker attach - metoda działa kiedy kontener uruchamia się z aktywnym shellem, i szybko przestałem z niej korzystać.
Druga, to docker exec.
Do podłączenia się do kontenera musimy znać jego id lub nazwę - z pomocą przychodzi nam tu docker ps .
[docker@docker-base ~]$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b399b5f6b2ce httpd "httpd-foreground" 5 seconds ago Up 4 seconds 0.0.0.0:32769->80/tcp silly_sinoussi
[docker@docker-base ~]$ docker exec -it silly_sinoussi bash
root@b399b5f6b2ce:/usr/local/apache2#
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b399b5f6b2ce httpd "httpd-foreground" 5 seconds ago Up 4 seconds 0.0.0.0:32769->80/tcp silly_sinoussi
[docker@docker-base ~]$ docker exec -it silly_sinoussi bash
root@b399b5f6b2ce:/usr/local/apache2#
Polecenie docker exec pozwala na wywołanie wenątrz kontenera komendy podawanej jako argument. Przy interaktywnym podłączeniu istotne są przełączniki użyte powyżej: -i pozwala na interakcję podłączając do kontenera STDIN, -t natomiast uruchamia pseudo terminal TTY dla kontenera. Wewnątrz kontenera poruszamy się tak, jak w zwykłym systemie operacyjnym.
Muszę tu wspomnieć o jednej właściwości dockera w odniesieniu do interakcji z kontenerem. Przy podłączeniu interaktywnym poprzez docker attach, lub uruchomieniu kontenera od razu z opcjami -it, który przeniesie nas do shella kontenera wyjście z niego przy użyciu standardowego exit lub kombinacji ctrl+d zabije nasz kontener - jeśli tego nie chcemy trzeba wyrobić sobie nawyk używania kombinacji wyjścia dockera ctrl+p ctrl+q
Uruchamianie i zatrzymywanie kontenerów
Pierwsze uruchomienie kontenera dodaje go do naszego inwentarza, który przeglądamy poprzez docker ps -a. Znajdujące się tu kontenery możemy zatrzymywać lub uruchamiać, zależnie od potrzeb.
[docker@docker-base ~]$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b399b5f6b2ce httpd "httpd-foreground" 10 minutes ago Up 3 minutes 0.0.0.0:32770->80/tcp silly_sinoussi
[docker@docker-base ~]$ docker stop b399b5f6b2ce
b399b5f6b2ce
[docker@docker-base ~]$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b399b5f6b2ce httpd "httpd-foreground" 11 minutes ago Exited (0) 4 seconds ago silly_sinoussi
[docker@docker-base ~]$ docker start silly_sinoussi
silly_sinoussi
[docker@docker-base ~]$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b399b5f6b2ce httpd "httpd-foreground" 11 minutes ago Up 1 seconds 0.0.0.0:32771->80/tcp silly_sinoussi
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b399b5f6b2ce httpd "httpd-foreground" 10 minutes ago Up 3 minutes 0.0.0.0:32770->80/tcp silly_sinoussi
[docker@docker-base ~]$ docker stop b399b5f6b2ce
b399b5f6b2ce
[docker@docker-base ~]$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b399b5f6b2ce httpd "httpd-foreground" 11 minutes ago Exited (0) 4 seconds ago silly_sinoussi
[docker@docker-base ~]$ docker start silly_sinoussi
silly_sinoussi
[docker@docker-base ~]$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b399b5f6b2ce httpd "httpd-foreground" 11 minutes ago Up 1 seconds 0.0.0.0:32771->80/tcp silly_sinoussi
Jak widać powyżej, stosowanie ID i nazwy kontenera jest zamienne i uwarunkowane jedynie preferencjami użytkownika. Dodatkowo, dostępne jest również polecenie docker restart restartujące kontener, a także, w przypadku tworów opornych na polecenie stop - docker kill.
Usuwanie kontenerów
Polecenie docker stop zatrzymuje kontener, ale nie usuwa go z naszego systemu. Kontener taki zajmuje ciągle zasoby dyskowe naszego hosta. Oczywiście istnieje możliwość permanentnego usunięcia nieużywanego już kontenera - wykonać to możemy poprzez
[docker@docker-base ~]$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
96d2915d0302 busybox "sh" 3 seconds ago Exited (0) 3 seconds ago jolly_fermat
b399b5f6b2ce httpd "httpd-foreground" 19 minutes ago Up 4 minutes 0.0.0.0:32772->80/tcp silly_sinoussi
[docker@docker-base ~]$ docker rm 96d2915d0302
96d2915d0302
[docker@docker-base ~]$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b399b5f6b2ce httpd "httpd-foreground" 19 minutes ago Up 4 minutes 0.0.0.0:32772->80/tcp silly_sinoussi
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
96d2915d0302 busybox "sh" 3 seconds ago Exited (0) 3 seconds ago jolly_fermat
b399b5f6b2ce httpd "httpd-foreground" 19 minutes ago Up 4 minutes 0.0.0.0:32772->80/tcp silly_sinoussi
[docker@docker-base ~]$ docker rm 96d2915d0302
96d2915d0302
[docker@docker-base ~]$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b399b5f6b2ce httpd "httpd-foreground" 19 minutes ago Up 4 minutes 0.0.0.0:32772->80/tcp silly_sinoussi
Tu również możemy zamiennie stosować id oraz nazwę kontenera.
Przydatne opcje i polecenia
Jednym z pierwszych przełączników jakich szukałem, był ten umożliwiający nadawanie konkretnych nazw kontenerom. Jeśli chcemy postawić kilka maszyn opartych o ten sam obraz, to nazwy typu "jolly_fermat" i "silly_sinoussi" niewiela nam pomogą przy identyfikacji konkretnej maszyny.Do nadawania własnych nazw kontenerów używamy przełącznika --name nazwa_kontenera.
Przydatnymi poleceniami mogą okazać się dwa, pozwalające na zatrzymywanie oraz usuwanie WSZYSTKICH maszyn z dockera.
Do zatrzymania wszystkich kontenerów możemy użyć polecenia docker stop $(docker ps -q).
Usunięcie wszystkich kontenerów zrealizujemy w sposób analogiczny: docker rm $(docker ps -qa)
Osobiście w linuksie bardzo lubię fakt, że jeśli czegoś zapomnę, mogę to w bardziej lub mniej łatwy sposób znaleźć bez korzystania za każdym razem z google. Oczywiście mówię tu o helpach i man-ach dla wszelakich poleceń. Trzeba przyznać, że deweloperzy dockera wpisują się bardzo dobrze w zwyczaje dokumentowania binariów. Szczególnie przydatny jest help do dockera, który skonstruowany jest wielopoziomowo:
docker help wyświetli nam ogólnego helpa
docker help komenda daje helpa dla konkretnej opcji (np. docker help run)
Brak komentarzy:
Prześlij komentarz