Na początku wyjaśnijmy – co to jest Docker?
Docker jest narzędziem pozwalającym umieścić aplikacje w kontenerze – lekkim, przenośnym środowisku które możemy w szybki sposób tworzyć, usuwać i skalować.
Niewątpliwie największą zaletą dockera w porównaniu do znanych nam wirtualizacji ( openvz,xen,kvm) jest to, że nie potrzebuje on specjalnym konfiguracji, instalowania całych systemów operacyjnych tylko korzysta z systemu serwera i tworzy na nim dodatkowe warstwy.
Kontenery są bardzo lekkie gdyż domyślnie nie mają zainstalowanych żadnych pakietów poza tymi które wskażemy podczas instalacji, lub które doinstalujemy samodzielnie. Z zasady kontenery są zawsze bezstanowe, tj nie przechowywują żadnych istotnych danych a przeważnie ich cykl pracy to:
- Uruchomienie kontenera z wymaganą konfiguracją
- Wykonanie zadania/zestawu zadań
- Usunięcie kontenera
Warto zapamiętać by nie traktować kontenerów na równi z wirtualnymi maszynami na których z reguły przechowujemy i składujemy dane.
Instalacja dockera na systemie CentOS 7:
Instalacja wymaganych pakietów:
1 |
yum install -y yum-utils device-mapper-persistent-data lvm2 |
Dodanie repozytorium dockera:
1 |
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo |
Instalacja i uruchomienie docker:
1 2 |
yum install docker-ce systemctl start docker |
Możemy sprawdzić czy nasz docker działa poprawnie uruchamiając ponadczasowe “Hello World”
1 |
docker run hello-world |
W odpowiedzi dostaniemy:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
[root@localhost ~]# docker run hello-world Unable to find image 'hello-world:latest' locally latest: Pulling from library/hello-world d1725b59e92d: Pull complete Digest: sha256:0add3ace90ecb4adbf7777e9aacf18357296e799f81cabc9fde470971e499788 Status: Downloaded newer image for hello-world:latest Hello from Docker! This message shows that your installation appears to be working correctly. To generate this message, Docker took the following steps: 1. The Docker client contacted the Docker daemon. 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. (amd64) 3. The Docker daemon created a new container from that image which runs the executable that produces the output you are currently reading. 4. The Docker daemon streamed that output to the Docker client, which sent it to your terminal. To try something more ambitious, you can run an Ubuntu container with: $ docker run -it ubuntu bash Share images, automate workflows, and more with a free Docker ID: https://hub.docker.com/ For more examples and ideas, visit: https://docs.docker.com/get-started/ |
na marginesie można dodać, że mimo iż docker wymaga wersji jądra minimum 3.1 i pełnej wirtualizacji, to istniały wersje które mogliśmy uruchomić na Openvz z jądrem 2.6
Uruchomienie kontenera
Stwórzmy nasz pierwszy kontener:
1 2 3 4 5 6 7 8 9 10 11 |
[root@localhost ~]# docker run --name="testowy" --rm -ti ubuntu:latest /bin/bash Unable to find image 'ubuntu:latest' locally latest: Pulling from library/ubuntu 124c757242f8: Pull complete 9d866f8bde2a: Pull complete fa3f2f277e67: Pull complete 398d32b153e8: Pull complete afde35469481: Pull complete Digest: sha256:de774a3145f7ca4f0bd144c7d4ffb2931e06634f11529653b23eba85aef8e378 Status: Downloaded newer image for ubuntu:latest root@00ea44300257:/# |
–name=”testowy” ustawia nazwę dla naszego kontenera na “testowy”
–rm – kontener zostanie skasowany po zakończeniu działania
-t – docker przygotuje dla kontenera pseudo TTY
-i – wskazuje, że ma być to sesja interaktywna, tj pozostawiamy otwarte wejście STDIN
ubuntu:latest – informacja jaka dystrybucja ma być pobrana/uruchomiona ( w tym przypadku najnowsza Ubuntu)
/bin/bash – nawa powłoki jaką chcemy mieć po utworzeniu kontenera
Jak widać na serwerze nie było dostępnego obrazu ubuntu – został więc on pobrany, kontener utworzony i zostaliśmy odrazu zalogowani do niego na powłokę /bin/bash
Poleceniem “exit” możemy wyjść z kontenera – ponieważ podaliśmy parametr “–rm” po wyjściu kontener zostanie usunięty.
Inne przydatne parametry przy tworzeniu kontenera to:
–hostname=”mojhostname” – ustawia hostname serwera
-p 80:80 przekierowanie z portu 80 serwera docker na port 80 kontenera
–dns=”8.8.8.8″ – jeśli chcemy używać innych serwerów DNS niż te ustawione na serwerze
-v /mnt/kopia:/kopia – montujemy katalog /mnt/kopia na kontenerze w katalogu /kopia. Uwaga: kontenery to twory ulotne, więc nie zalecam montowania stałych zasobów, gdyż związujemy się w tym momencie z danym serwerem. Polecam używać tej opcji np jeśli chcemy stosować cache w przestrzeni wymiany
–read-only=true – montujemy kontener tylko w trybie do odczytu
–tmpfs /tmp – w przypadku użycia opcji read-only możemy dodatkowo ustawić katalog /tmp jako jedyny zapisywalny
–cpu-shares=1024 – określamy moc cpu. 1024 traktujemy jako 100% wszystkich rdzeni cpu, i w zależności od tego ile chcemy przydzielić mocy ustawiamy ilość punktów cpu
–cpuset=0 – przypisanie kontenera do konkretnego rdzenia cpu ( rdzenie cpu liczymy od zera, w przypadku serwera z 4 rdzeniami cpu możemy ustawić na 0,1,2,3 )
-m 512m – ustawienie ilości pamięci ram i ilości pamięci swap dla kontenera. Obsługiwane jednostki to b,k,m,g. Uwaga: Pamięć ram jest “sztywna”, więc jak serwer ma 64 GB ram a ustawimy dla kontenera 12, to nie użyje więcej niż te 12
–memory-swap=1024m – ustawienie tego parametru wraz z powyższym pozwala na ustawienie osobnej ilości pmięci ram i pamięci wymiany. Ustawienie memory-swap na “-1” wyłącza swap dla kontenera.
Wyłączenie kontenera
Istnieją trzy sposoby na zatrzymanie działania kontenera:
Pierwszy – zatrzymanie “miękkie”, czyli wysłanie sygnału SIGTERM:
1 |
docker stop CTID |
Drugi – zatrzymanie miękkie, a w przypadku gdy po x ( poniżej x=20) sekundach kontener się nie zatrzymał – zatrzymanie “twarde” czyli wysłanie sygnału SIGKILL
1 |
docker stop -t 20 CTID |
Trzeci – zatrzymanie twarde, czyli zmuszenie do zakończenia procesów:
1 |
docker kill CTID |
Szukanie obrazów dockera
Jeśli chcemy znaleść obraz docker możemy wyszukać go w bazie po nazwie – np w przypadku wyszukiwania obrazów debiana ( screen by zachować odpowiednie formatowanie wyniku):
Robimy porządki, czyli usuwanie kontenerów i obrazów
Listę wszystkich kontenerów uzyskamy wpisując:
1 |
docker ps -a |
Jeśli chcemy usunąć konkretny kontener:
1 |
docker rm CTID |
Listę wszystkich obrazów uzyskamy poleceniem:
1 |
docker images |
Usuwanie obrazu:
1 |
docker rmi Images_ID |
Uwaga: Jeśli spróbujemy usunąć obraz używany przez działający kontener otrzymamy komunikat błędu “cannot delete”
Korzystanie z kontenera
Tworzymy i uruchamiany nasz kontener:
1 2 3 4 5 6 7 8 9 10 11 |
[root@localhost ~]# docker create --name="testowy" -ti ubuntu:latest /bin/bash 85f829476c3a4239511cc26a6c59eeec62b84628c4c34e15a9f58d8aff3a89cf [root@localhost ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 85f829476c3a ubuntu:latest "/bin/bash" 5 seconds ago Created testowy [root@localhost ~]# [root@localhost ~]# docker start 85f829476c3a 85f829476c3a [root@localhost ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 85f829476c3a ubuntu:latest "/bin/bash" About a minute ago Up 2 seconds testowy |
Aby wejść w kontener podajemy komendę docker exec wraz z id kontenera i powłoką:
1 2 3 4 5 6 7 |
[root@localhost ~]# docker exec -ti 85f829476c3a /bin/bash root@85f829476c3a:/# exit exit [root@localhost ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 85f829476c3a ubuntu:latest "/bin/bash" 2 minutes ago Up 34 seconds testowy [root@localhost ~]# |
Jeżeli chcemy wydać jakieś polecenie dla kontenera podajemy je w argumencie -c:
1 2 3 |
[root@localhost ~]# docker exec 85f829476c3a /bin/bash -c "cat /etc/issue" Ubuntu 18.04.1 LTS \n \l [root@localhost ~]# |
Ważnym jest by argumenty podawać w cudzysłowiu – inaczej drugi i kolejny argument będą wykonywane na serwerze dockera a nie wewnątrz kontenera co zwróci błędny wynik:
1 2 |
[root@localhost ~]# docker exec 85f829476c3a /bin/bash -c cat /etc/issue [root@localhost ~]# |
Logi
Aby sprawdzić logi wygenerowane przez aplikacje uruchomione w kontenerze podajemy:
1 |
docker logs 85f829476c3a |
Jeśli nie chcemy korzystać z systemu logowania dockera możemy przy tworzeniu kontenera kazać zapisywać logi do syslog-u serwera:
1 |
--log-driver=syslog |
zapisywać je na zdalny serwer:
1 |
--log-opt syslog-address=tcp://192.168.56.40:123 |
lub wyłączyć zapisywanie jakichkolwiek logów:
1 |
--log-driver=none |
Statystyki
Podstawowe statystyki ( analogiczne do programu top), czyli użycie cpu,ram i łącza otrzymamy wpisując:
1 2 3 4 5 |
[root@localhost ~]# docker stats 85f829476c3a CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS 85f829476c3a testowy 0.00% 400KiB / 3.701GiB 0.01% 648B / 0B 0B / 0B 1 ^C [root@localhost ~]# |
Szczegółowe statystyki kontenera można wyciągnąć z poziomu api, a dla osób które chciałyby szybko zobaczyć statystyki w formie graficznej najlepsze będzie wdrożenie…. obrazu dockera 🙂
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
[root@localhost ~]# docker run --volume=/:/rootfs:ro \ --volume=/var/run:/var/run:rw \ --volume=/sys:/sys:ro \ --volume=/cgroup:/cgroup \ --volume=/var/lib/docker:/var/lib/docker:ro \ --publish=8080:8080 --detach=true \ --name=cadvisor google/cadvisor:latest Unable to find image 'google/cadvisor:latest' locally latest: Pulling from google/cadvisor ab7e51e37a18: Pull complete a2dc2f1bce51: Pull complete 3b017de60d4f: Pull complete Digest: sha256:9e347affc725efd3bfe95aa69362cf833aa810f84e6cb9eed1cb65c35216632a Status: Downloaded newer image for google/cadvisor:latest f743c54beadbd53c632597a915fc97b38a506bb94abfde58e63332455321e851 |
Jak widać pobraliśmy i uruchomiliśmy obraz cadvisor – darmowego narzędzia od google do monitorowania kontenerów.
Podczas uruchomienia przekierowaliśmy port 8080 naszego serwera na port 8080 kontenera.
Po wpisaniu adresu http://ip_serwera:8080 przekieruje Nas na http://ip_serwera:808/containers/ i zobaczymy takie oto ładne wykresy:
Podsumowanie
Zainstalowaliśmy dockera, uruchomiliśmy pierwsze kontenery, wiemy już też jak się na nie logować i monitorować.
Jeżeli chciałbyś poznać więcej szczegółów dotyczących konfiguracji dockera – przejrzyj koniecznie jego dokumentację.
W kolejnym wpisie omówimy tworzenie i korzystanie z własnych obrazów – stay tuned 🙂
[…] pierwszej części opisałem proces instalacji, tworzenia i usuwania kontenerów docker. W tej części natomiast […]