Docker – Podstawy
Wstęp do konteneryzacji za nami, opublikowany na blogu został już jakiś czas temu i możecie go znaleźć tutaj. Skoro już wiemy mniej więcej jak to ustrojstwo działa, to już najwyższy czas pobrudzić rączki i postawić sobie jakieś środowisko konteneryzacyjne.
Myślę, że warto rozpocząć swoją przygodę z konteneryzacją od platformy Docker. Jest ona relatywnie prosta, a do jej zrozumienia nie trzeba mieć doktoratu z systemów rozproszonych czy też profesury z Go. W kolejnych artykułach uderzymy w temat Kubernetesa, OpenShift, czy też VMware PKS. Na razie jednak wystartujmy spokojnie i rozgrzejmy się na Docker CE.
Do zabawy potrzebujemy maszyny wirtualnej z Ububtu, może być też inny linuch, to bez różnicy – po prostu będą się różnić komendy. Na początku wystarczy jedna VM, później będzie się to rozrastać jak będziemy rozwijać Laba. Zaczynamy!
Zaczynamy od aktualizacji systemu i instalacji Dockera:
uname -a sudo apt-get -y update sudo apt-get -y upgrade sudo apt-get -y install apt-transport-https ca-certificates curl software-properties-common curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" sudo apt-get -y update sudo apt-get -y install docker-ce sudo docker info
Nie posysamy Dockera z repozytoriów dystrybucji, bo zazwyczaj jest stary i śmierdzący. Trzeba bawić się na nowym sofcie. Zatem dodajemy repozytorium a później instalujemy docker-ce, czyli darmową wersję platformy.
Zdarza się, że potrzebne są zmiany w firewall (jeżeli jest), wykonuje się je następująco:
sudo vi /etc/default/ufw DEFAULT_FORWARD_POLICY="DROP" -> DEFAULT_FORWARD_POLICY="ACCEPT" sudo ufw reload
Po udanej instalacji pozostaje nam wystartować demona docker:
sudo service docker start netstat -npea | grep -i docker ps aux | grep -i docker
Warto tutaj zauważyć, że netstat pokazuje nam zależności sieciowe dot. samego Dockera, jak i później kontenerów. Podobnie ps aux, daje nam to możliwość ubicia procesu odpowiedzialnego za kontener z ręki, gdyby inne bardziej cywilizowane metody zawiodły.
Może to zaskakujące, ale to w zasadzie wszystko, jeśli chodzi o taką podstawową konfigurację. Te kilka komend daje nam w pełni działające środowisko. To dobry moment, aby powołać swój pierwszy kontener… jeszcze tylko wywołacie proszę:
hostname
Komenda ta zwróci ci aktualną nazwę hosta. Zwróć na nią uwagę, wrócimy do tego za chwilę. Tymczasem! Werble, pierwszy kontener:
sudo docker run -i -t ubuntu /bin/bash
Kiedy wywołamy powyższą komendę, uruchomimy pierwszy kontener. Dzięki przełącznikowi -i wskoczymy w tryb interakcji z ni, dzięki przełącznikowi -t zwróci on na nasz ekran swoje standardowe wyjście – czyli zobaczymy co do nas mówi. Kontener oparty będzie o obraz ubuntu zassany domyślnie z Docker Hub (potrzebny dostęp do internetu). Miejsce to jest publicznym rejestrem obrazów, można również wybrać rejestry prywatne, ale o tym później. Uruchomimy w kontenerze komendę /bin/bash. Następnie warto wywołać kilka komend:
hostname
Zwróćcie uwagę, że różni się wynik tej komendy od tej wydanej wcześniej. Dzieje się tak dlatego, że uruchamiając kontener w trybie interaktywnym niejako wskakujemy do niego. Można to porównać do warstw. VM, na której zainstalowaliśmy demona Docker jest warstwą nr 1 nazywaną Docker Engine (DE), warstwą nr 2 jest Kontener. Na obu warstwach możemy mieć różne parametry systemu, różne systemy itp. Zatem siedząc teraz w kontenerze znajdujemy się niejako w innym systemie (pod wieloma względami, acz nie do końca – tutaj znajdziecie więcej o tym). Warto wydać kilka komend, które pokażą nam kilka różnic:
cat /etc/hosts hostname -I ps -aux
Kontener ma własne pliki, własny hostnam, jak również i procesy. Doinstalujmy coś!
apt-get update && apt-get upgrade && apt-get install vim vim
W kontenerze możemy mieć inne programy niż w Docker Engine. Wyjdźmy z kontenera do systemu bazowego komendą:
exit
Pamiętajcie, kontener umiera, gdy z niego wychodzicie w trybie interaktywnym. Zabijacie bowiem proces bash, który jest jedynym powodem jego istnienia. Wywołacie sobie komendę:
sudo docker ps -a
Zobaczcie, że Wasz poprzedni kontener miał nazwę wygenerowaną, teraz czas stworzyć sobie kontener z nazwą:
sudo docker run --name chochlik_1 -i -t ubuntu /bin/bash exit
Ponownie wywołaj:
sudo docker ps -a
Fajnie nie? Mamy naszego stworka! Możemy teraz na nim wywołać kilka operacji:
sudo docker ps -a sudo docker start chochlik_1 sudo docker start [ID] sudo docker attach chochlik_1 sudo docker attach [ID]
Zauważcie, że można to robić zarówno po ID, jak również po nazwie. Komenda attach podłącza nas do kontenera, który już działa coś jak przełączniki -i i -t przy jego starcie. Pamiętajcie, wywołanie komendy exit prowadzi do zabicia kontenera.
Czas na coś bardziej samodzielnego. Uruchommy kontener z zadaniem:
sudo docker run --name chochlik_2 -d ubuntu /bin/sh -c "while true; do echo praca praca; sleep 1; done
Przełącznik -d uruchamia kontener w tle. Po jego odpaleniu zobaczmy, jak wygląda w rejestrze:
sudo docker ps
A teraz jak z niego wyciągnąć informację co robi? Możemy powołać się na logi, niekoniecznie podłączając się do samego standardowego wyjścia:
sudo docker logs chochlik_2 sudo docker logs -f chochlik_2
Pierwsza komenda wyświetli nam logi z momentu jej wywołania. Przełącznik -f, tak jak w przypadku komendy tail daje nam możliwość oglądania ich w czasie rzeczywistym. Możemy je również wysyłać do syslog Docker Engine:
sudo docker run --log-driver="syslog" --name chochlik_3 -d ubuntu /bin/sh -c "while true; do echo praca praca; sleep 1; done" sudo docker logs -f chochlik_3 tail -f /var/log/syslog
Tak jak w normalnym systemie możemy i kontenerki potraktować narzędziami do prostego monitoringu:
sudo docker top chochlik_3 sudo docker stats chochlik_2 chochlik_3
Możemy również z perspektywy DE stworzyć pliki w kontenerze:
sudo docker exec -d chochlik_2 touch /etc/bomba sudo docker exec -t -i chochlik_2 /bin/bash ls -alh /etc/bomba exit
Możemy również zatrzymać kontener:
sudo docker ps -a sudo docker stop chochlik_2 sudo docker stop [ID]
Jak zaczynamy posiadać nieco więcej kontenerów (a dzieje się to nad wyraz szybko) przydadzą nam się komendy z rodziny inspect, poniżej klika przydatnych przykładów:
sudo docker inspect chochlik_3 sudo docker inspect --format='{{ .State.Running }}' chochlik_3 sudo docker inspect --format '{{ .NetworkSettings.IPAddress }}' chochlik_3 sudo docker inspect --format '{{.Name}} {{.State.Running}}' chochlik_2 chochlik_3 sudo ls -alh /var/lib/docker/containers
Ciekawym przełącznikiem jest format, który pozwala wyciągać tylko konkretne informacje z obszernego raportu.
Ciekawym tematem jest ubijanie kontenera – można to robić na kilka sposobów:
sudo docker ps -a sudo docker kill chochlik_3 sudo docker ps -a sudo docker start chochlik_3 sudo ps aux | grep docker sudo kill -9 [PID] sudo docker ps -a
Na początku proponuję zaczynać od tych z góry, są one bowiem bardziej cywilizowane. Kill i rodzinka służy raczej do tego, gdy coś nam się zawiesi i nie będzie można wykonać standardowego wyłączenia. Po wyłączeniu kontenera nie jest on usuwany, można to zrobić za pomocą:
sudo docker rm [ID] sudo docker rm -f `sudo docker ps -a -q`
A generalne utrzymanie czystości, czyli usuwanie niepotrzebnych obrazów z Docker Engine można wykonać za pomocą:
sudo docker container prune sudo docker system prune --volumes
To już tyle jeśli chodzi o pierwsze kroki. W kolejnej odsłonie poruszymy temat wolumenów i punktów montowania, obrazów, docker hub, jak również i definiowania prywatnego rejestru. Pamiętaj, to tylko początki, dalej czeka nas definiowanie kontenera w Dockerfile, a później klaster Swarm i cała infrastruktura jako kod. Podekscytowani? Pewka.
Pingback: Sektor finansowy w kontenerach? » Inleo - Infrastruktura i architektura IT, Konteneryzacja, Datacenter, Private Cloud, PM