Konteneryzacja aplikacji wykorzystująca Dockera i ich orkiestracja za pomocą Kubernetes przebojem zdobywają coraz większą grupę zwolenników. Postanowiłem zmierzyć się z tymi produktami.
Założyłem, ze wykorzystam jakieś darmowe środowisko, które pozwoli mi na pierwsze zabawy, bez zbędnej instalacji oprogramowania na stacji roboczej. Powtarzalne operacje zostaną zapisane w plikach na Githubie.
Niniejszy wpis wykorzystuje https://labs.play-with-k8s.com/ .
Uruchomienie środowiska wymaga zalogowania się na konto GitHub lub na konto DockerHuba. Wybrałem tę drugą opcję.
Po podaniu naszych poświadczeń i po naciśnięciu zielonego przycisku Start mamy do dyspozycji uruchomione gotowe środowisko do testów, które zostaje powołane na czas czterech godzin.
Na początku musimy dodać pierwszą instancję. Po krótkiej chwili mamy już gotowe środowisko z dostępem do shella.
Pierwsze polecenie uname -a
Linux node1 4.4.0-127-generic #153-Ubuntu SMP Sat May 19 10:58:46
UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
Mamy dostęp do schowka
Shift + insert = kopiuj
Ctrl + insert = wklej
Co więcej możemy doinstalować sobie potrzebne pakiety, np. edytor nano, midnight commander i inne cuda…
yum install mc nano lynx
Spróbujmy uruchomić prostą aplikację w kontenerze z gotowego publicznego repozytorium Docker Hub.
Na początku uruchomimy pusta aplikacje www opartą o popularny serwer apache2.
docker run -d -p 80 httpd:2.4
Polecenie to uruchamia obraz o nazwie httpd w wersji 2.4 z wystawiony portem tcp 80 od strony kontenera, port hosta zostanie zmapowany automatycznie. Za chwile zobaczymy na jaką wartość. Obrazu tego nie było do tej pory lokalnie, stąd komunikat “unable to find image”. Przed budową zostanie on ściągnięty z repozytorium Docker Huba.
Otrzymany wynik:
Unable to find image 'httpd:2.4' locally
2.4: Pulling from library/httpd
f17d81b4b692: Pull complete
06fe09255c64: Pull complete
0baf8127507d: Pull complete
07b9730387a3: Pull complete
6dbdee9d6fa5: Pull complete
Digest: sha256:90b34f4370518872de4ac1af696a90d982fe99b0f30c9be994964f49a6e2f421
Status: Downloaded newer image for httpd:2.4
46da2648c3cb1b8a1354c488a6fac06036b1dfa388758bba0badf646ea775bdb
Sprawdźmy listę naszych obrazów
docker images
Otrzymany wynik:
REPOSITORY TAG IMAGE ID CREATED SIZE
httpd 2.4 55a118e2a010 2 days ago 132MB
Sprawdzamy, które obrazy są uruchomione.
docker ps
Otrzymany wynik:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
46da2648c3cb httpd:2.4 "httpd-foreground" 32 seconds ago Up 29 seconds 0.0.0.0:32768->80/tcp jolly_engelbart
>80/tcp jolly_engelbart
Port 80 tcp kontenera zostaje zmapowany na port 32768 hosta.
Pojawia się niebieskie łącze o nazwie wystawionego portu. Po kliknięciu mamy stronę z napisem
It works!
Wykorzystując gotowe obrazy, które można traktować jako bazę, mamy możliwość tworzenia na ich podstawie bardziej skomplikowanych funkcjonalnie aplikacji. W tym celu możemy wykorzystać plik konfiguracyjny, tak zwany Dockerfile.
Przykładowy Dockerfile:
# base image...
FROM phusion/baseimage
# author
MAINTAINER djkormo
RUN apt-get clean -qy
RUN apt-get update -qy
# install packages
RUN apt-get install apache2 git -qy
# clone content of sample app
RUN git clone https://github.com/djkormo/simple-chess-ai
# copy content to apache root directory
RUN cd simple-chess-ai && cp -R . /var/www/html/ && cd .. && rm -r simple-chess-ai/
RUN chmod a+x -R /var/www/html/
# running apache
ENTRYPOINT ["/usr/sbin/apache2ctl","-D","FOREGROUND"]
# exposing 80 port
EXPOSE 80
# Utwórzmy dedykowany katalog
mkdir containers
cd containers
mkdir chess-ai
cd chess-ai
touch Dockerfile
Uzupełniamy zawartość pustego pliku Dockerfile i budujemy nasz kontener.
docker build -t chess-ai .
Uruchamiamy nasz kontener
docker run -p 80 -d chess-ai
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTSNAMES
c4bae941f8d5 chess-ai "/usr/sbin/apache2ct…" 7 seconds ago Up 6 seconds 0.0.0.0:32770->80/tcp
Jak widać kontener nasłuchuje na porcie 32770 hosta
Można tę informację pobrać w bardziej elegancji sposób:
PORT="$(docker ps|grep chess-ai|sed 's/.*0.0.0.0://g'|sed 's/->.*//g')"
echo $PORT
32770
Na górze powinien pojawić się niebieski link z takim numerem portu.
Po uruchomieniu
http://ip172-18-0-22-bf4df2mn5ugg00cc6t5g-32770.direct.labs.play-with-k8s.com/
Mamy widoczną naszą aplikację.
Warto zapamiętać budowę linku:
http://ip<hyphen-ip>-<session_jd>-<port>.direct.labs.play-with-k8s.com
A naszym przypadku był to
http://ip172-18-0-22-bf4df2mn5ugg00cc6t5g-32770.direct.labs.play-with-k8s.com/
Warto pamiętać o kilku zasadach, które pomagają budować obrazy kontenerowe w sposób efektywny
- Wybieramy obraz, z najbardziej optymalną funkcjonalnością, czyli np. taki który zawiera tylko potrzebne oprogramowanie i nic więcej.
- Instalujemy tylko potrzebne oprogramowanie.
- Niepotrzebne pliki tymczasowe, które powstają podczas instalacji oprogramowania powinny zostać usunięte.
- Każde polecenie RUN tworzy nowa warstwę w obrazie, eliminujmy ich liczbę. Stad często widoczne jest sklejanie poleceń przez &&.
- Każdy projekt powinien mieć własny plik
.dockerignore
, w którym zawarte są reguły wykluczające pliki i katalogi w procesie budowania.
Wykonajmy prosty eksperyment.
Przygotowałem dwie wersje pliku DockerFile,
jeden to obraz ubuntu:16.04,
https://github.com/djkormo/ContainersSamples/blob/master/Docker/chess-ai/ubuntu/Dockerfile
drugi to alpine:3.7.
https://github.com/djkormo/ContainersSamples/tree/master/Docker/chess-ai/alpine/Dockerfile
# pobierzmy pliki z repozytorium GitHub.
git clone https://github.com/djkormo/ContainersSamples.git
Otrzymany wynik:
Cloning into 'ContainersSamples'...
remote: Enumerating objects: 84, done.
remote: Counting objects: 100% (84/84), done.
remote: Compressing objects: 100% (57/57), done.
remote: Total 84 (delta 13), reused 81 (delta 10), pack-reused 0
Unpacking objects: 100% (84/84), done.
Wchodzimy do podkatalogów
cd ContainersSamples/
cd Docker/
cd chess-ai/
W podkatalogu mamy trzy wersje plików Dockeffile
W każdym z podkatalogów budujemy lokalna wersje obrazu, tu dla przykładu dla obrazu pochodzącego z dystrybucji alpine.
docker build -t local/chess-ai-alpine .
Dla obrazu Ubuntu
docker build -t local/chess-ai-ubuntu .
Po zbudowaniu tych dwóch obrazów , możemy porównać ich rozmiar
docker images
Otrzymujemy następujące wartości:
REPOSITORY TAG IMAGE ID CREATED SIZE
local/chess-ai-alpine latest b9ab394052a6 18 seconds ago 28.3MB
local/chess-ai-ubuntu latest db929792894c 58 seconds ago 275MB
ubuntu 16.04 4a689991aa24 8 days ago 116MB
alpine 3.7 34ea7509dcad 6 weeks ago 4.2MB
To co widać od razu, z obrazu bazowego alpine:3.7 o wielkości 4.2MB powstał obraz local/chess-ai-alpine o wielkości 28.3MB. Natomiast z bazowego obrazu ubuntu:16.04 o wielkości 116MB powstał obraz localhost/chess-ai-ubuntu o wielkości 275MB. Funkcjonalność obu aplikacji, czyli prosta gra w szachy napisania w Javascript, jest taka sama, a różnica w wielkości jest dziesięciokrotna.
Literatura:
https://medium.com/@marcosnils/introducing-pwk-play-with-k8s-159fcfeb787b
https://github.com/play-with-docker/play-with-docker/issues/259
Dodaj komentarz