Aby Docker był użyteczny musi mieć możliwość konfigurowania połączeń między kontenerami oraz przekierowania portów z hosta do kontenera. Równie ważne jest, aby określone dane naszego kontenera, które chcemy zachować nie zostały usunięte po wyłączeniu kontenera. Funkcjonalność tą zapewniają sieci i wolumeny.
Sieci
Domyślnie Docker tworzy trzy sieci. Aby zobaczyć listę dostępnych sieci wykonujemy następujące polecenie:
docker network lsWynik takiego polecenie u mnie zaraz po zainstalowaniu Dockera na Windows 7 wygląda następująco:
NETWORK ID NAME DRIVER SCOPE eeb9f462e641 bridge bridge local e460abd29cbf host host local 3eb86933ba06 none null local
Domyślnie Docker łączy kontener z siecią o nazwie i typie bridge. Oczywiście możemy połączyć kontener z dowolną siecią dodając do docker run parametr –net co zobrazowano w następującym poleceniu:
docker run –it --net=host ubuntu /bin/bash
Podłączenie kontenera do sieci host powoduję, że będzie on współdzielił porty i adresy IP hosta. Podłączenie kontenera do sieci none spowoduję, że kontener będzie miał tylko interfejs pętli zwrotnej loopback. Podłączenie kontenera do sieci typu bridge spowoduję, że kontenery będące w tej samej sieci będą się mogły pingować a kontenery będące w innych sieciach już nie. Aby zobaczyć informację o danej sieci wykonujemy następujące polecenie:
docker network inspect [nazwa_sieci]
W wynikach tego polecenia zobaczymy przykładowo takie informacje jak adresacja wykorzystywana dla danej sieci typu bridge.
Oczywiście możemy stworzyć więcej sieci w zależności od naszych wymagań. Aby stworzyć nową sieć typu bridge wykonujemy następujące polecenie:
docker network create [nazwa_nowej_sieci]Sieć usuwamy wykorzystując polecenie:
docker network rm [nazwa_sieci]Jeżeli nasz kontener jest uruchomiony w sieci typu bridge i chcemy poznać jego adres IP to musimy podejrzeć informację o tym kontenerze za pomocą polecenia:
docker inspect [ID kontenera lub nazwa]Polecenie to zwróci nam wszystkie informację o kontenerze, ale możemy je od razu przefiltrować aby zobaczyć tylko interesujący nas adres IP kontenera. Aby to zrobić wykonujemy następujące polecenie:
docker inspect --format='{{.NetworkSettings.IPAddress}}' [ID kontenera lub nazwa]
Publikowanie portu kontenera za pomocą parametru –p
Docker umożliwia udostępnienie usługi działającej na kontenerze poprzez powiązanie określonego portu kontenera z określonym lub wygenerowanym automatycznie portem hosta Dockera. W tym celu możemy wykorzystać jedną z czterech składni:
- -p <port hosta>:<port kontenera>
- -p <port kontenera>
- -p <ip>:<port hosta>:<port kontenera>
- -p <ip>::<port kontenera>
Pierwsza składnia w postaci –p 8080:80 oznacza, że port 8080 naszego hosta będzie powiązany z portem 80 naszego kontenera. W przypadku, gdy uruchomimy kontener z parametrem –p 8080:80 za pomocą polecenia:
docker run -itd -p 80:80 ubuntu:16.04 /bin/bash
Następnie przyjrzymy się wynikowi wylistowania aktywnych kontenerów za pomocą polecenia docker ps:
docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES d5548eb33ecf ubuntu:16.04 "/bin/bash" 4 seconds ago Up 2 seconds 0.0.0.0:8080->80/tcp laughing_chandrasekhar
Ja widzimy w wynikach pojawił się następujący wpis 0.0.0.0:8080->80. Znaczy on tyle, że port 8080 naszego hosta jest połączony z portem 80 naszego kontenera. Adres 0.0.0.0 jest meta adresem reprezentującym wszystkie adresy IP skonfigurowane w hoście Dockera.
Jeżeli używamy Dockera pod Windows 7 wówczas tak naprawdę używana jest maszyna wirtualna VirtualBox-a (boot2docker) dlatego adresy którego się tycz meta adres 0.0.0.0 odnoszą się do adresów maszyny wirtualnej. Odpalając terminal Dockera pod Windows 7 będziemy mieli wyświetloną informację o nazwie maszyny wirtualnej i jej adresie IP. Na poniższym obrazie nazwa i adres jest na zielono i w moim przypadku maszyna nazywa się default a adres IP to 192.168.99.100.
Adres ten możemy również sprawdzić wykonując następujące polecenie:
docker-machine ip
Druga składnia w postaci –p 80 oznacza, że port po stronie hosta zostanie wygenerowany automatycznie i zostanie powiązany z portem 80 kontenera. Numer portu możemy oczywiście zobaczyć listując kontenery analogicznie jak powyżej.
Trzecia składnia w postaci -p 10.0.0.10:8080:80 oznacza, że port 80 kontenera zostanie powiązany z portem 8080 hosta ale tylko na adresie 10.0.0.10. Listując kontenery zamiast 0.0.0.0 będziemy mieli 10.0.0.10 z racji powiązania już tylko z jednym adresem IP.
Czwarta składnia w postaci -p 10.0.0.10::80 oznacza, że port 80 kontenera zostanie powiązany z automatycznie wygenerowanym portem ale tylko na adresie 10.0.0.10. W takiej sytuacji listując kontenery zobaczymy wynik podobny do 10.0.0.10:32768->80.
Wiązanie portów może zostać również wykonane za pomocą instrukcji EXPOSE użytej w pliku Dockerfile. Jednak, aby wiązanie zadziałało trzeba dodać do docker run parametr –P ponieważ sama instrukcja EXPOSE nie może aktywować wiązania portów.
Udostępnianie danych hosta
Katalogi oraz pliki hosta mogą być udostępnione jako wolumeny danych tylko podczas uruchamiania kontenera. Do tego celu używamy parametru –v. Składnia przy użyciu parametru –v jest następująca:
- -v <ścieżka kontenera>
- -v <ścieżka hosta>:<ścieżka kontenera>
- -v <ścieżka hosta>:<ścieżka kontenera>:<tryb zapis i odczyt>
- -v <nazwa woluminu>:<ścieżka kontenera>
- -v <nazwa woluminu>:<ścieżka kontenera>:<tryb zapis i odczyt>
Załóżmy, że odpaliliśmy kontener za pomocą następującego polecenia:
docker run -it -v /MountTest ubuntu:16.04
wówczas Docker stworzy w katalogu Volumes znajdującym się na hoście folder, który zostanie powiązany z katalogiem /MountTest który zostanie utworzony automatycznie w kontenerze. Jeżeli teraz odpalimy kontener i zapiszemy coś w lokalizacji /MountTest to dane te będą się znajdowały też na hoście. Dokładną nazwę i lokalizację wolumenu możemy zobaczyć w wynikach następującego polecenia:
docker inspect [ID kontenera lub nazwa]
Jeżeli usuniemy kontener to folder na hoście o którym pisaliśmy nadal pozostanie na dysku hosta wraz z danymi w nim zapisanymi przez kontener. Jeżeli nie potrzebujemy już tych danych wówczas usuwając kontener możemy dodać parametr –v, co spowoduje usunięcie automatycznie stworzonego wolumenu:
docker rm –v [ID kontenera lub nazwa]
Jeżeli kontener nadal pracuje a chcemy go usunąć wraz wolumenem automatycznie utworzonym wówczas należy wykonać następujące polecenie:
docker rm –fv [ID kontenera lub nazwa]Jeżeli odpalimy następujące polecenie:
docker run -it -v /hostFolder:/MountTest ubuntu:16.04
wówczas zawartość folderu hosta zlokalizowana w /hostFolder będzie dostępna z poziomu kontenera w lokalizacji /MountTest.
Możemy ograniczyć uprawnienia tak, aby były tylko do odczytu(ro) wykonując następujące polecenie:
docker run -it -v /hostFolder:/MountTest:ro ubuntu:16.04Trzeci sposób polega na utworzeniu wolumenu. Aby utworzyć nowy wolumen wykonujemy następujące polecenie:
docker volume create [nazwa_wolumenu]Aby wylistować wszystkie wolumeny wykonujemy następujące polecenie:
docker volume lsAby sprawdzić, w którym miejscu wolumen zapisuje dane wykonujemy następujące polecenie:
docker volume inspect [nazwa_ wolumenu]Aby usunąć wolumen wykonujemy następujące polecenie:
docker volume rm [nazwa_ wolumenu]Aby usunąć wszystkie nieużywane wolumeny wykonujemy następujące polecenie:
docker volume pruneW przypadku użycia prune trzeba uważać, ponieważ zostaną usunięte te wolumeny, które aktualnie nie są podpięte do żadnego kontenera i będą to zarówno wolumeny stworzone automatycznie jak i ręcznie.
Udostępnianie danych pomiędzy kontenerami
Jeżeli wykonamy dwa następujące polecenia używając w drugim polecenia –volumes-from w następujący sposób:
docker run -it --name=ww1 -v /test:/MountTest ubuntu:16.04 docker run -it --name=ww2 --volumes-from ww1 ubuntu:16.04Wówczas zarówno kontener ww1 jak i ww1 będą miały katalog /MountTest.
Bardzo fajnie napisane. Jestem pod wrażeniem i pozdrawiam.
OdpowiedzUsuń