Docker – instalacja oraz zarządzanie

docker logoDocker to zyskująca coraz większą popularność aplikacja, podchodząca w ciekawy sposób do tematu wirtualizacji. Przy jej pomocy uruchamiamy nie całe maszyny wirtualne (wraz z systemem operacyjnym), tylko aplikację/program (tzw. kontener). Kontenery nie zajmują dużo miejsca i uruchamiają się bardzo szybko. Dodatkowo korzystają one z systemu plików działającym w trybie Copy-on-Write, przez co tworząc nowy kontener, docker nie kopiuje całego kontenera, a jedynie pliki które zostały zmodyfikowane.
Jeśli potrzebujemy np. bazy danych MySQL w wersji 5.6, wystarczy pobrać odpowiedni obraz (lub samemu zbudować) ze strony https://hub.docker.com/. Jeśli nie znajdziemy tego co chcemy, możemy ściągnąć bazowy system (np. obraz Ubuntu 15.04) doinstalować to co chcemy i następnie stworzyć własny obraz. Jeśli nie będzie nam już więcej potrzebny, usuwamy go i po sprawie. Każdy kontener możemy też dostosować do własnych potrzeb, np. doinstalować jakiś pakiet lub uruchomić na nim jakąś dodatkową usługę. Z założenia jednak każdy kontener powinien obsługiwać tylko jedną usługę. Przykładowo chcemy stworzyć nową stronę www (PHP + MySQL). Aby przetestować nasz kod potrzebujemy serwera www. Przy pomocy dockera łatwo uruchomimy serwer www używając 2 różnych kontenerów. Jeden będzie obsługiwał bazę danych, drugi- serwer apache wraz z PHP. Następnie łączymy (linkujemy) je ze sobą, a pliki strony mapujemy z naszego lokalnego dysku hosta. Zaletą takiego rozwiązania jest to, że jeśli chcemy przetestować nasz projekt korzystając z innej wersji PHP, wystarczy że ściągniemy odpowiedni obraz (tag) i ponownie uruchomimy kontenery.

Docker – instalacja w systemie CentOS

Skupimy się tutaj na instalacji w systemie CentOS 7, dokładne instrukcje jak zainstalować dockera pod innymi systemami można znaleźć w oficjalnej dokumentacji. Program możemy dodać korzystając z dostępnego repozytorium lub skryptu instalacyjnego. Wybierzemy opcję numer 1.

tee /etc/yum.repos.d/docker.repo <<-'EOF'
[dockerrepo]
name=Docker Repository
baseurl=https://yum.dockerproject.org/repo/main/centos/$releasever/
enabled=1
gpgcheck=1
gpgkey=https://yum.dockerproject.org/gpg
EOF 

Następnie instalujemy pakiet docker-engine:

yum install docker-engine

oraz uruchamiamy usługę:

systemctl start docker

Jeśli chcemy, żeby docker startował automatycznie z naszym systemem wpisujemy:

systemctl enable docker
systemctl is-enabled docker
enabled

Sprawdzamy czy daemon działa:

docker version
Client:
 Version:      1.8.2
 API version:  1.20
 Package Version: docker-1.8.2-7.el7.centos.x86_64
 Go version:   go1.4.2
 Git commit:   bb472f0/1.8.2
 Built:        
 OS/Arch:      linux/amd64

Server:
 Version:      1.8.2
 API version:  1.20
 Package Version: 
 Go version:   go1.4.2
 Git commit:   bb472f0/1.8.2
 Built:        
 OS/Arch:      linux/amd64

Jeżeli nie chcemy działać z konta root (lub poprzez sudo) wystarczy dodać naszego użytkownika do grupy docker:

usermod -aG docker nasz_user
id nasz_user
uid=1001(nasz_user) gid=1002(nasz_user) groups=1002(nasz_user),993(docker)

Uruchamiamy i zarządzamy kontenerem

Przejdźmy do części praktycznej, ściągniemy z Docker Hub obraz Ubuntu:

docker pull ubuntu

Domyślnie dostaniemy obraz oznaczony tagiem latest, jeśli potrzebujemy wersji 12.04 wpisujemy:

docker pull ubuntu:12.04

Korzystając z poniższego polecenia możemy wyświetlić wszystkie dostępne obrazy (na dysku twardym):

docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
docker.io/ubuntu    latest              ca4d7b1b9a51        3 weeks ago         187.9 MB
docker.io/ubuntu    12.04               04c3793b1229        3 weeks ago         136 MB

Kolejny krok to uruchomienie kontenera

docker run ubuntu:12.04

Ok... problem w tym, że tak naprawdę nic się nie stało. Nasz kontener uruchomił się i natychmiast zakończył swoje działanie, ponieważ nie przekazaliśmy mu żadnego polecenia. Spróbujmy jeszcze raz tym razem jako argument podając jakieś polecenie:

[root@docker tech-itcore-000]# docker run ubuntu:12.04 cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=12.04
DISTRIB_CODENAME=precise
DISTRIB_DESCRIPTION="Ubuntu 12.04.5 LTS"
[root@docker tech-itcore-000]# docker run ubuntu cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=14.04
DISTRIB_CODENAME=trusty
DISTRIB_DESCRIPTION="Ubuntu 14.04.3 LTS"

Wygląda lepiej, po wykonaniu polecenia kontener jest natychmiast zatrzymywany. Spróbujmy dostać się do powłoki kontenera:

docker run -it ubuntu:12.04

root@15c48dfe8ea7:/# cat /etc/lsb-release 
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=12.04
DISTRIB_CODENAME=precise
DISTRIB_DESCRIPTION="Ubuntu 12.04.5 LTS"

Parametr -t przydziela dockerowi konsolę, natomiast -i mówi, by docker działał w trybie interaktywnym. Korzystając z polecenia docker ps zobaczymy wszystkie aktualnie uruchomione kontenery. Warto zaznaczyć, że po każdym uruchomieniu (run) tworzony jest nowy kontener z unikalnym identyfikatorem (CONTAINER ID):

docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
76e9c17fc816        ubuntu:12.04        "/bin/bash"         30 seconds ago      Up 29 seconds                           loving_torvalds

lub jeśli chcemy wyświetlić wszystkie, które zostały utworzone w naszym systemie:

docker ps -a
CONTAINER ID        IMAGE                                COMMAND                  CREATED              STATUS                      PORTS                                                                                                                            NAMES
76e9c17fc816        ubuntu:12.04                         "/bin/bash"              About a minute ago   Up About a minute                                                                                                                                            loving_torvalds
1b8ebfaa46ac        ubuntu                               "/bin/bash"              2 minutes ago        Exited (0) 2 minutes ago                                                                                                                                     boring_goodall
e6ab8d0343e8        ubuntu                               "cat /etc/lsb-release"   3 minutes ago        Exited (0) 3 minutes ago                                                                                                                                     thirsty_tesla
f2a913a7d6a0        ubuntu:12.04                         "cat /etc/lsb-release"   3 minutes ago        Exited (0) 3 minutes ago                                                                                                                                     admiring_wright
b0707f3cb095        ubuntu:12.04                         "lsb_release -a"         3 minutes ago        Created           

Korzystając z polecenia docker rm możemy usunąć wybrany kontener (musimy podać jego ID), przy pomocy docker rmi usuwamy obraz:

docker rm 76e9c17fc816  # usuwa kontener
docker rmi ubuntu       # usuwa obraz

Uwaga jeżeli w naszym systemie wciąż mamy kontenery korzystające z danego obrazu, nie uda nam się go usunąć:

docker rmi ubuntu:12.04                                                                                                                                                             
Error response from daemon: Conflict, cannot delete 04c3793b1229 because the container b0707f3cb095 is using it, use -f to force
docker rmi -f ubuntu:12.04                                                                                                                                                          
Untagged: ubuntu:12.04
Deleted: 04c3793b12299e58bb9c47bc75a51dfb0e0421a97a319d1fc897e430bd44af58
Deleted: 259b021ba9cd3ed978d537d7f65f4d2f4a080787b778a8ad46b0122e2d769a54
Deleted: 5bc08cfeaf2ba4931bc9d54351cce660759e3fc20c2b2cb8ef6b8ec0d8116787
Deleted: e31e0d7aee0f34af6f896fd941ceb052d2cf40cb6661df1f86d2ee01bd24cde1
docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
docker.io/ubuntu    latest              ca4d7b1b9a51        3 weeks ago         187.9 MB

Budujemy własny obraz (Dockerfile)

Mamy już obrazy, jednak powiedzmy że chcemy doinstalować serwer www. Możemy albo znaleźć gotowy obraz, albo zbudować własny. Tutaj przychodzi z pomocą tzw. Dockerfile, w którym definiujemy zestaw instrukcji (poleceń), które mówią dockerowi co ma zrobić z naszym obrazem.

FROM centos:6
MAINTAINER  ITCore 
RUN yum -y upgrade && yum -y install httpd && yum clean all

ADD start-httpd.sh /start-httpd.sh
RUN chmod -v +x /start-httpd.sh

CMD ["/start-httpd.sh"]

W pierwszej linijce definiujemy z którego obrazu chcemy skorzystać jako "bazy" dla naszego projektu. Pole MAINTAINER jest przydatne jeśli będziemy chcieli wrzucić nasz obraz do docker hub. W trzeciej linijce zlecamy docker'owi aktualizację systemu, a następnie doinstalowanie pakietu httpd oraz usunięcie cache'u. W kolejnym kroku dodajmy skrypt start-httpd.sh (który znajduje się na naszym lokalnym dysku) do kontenera oraz nadajemy mu odpowiednie prawa. Na końcu definiujemy, aby nasz skrypt został uruchomiony automatycznie po starcie kontenera.
Poniżej zawartość pliku start-httpd.sh:

#!/bin/bash
rm -rf /run/httpd/*
exec /usr/sbin/apachectl -D FOREGROUND

Wszystko przygotowane, czas na zbudowanie obrazu:

docker build -t tech-itcore/centos6-httpd .

Cały proces zajmuje trochę czasu, w konsoli widzimy też kolejne kroki wykonywane podczas procesu budowania obrazu:

Sending build context to Docker daemon 3.072 kB
Step 1 : FROM centos:6
 ---> 1a895dd3954a
Step 2 : MAINTAINER ITCore
....
Step 3 : RUN yum -y upgrade && yum -y install httpd && yum clean all
...
Step 4 : ADD start-httpd.sh /start-httpd.sh
...
Step 5 : RUN chmod -v +x /start-httpd.sh
...
Step 6 : CMD /start-httpd.sh
docker images
REPOSITORY                                     TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
tech-itcore/centos6-httpd                      latest              11bd03750c7d        7 minutes ago       414.9 MB

Uruchamiamy nasz świeży obraz:

docker run tech-itcore/centos6-httpd
httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.30 for ServerName
docker ps
CONTAINER ID        IMAGE                       COMMAND             CREATED             STATUS              PORTS               NAMES
dc2d9a6a23f3        tech-itcore/centos6-httpd   "/start-httpd.sh"   2 minutes ago       Up 2 minutes                            sick_blackwell

Wszelkie logi, które kontener wysyła na standardowe wyjście, wyświetlają nam się od razu na konsoli. Możemy też skorzystać z polecenia docker logs

docker logs dc
httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.30 for ServerName

docker inspect zwraca nam też wiele ciekawych informacji na temat kontenera (np. adres MAC lub IP):

docker inspect dc | grep -i ipaddress
        "IPAddress": "172.17.0.30",
        "SecondaryIPAddresses": null,

Kontenerowi przydzielony został adres 172.17.0.30, zobaczmy czy apache nasłuchuje na porcie 80:

links http://172.17.0.30 -dump
                               Apache 2 Test Page
                               powered by CentOS

   This page is used to test the proper operation of the Apache HTTP server
   after it has been installed. If you can read this page it means that the
   Apache HTTP server installed at this site is working properly.

Zatrzymując kontener i uruchamiając nowy docker przydzieli mu dynamicznie nowy adres IP:

docker stop dc
docker run tech-itcore/centos6-httpd
httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.31 for ServerName
docker ps
CONTAINER ID        IMAGE                       COMMAND             CREATED             STATUS              PORTS               NAMES
c5f89e093565        tech-itcore/centos6-httpd   "/start-httpd.sh"   2 minutes ago       Up 2 minutes                            fervent_bohr
[root@docker tech-itcore-000]# docker inspect c5 | grep -i ipaddress
        "IPAddress": "172.17.0.31",
        "SecondaryIPAddresses": null,

Przy pomocy docker'a możemy też przekierować port wybranego kontenera na lokalny adres IP i port.

docker run -p 8080:80 tech-itcore/centos6-httpd 

Zakładając, że lokalny PC ma adres IP 192.168.100.100, powinniśmy mieć dostęp do serwera www poprzez port 8080:

links http://192.168.100.100:8080 -dump | head -n 3
                               Apache 2 Test Page
                               powered by CentOS

Jeżeli planujemy uruchomić więcej kontenerów, a następnie połączyć je między sobą (zlinkować) przydatna może być opcja EXPOSE, która udostępnia usługę działającą na danym porcie innym kontenerom:

FROM centos:6
MAINTAINER  ITCore 

RUN yum -y upgrade && yum -y install httpd && yum clean all

# Simple startup script to avoid some issues observed with container restart 
ADD start-httpd.sh /start-httpd.sh
RUN chmod -v +x /start-httpd.sh

EXPOSE 80

CMD ["/start-httpd.sh"]

To tyle tytułem wstępu. W następnym artykule przedstawimy bardziej "życiowy" przykład użycia docker'a. Zbudujemy i połączymy ze sobą 2 kontenery (webserver oraz baza danych), udostępnimy lokalny katalog kontenerowi oraz zainstalujemy wordpressa.

Zostaw komentarz


Podpowiedź - możesz użyć tych HTML tagów i atrybutów:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

Obraz CAPTCHY

*