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:

  1. Uruchomienie kontenera z wymaganą konfiguracją
  2. Wykonanie zadania/zestawu zadań
  3. 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:

yum install -y yum-utils device-mapper-persistent-data lvm2

Dodanie repozytorium dockera:

yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

Instalacja i uruchomienie docker:

yum install docker-ce
systemctl start docker

Możemy sprawdzić czy nasz docker działa poprawnie uruchamiając ponadczasowe “Hello World”

docker run hello-world

W odpowiedzi dostaniemy:

[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:

​[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:

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

docker stop -t 20  CTID

Trzeci – zatrzymanie twarde, czyli zmuszenie do zakończenia procesów:

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):

docker

Robimy porządki, czyli usuwanie kontenerów i obrazów
Listę wszystkich kontenerów uzyskamy wpisując:

docker ps -a

Jeśli chcemy usunąć konkretny kontener:

docker rm CTID

Listę wszystkich obrazów uzyskamy poleceniem:

docker images

Usuwanie obrazu:

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:

[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ą:

[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:

[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:

[root@localhost ~]# docker exec 85f829476c3a /bin/bash -c cat /etc/issue
[root@localhost ~]# 

Logi

Aby sprawdzić logi wygenerowane przez aplikacje uruchomione w kontenerze podajemy:

 docker logs 85f829476c3a

Jeśli nie chcemy korzystać z systemu logowania dockera możemy przy tworzeniu kontenera kazać zapisywać logi do syslog-u serwera:

--log-driver=syslog

zapisywać je na zdalny serwer:

--log-opt syslog-address=tcp://192.168.56.40:123

lub wyłączyć zapisywanie jakichkolwiek logów:

--log-driver=none

Statystyki

Podstawowe statystyki ( analogiczne do programu top), czyli użycie cpu,ram i łącza otrzymamy wpisując:

[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 🙂

[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:

docker-cadvisor

 

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 🙂

5 (100%) Ocen: 2