Docker part two — Docker-compose, Dockerfile
09.07.2018 | aktual.: 09.07.2018 17:57
W poprzednim moim wpisie o docker, zatytułowanym docker part one. W środowisku docker, wspólnie uruchomiliśmy kontener zawierający stronę www z WordPress. Nasz CMS wykorzystywał też bazę danych MySQL, uruchomioną na innym kontenerze. Zastanawiać nas może na ile takie rozwiązanie jest wydajne w porównaniu do środowiska które, to byśmy uruchomili bezpośrednio na naszej maszynie. Bez konteneryzacji czy wirtualizacji. Przyjrzyjmy się zatem testom porównawczym naszego środowiska. Zapraszam, miłej lektury
Posprzątajmy po poprzednim zadaniu (oczywiście nie musisz tego robić). Usuńmy nasze kontenery:
user@piotrskoska1:~$ docker container rm $(docker ps -aq) edb3432afb3a 96d2d93ad06f
Teraz obrazy:
user@piotrskoska1:~$ docker image rm $(docker images -q) Untagged: wordpress:latest Untagged: wordpress@sha256:7122e8924cfb8bc1f4bc0d5a01f6df7d8186f5661c385511079c60c4feca5019 Deleted: sha256:1d3cc82944da303e17b2fa48b5fa04d69acec1a0f4bd15d76a94d1004b84b232 Deleted: sha256:88db234a03bf4ad13b083cfb123aa615d62222461374751ce7331088ff08fcc1 Deleted: sha256:74697bb528e0642d88f3de7877209cc78bf5f69698646c419b1b1d6bc64dd1e1 Deleted: sha256:0caded870cec018bf959198a31dca58e971ea61b73fc4092af2d330939bf8b9f Deleted: sha256:0d50b480bddfbc8ada4b1491d1362928c46c4f0ab10a2ef22d43c35f75c017a6 Deleted: sha256:d7bacdcf48a705692458f4a179771b03cda1295fb2ae9bc4ea98fe28094a908f Deleted: sha256:a718d503c157a426eaa689c2f68ae559d4cb14b13d15e55397415885f4d4ff4f Deleted: sha256:988609d9c0c86b7009b1e5b8f3ee9e8bc21e4924a7ee744c9f72684253a52f77 Deleted: sha256:a512a51be99cce43c5d09c8acef49e476750fa2fad8158e34a0e5b4d270df9a2 Deleted: sha256:4c576a78131867f44bcca53842b71f6177f4995b1aed5cd3c90c3c392a6a6655 Deleted: sha256:6d1656c531823c4d642fca70a9c68064c67ab1681185edeb8bc40644d4e9a277 Deleted: sha256:327cf04f6a364c92f3d81e145af7bb1abef97c0c599a7bde0032abd7c50c3e8c Untagged: php:7.1.19-apache-stretch Untagged: php@sha256:5be4aaa759a3ce5e615bdb870ec75d833bb7a3dd8d4c379220fbf82da6a5e45a Deleted: sha256:9a8614ec9b1c5b29bdf0b4e0de93a39ef0ef80b43c321acbe0085e4c6e9f6131 Deleted: sha256:684d1d1e38089c6574d771864ed5055fd0ae0dbcc515994c9af4225a3d6f22b0 Deleted: sha256:cd554c64ce4cdf6e8d3cfd691040a577676c2608a77ceb5bae8351bf26696a1c Deleted: sha256:a83b1fdac804c3db78e098fbf225ed639a3edeb110156fd17cc95f5a4ba51ed3 Deleted: sha256:ab384881c32ca22a6b055d1aa4cd32fb13414187f2947d8a28cd0917a8355ff0 Deleted: sha256:f074816ecc1eaa60645b46cd4df89f602d5daeb042fd3aa8a633f4176198144c Deleted: sha256:0086afcff0b2a1fd02c1c4d85dedfe14ba9806440a06d167db207e8eb6a415aa Deleted: sha256:ce1045ecd636ce094cd8b7e096dbb3cba29f36f20225faceb973ad551ffdd91b Deleted: sha256:4c0b8b3e286f6d5f1d9948f47e282ba3363769288509fe39877b07ee4659e140 Deleted: sha256:bd4f1fc037fbaecfef37720c56db7020a4da60a5d258ff57d476fc07cef34940 Deleted: sha256:e405616e9966e660f73d8c440aa53b10c2f1fac5dc32ed734f33dabd188fca38 Deleted: sha256:d7b9430142428e5576b372eff134bdec3224ddf262ca0ea86642370ae19892a2 Deleted: sha256:902cf35f1f491062dda3941dd168e1286158d7742dee7b116aaeac9837e0a487 Deleted: sha256:07eaea308725a6305dae826ccd39ce73afe742c2503efa093c471dab49f3d5e9 Untagged: mysql:5.7.22 Untagged: mysql@sha256:1203dfba2600f140b74e375a354b1b801fa1b32d6f80fdee5f155d1e9f38c841 Deleted: sha256:66bc0f66b7af6ba3ea96582685d3afcd6dff93c2f8999da0ffadd67b280db548 Deleted: sha256:e011b4529a892ab54f15200c43d85ac4b9feb4b3dca14d129d23aba434bfca4f Deleted: sha256:8c1cd5fbd44434aff000f30595af979244ecfdedb54033d2822aa7f1764c7d41 Deleted: sha256:b3c692a6ea0dcc16eee1282e32522d7906f5bd35ad2d2b8e2a1a3f2a322d80e8 Deleted: sha256:e9233555be2dca57164cda0d8cda82bdfd7e585b8281cf53f954fba9b55e25eb Deleted: sha256:c0dcf468053a84ab7e4d982267d6423737752582acc1688f98b59950d3c3409a Deleted: sha256:e2221c9439fec64bbc63a4394aa09fb07285f4a9860833dfd0186b58dd4b03a4 Deleted: sha256:7ddf06c0d571150fd0770f0cacc7781da3fb66c8c1b0fef6bbde93f5527a7705 Deleted: sha256:52187c3153b1efb7fd75f052fe00d80f2b271a62f42aa91d50146e954eb9ea4a Deleted: sha256:ae038d900eb36ccbe2a2f552a3ab2ab2f09bd7661ac767ee6516d2682a54efa6 Deleted: sha256:772e498d907ce04162231d1c2361e5ae8e4ae26712ab0c72fea5f1eae4a28182 Deleted: sha256:9c46f426bcb704beffafc951290ee7fe05efddbc7406500e7d0a3785538b8735 Untagged: ubuntu:latest Untagged: ubuntu@sha256:5f4bdc3467537cbbe563e80db2c3ec95d548a9145d64453b06939c4592d67b6d Deleted: sha256:113a43faa1382a7404681f1b9af2f0d70b182c569aab71db497e33fa59ed87e6 Deleted: sha256:a9fa410a3f1704cd9061a802b6ca6e50a0df183cb10644a3ec4cac9f6421677a Deleted: sha256:b21f75f60422609fa79f241bf80044e6e133dd0662851afb12dacd22d199233a Deleted: sha256:038d2d2aa4fb988c06f04e3af208cc0c1dbd9703aa04905ade206d783e7bc06a Deleted: sha256:b904d425ea85240d6af5a6c6f145e05d5e0127f547f8eb4f68552962df846e81 Deleted: sha256:db9476e6d963ed2b6042abef1c354223148cdcdbd6c7416c71a019ebcaea0edb Untagged: hello-world:latest Untagged: hello-world@sha256:f5233545e43561214ca4891fd1157e1c3c563316ed8e237750d59bde73361e77 Deleted: sha256:e38bc07ac18ee64e6d59cf2eafcdddf9cec2364dfe129fe0af75f1b0194e0c96 Deleted: sha256:2b8cbd0846c5aeaa7265323e7cf085779eaf244ccbdd982c4931aef9be0d2faf Error response from daemon: conflict: unable to delete 49f7960eb7e4 (must be forced) - image is referenced in multiple repositories Error response from daemon: conflict: unable to delete 49f7960eb7e4 (must be forced) - image is referenced in multiple repositories
Przy usuwaniu obrazów może pojawić się błąd:
Error response from daemon: conflict: unable to delete 49f7960eb7e4 (must be forced) - image is referenced in multiple repositories Error response from daemon: conflict: unable to delete 49f7960eb7e4 (must be forced) - image is referenced in multiple repositories
Mówi on nam o tym, że obrazy są ze sobą powiązane. Widać to w tym poleceniu:
user@piotrskoska1:~$ docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE centos 7 49f7960eb7e4 4 weeks ago 200MB centos latest 49f7960eb7e4 4 weeks ago 200MB
Jak możemy zobaczyć ID naszego IMAGE w obu przypadkach jest takie same. By usunąć takie obrazy musimy skorzystać z przełącznika -f o czym mówi nam nasz output error.
user@piotrskoska1:~$ docker image rm -f $(docker image ls -q) Untagged: centos:7 Untagged: centos:latest Untagged: centos@sha256:b67d21dfe609ddacf404589e04631d90a342921e81c40aeaf3391f6717fa5322 Deleted: sha256:49f7960eb7e4cb46f1a02c1f8174c6fac07ebf1eb6d8deffbcb5c695f1c9edd5 Deleted: sha256:bcc97fbfc9e1a709f0eb78c1da59caeb65f43dc32cd5deeb12b8c1784e5b8237 Error: No such image: 49f7960eb7e4
Mamy wyczyszczone nasze środowisko docker. Stwórzmy kontenery z bazą MySQL, WordPress, phpmyadmin. Skorzystajmy też z opcji przełącznikowej volume. Co da nam ta opcja za chwilę, teraz zbudujmy nasze środowisko. Wykorzystamy do tego narzędzie docker-compose które, pozwoli nam łatwiej "rozmieścić" nasze kontenery :)
Deploy
Opiszę tu deploy kontenerów z wykorzystaniem docker-compose. Wszystkie nowe opcje które, wykorzystam w docker-compose a jeszcze ich nie omawiałem, opisze jak uzyskać je także po przez polecenia docker. Zacznijmy jednak od szybkiej instalacji naszego narzędzia docker-compose. Wykorzystajmy do tego poniższe polecenie:
sudo curl -L <span id="https://github.com/docker/compose/releases/download/1.21.2/docker-compose-$(uname">https://github.com/docker/compose/releases/download/1.21.2/docker-compose-$(uname</span> -s)-$(uname -m) -o /usr/local/bin/docker-compose
Po pobraniu nadajemy odpowiednie uprawnienia:
sudo chmod +x /usr/local/bin/docker-compose
Weryfikujemy wersje naszego docker-compose:
docker-compose --version
Mamy już narzędzie teraz przejdźmy do naszego warsztatu. Utwórz w dowolnej lokalizacji plik YAML stack.yml (nazwa może być dowolna). YAML to uniwersalny język formalny przeznaczony do reprezentowania różnych danych w ustrukturalizowany sposób. Poszczególne elementy struktury danych są oddzielane znakami nowej linii, a ich hierarchia ustalana jest na podstawie wcięcia linii. Język wprowadza trzy podstawowe struktury danych, które mogą być wkomponowane w dokument: listy, słowniki i skalary. Obsługuje również referencje, które eliminują konieczność redundancji danych. Wszystkie te cechy sprawiają, że dokumenty napisane w YAML-u są bardzo zwięzłe, czytelne dla człowieka, dają się też łatwo przetwarzać prostym narzędziom, takim jak grep, awk czy sed oraz przy pomocy języków skryptowych.
Jednak jak będzie wyglądać nasza składnia rozumiana przez docker-compose: zacznijmy od słowa version i services. "Version" zależne jest od wersji naszego docker
user@piotrskoska1:~$ docker version Client: Version: 18.05.0-ce API version: 1.37 Go version: go1.9.5 Git commit: f150324 Built: Wed May 9 22:16:25 2018 OS/Arch: linux/amd64 Experimental: false Orchestrator: swarm Server: Engine: Version: 18.05.0-ce API version: 1.37 (minimum version 1.12) Go version: go1.9.5 Git commit: f150324 Built: Wed May 9 22:14:32 2018 OS/Arch: linux/amd64 Experimental: false
Własne wyniki porównajcie z tabelą na tej stronie docker-compose. Wersje pliku yaml określają minimalna wersję docker jaką należy posiadać by z konkretnej wersji yaml file skorzystać.
Ważne jest też by w plikach yaml zdecydować się na na jednego rodzaju wcięcia. Wybieramy spacje lub tabulatory. Nie jest dozwolone używanie ich w całym pliku na przemiennie, gdyż może to powodować złą interpretację naszego pliku.
stack.yml
version: '3.1' services:
Niestety w edytorze dobrych programów na dzień pisania wpisu blogowego nie znalazłem opcji wstawiania block code jako yaml. Dlatego wykorzystam bash, - jednak by łatwiej było odróżnić komendy shellowe od pliku yaml. Code block związany z yaml będę poprzedzał nazwa pliku *.yaml.
Zastanówmy się co potrzebujemy w naszym testowym środowisku. Na pewno naszą bazę danych - czyli kontener z mysql. Na tym moglibyśmy zakończyć. Ponieważ do przetestowania bazy danych więcej kontenerów potrzebować nie będziemy. Jednak by omówić trochę więcej opcji i trochę urozmaicić ten wpis ja dorzucę jeszcze do naszego środowiska kontener z WordPress, phpMyAdmin, adminer i ubuntu. Na ostatnim kontenerze z Ubuntu zainstalujemy nasze narzędzie do testowania bazy danych.
Zdefiniujmy nasze serwisy w stack.yml
version: '3.1' services: db: adminer: wordpress: phpmyadmin:
Wykorzystajmy to co już wiemy na temat naszych obrazów które, pomogą nam zbudować nasze kontenery. Powróćmy pamięcią do poprzedniego wpisu docker part one. Przypomnijmy sobie co jest potrzebne w naszych kontenerach. W kontenerze z mysql potrzebujemy expose portu 3306 oraz hasła dla użytkownika root do bazy danych. Kontener z wordpress potrzebuje portu 80 udostępnionego na zewnątrz. Potrzebuje też hasła takiego samego jak w kontenerze z bazą danych. Kontener z ubuntu to nasz kontener na którym będziemy uruchamiać nasze narzędzie do testów bazy danych. Ostatnie dwa kontenery to graficzny menadżer bo naszej bazy danych. Wykorzystamy go później przy testach.
Podejrzyjmy nasz plik stack.yml
version: '3.1' services: db: image: mysql:5.7.22 container_name: mysql_db restart: always ports: - 3306:3306 environment: MYSQL_ROOT_PASSWORD: rutek volumes: - /home/user/database:/var/lib/mysql adminer: image: adminer container_name: adminer restart: always ports: - 8080:8080 wordpress: image: wordpress container_name: wordpress restart: always ports: - 80:80 environment: WORDPRESS_DB_PASSWORD: rutek links: - "db:mysql" phpmyadmin: image: phpmyadmin/phpmyadmin container_name: phpmyadmin restart: always ports: - 8082:80 links: - "db:mysql_db" ubuntu: build: context: . dockerfile: Dockerfile container_name: test_env_ubuntu ports: - "3333:22"
Patrząc na nasz plik od góry odpowiednie wcięcia oznaczają nasze serwisy czyli kontenery
- db
- adminer
- wordpress
- phpmyadmin
- ubuntu
Wcięcie potomne nazw tych serwisów to opcje tych kontenerów. Pole image w każdym serwisie oznacza obraz na podstawie którego, będzie budowany nasz kontener. Odpowiednio dla naszej bazy danych jest to obraz mysql z tagiem 5.7.22. Adminer wykorzystuje obraz o takiej samej nazwie jak wordpress, phpmyadmin korzysta z publicznego repo o nazwie phpmyadmin/phpmyadmin. Kontener z ubuntu jest konstruowany na podstawie pliku Dockerfile. O plikach Dockerfile porozmawiamy nieco później.
Kolejny element to nazwa kontenera. Odpowiednikiem jest polecenie docker run z parametrem -‑name dobrze nam znany z poprzedniego wpisu. Zmienna ta nie jest zmienną niezbędną. Pozwala nam jedynie uzyskać nie losową nazwę naszego kontenera.
Opcja restart: always to odpowiednik polecenia:
docker run -dit --restart always ubuntu /bin/bash
Daje nam pewną właściwość dla naszego kontenera która, będzie go uruchamiać zawsze gdy jego status będzie inny niż UP.
Ports to opcja udostępnienia portu na zewnątrz kontenera - zasada taka sama jak w poleceniu docker run z -p <PORT_W_NASZYM_HOŚCIE>:<PORT_W_NASZYM_KONTENERZE> ale to już znamy.
Environment to nasze zmienne dostępne w kontenerze. Tu udostępniamy hasło do naszej bazy danych.
Opcja links jest już nam dobrze znana i łączy nasz kontener wordpress i phpmyadmin z mysql
Nowości jest opcja volumes. Daje nam to możliwość "mapowania" dowolnego miejsca na naszym lokalnym komputerze, dzięki czemu będzie on widoczny dla kontenera i będzie on tam zapisywał swoje dane. Odpowiednikiem polecenia docker jest:
docker run -it --name vol-test -v $PWD:/data debian /bin/bash
Najwięcej nowości jest w serwisie ubuntu. Opcja build daje możliwość skorzystania z pliku Dockerfile. Plik taki pozwala budować własne obrazy, które potem można wykorzystać do budowy kontenera. Zobaczmy zatem jak będzie wyglądał nasz Dockerfile
Dockerfile
FROM ubuntu:16.04 RUN apt-get update && apt-get install -y openssh-server RUN mkdir /var/run/sshd RUN echo 'root:screencast' | chpasswd RUN sed -i 's/PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd ENV NOTVISIBLE "in users profile" RUN echo "export VISIBLE=now" >> /etc/profile EXPOSE 22 CMD ["/usr/sbin/sshd", "-D"]
Oczywiście wymaga to komentarza z mojej strony by nie było to swoistym kopiuj wklej. Patrząc od góry mamy opcje FROM która, powinna zawsze znajdować się w pierwszej linii naszego pliku Dockerfile. Wskazuje nam obraz lub źródło z którego, będzie budowany nas obraz (może to też być plik *.tar).
Opcja RUN jak już możecie zauważyć to polecenia które zostaną wywołane w celu dodatkowej konfiguracji naszego kontenera. Możemy dzięki temu doinstalować dodatkowe biblioteki takie jak serwer openssh. Albo po prostu stworzyć katalog lub edytować plik. Ważne jest to że, opcja RUN nie przewiduje interakcji. Więc wszystkie komendy muszą mieć charakter automatyczny.
Opcja ENV pozwala na zdefiniować własną zmienną.
EXPOSE to tu definiujemy, że nasz port w tym przypadku 22 będzie dostępny i możliwy do mapowania po za nasz kontener.
Opcja CMD w tym przypadku jest wartością która to definiuje proces jaki będzie uruchamiany w kontenerze. Dopóki ten proces będzie działał, będzie też istniał nasz kontener.
Każde poszczególne polecenie to osobna warstwa o której, wspominałem w poprzednim wpisie. Każda warstwa to osobny kontener który, pod koniec jest scalany w konkretny obraz z którego, budowany jest nasz wyjściowy kontener.
Czas uruchomić całość.
Skorzystajmy z polecenia:
docker-compose -f stack.yml up -d
Docker-compose za nas pobierze odpowiednio obrazy dla mysql, pypmyadmin, adminer, wordpress.
user@piotrskoska1:~/yaml_file$ docker-compose -f stack.yml up -d Pulling db (mysql:5.7.22)... 5.7.22: Pulling from library/mysql 683abbb4ea60: Pull complete 0550d17aeefa: Pull complete 7e26605ddd77: Pull complete 9882737bd15f: Pull complete 999c06ab75f6: Pull complete c71d695f9937: Pull complete c38f847c1491: Pull complete 74f9c61f40bf: Pull complete 30b252a90a12: Pull complete 9f92ebb7da55: Pull complete 90303981d276: Pull complete Digest: sha256:1203dfba2600f140b74e375a354b1b801fa1b32d6f80fdee5f155d1e9f38c841 Status: Downloaded newer image for mysql:5.7.22
Oczywiście dla innych obrazów output może być podobny.
Dla naszego obrazu budowanego z pliku dockerfile output będzie inny bardziej obszerny. Sporo informacji. Możemy je skrócić przez dodanie opcji > /dev/null do naszych poleceń instalacyjnych.
Nasz dockerfile będzie wyglądał teraz tak:
FROM ubuntu:16.04 RUN apt-get update > /dev/null && apt-get install -y openssh-server > /dev/null RUN mkdir /var/run/sshd RUN echo 'root:screencast' | chpasswd RUN sed -i 's/PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd ENV NOTVISIBLE "in users profile" RUN echo "export VISIBLE=now" >> /etc/profile EXPOSE 22 CMD ["/usr/sbin/sshd", "-D"]
Jeżeli uruchomiłeś już docker-compose obrazy i kontenery możesz usunąć przy pomocy polecenia:
docker container stop $(docker ps -qa); docker container rm $(docker ps -qa); docker image rm -f $(docker image ls -q)
Ostatnia informacja z polecenia docker-compose powinno zwrócić nam informacje na temat naszych kontenerów.
Możemy też sprawdzić status naszych kontenerów:
Jak widzimy nasze kontenery działają.
Sysbench
Do przetestowania naszej bazy danych użyjemy narzędzia zwanego sysbench. Wejdźmy do naszego kontenera z Ubuntu. I zainstalujmy nasz pakiet.
ssh -p 3333 root@localhost
Dla systemu ubuntu / debian instalacja sysbench jest następująca:
curl -s <span id="https://packagecloud.io/install/repositories/akopytov/sysbench/script.deb.sh">https://packagecloud.io/install/repositories/akopytov/sysbench/script.deb.sh</span> | sudo bash sudo apt -y install sysbench
Jeżeli próbujecie zrobić to co opisuje nie szablonowo dla innych dystrybucji opis znajdziecie tutaj.
Sprawdźmy też czy nasze kontenery działają. Ja użyłem odpowiednio port forwarding by uzyskać dostęp do aplikacji świadczonych przez kontenery.
Powinieneś bez problemu zalogować się na dane dostepowe które, podałeś podczas budowy kontenerów. Tak więc zaczynamy. Przyjrzyjmy się składni sysbench.
root@cd980a8f8023:~# sysbench --help Usage: sysbench [options]... [testname] [command] Commands implemented by most tests: prepare run cleanup help General options: --threads=N number of threads to use [1] --events=N limit for total number of events [0] --time=N limit for total execution time in seconds [10] --forced-shutdown=STRING number of seconds to wait after the --time limit before forcing shutdown, or 'off' to disable [off] --thread-stack-size=SIZE size of stack per thread [64K] --rate=N average transactions rate. 0 for unlimited rate [0] --report-interval=N periodically report intermediate statistics with a specified interval in seconds. 0 disables intermediate reports [0] --report-checkpoints=[LIST,...] dump full statistics and reset all counters at specified points in time. The argument is a list of comma-separated values representing the amount of time in seconds elapsed from start of test when report checkpoint(s) must be performed. Report checkpoints are off by default. [] --debug[=on|off] print more debugging info [off] --validate[=on|off] perform validation checks where possible [off] --help[=on|off] print help and exit [off] --version[=on|off] print version and exit [off] --config-file=FILENAME File containing command line options --tx-rate=N deprecated alias for --rate [0] --max-requests=N deprecated alias for --events [0] --max-time=N deprecated alias for --time [0] --num-threads=N deprecated alias for --threads [1] Pseudo-Random Numbers Generator options: --rand-type=STRING random numbers distribution {uniform,gaussian,special,pareto} [special] --rand-spec-iter=N number of iterations used for numbers generation [12] --rand-spec-pct=N percentage of values to be treated as 'special' (for special distribution) [1] --rand-spec-res=N percentage of 'special' values to use (for special distribution) [75] --rand-seed=N seed for random number generator. When 0, the current time is used as a RNG seed. [0] --rand-pareto-h=N parameter h for pareto distribution [0.2] Log options: --verbosity=N verbosity level {5 - debug, 0 - only critical messages} [3] --percentile=N percentile to calculate in latency statistics (1-100). Use the special value of 0 to disable percentile calculations [95] --histogram[=on|off] print latency histogram in report [off] General database options: --db-driver=STRING specifies database driver to use ('help' to get list of available drivers) [mysql] --db-ps-mode=STRING prepared statements usage mode {auto, disable} [auto] --db-debug[=on|off] print database-specific debug information [off] Compiled-in database drivers: mysql - MySQL driver pgsql - PostgreSQL driver mysql options: --mysql-host=[LIST,...] MySQL server host [localhost] --mysql-port=[LIST,...] MySQL server port [3306] --mysql-socket=[LIST,...] MySQL socket --mysql-user=STRING MySQL user [sbtest] --mysql-password=STRING MySQL password [] --mysql-db=STRING MySQL database name [sbtest] --mysql-ssl[=on|off] use SSL connections, if available in the client library [off] --mysql-ssl-cipher=STRING use specific cipher for SSL connections [] --mysql-compression[=on|off] use compression, if available in the client library [off] --mysql-debug[=on|off] trace all client library calls [off] --mysql-ignore-errors=[LIST,...] list of errors to ignore, or "all" [1213,1020,1205] --mysql-dry-run[=on|off] Dry run, pretend that all MySQL client API calls are successful without executing them [off] pgsql options: --pgsql-host=STRING PostgreSQL server host [localhost] --pgsql-port=N PostgreSQL server port [5432] --pgsql-user=STRING PostgreSQL user [sbtest] --pgsql-password=STRING PostgreSQL password [] --pgsql-db=STRING PostgreSQL database name [sbtest] Compiled-in tests: fileio - File I/O test cpu - CPU performance test memory - Memory functions speed test threads - Threads subsystem performance test mutex - Mutex performance test See 'sysbench <testname> help' for a list of options for each test.
Jak widzimy na dole mamy rodzaj testów do uruchomienia. Jednak my nie będziemy się skupiać na fileio, cpu czy memory. Nas interesują testy bazy danych. Zatem jak je odnaleźć. Najprostszą metodą jest wydanie polecenia:
dpkg --listfiles sysbench
Który zwróci nam taki output:
root@cd980a8f8023:~# dpkg --listfiles sysbench /. /usr /usr/share /usr/share/doc /usr/share/doc/sysbench /usr/share/doc/sysbench/ChangeLog.gz /usr/share/doc/sysbench/manual.html /usr/share/doc/sysbench/changelog.Debian.gz /usr/share/doc/sysbench/README.md.gz /usr/share/doc/sysbench/COPYING.gz /usr/share/doc/sysbench/copyright /usr/share/sysbench /usr/share/sysbench/oltp_read_write.lua /usr/share/sysbench/oltp_delete.lua /usr/share/sysbench/oltp_common.lua /usr/share/sysbench/oltp_insert.lua /usr/share/sysbench/oltp_update_non_index.lua /usr/share/sysbench/oltp_point_select.lua /usr/share/sysbench/tests /usr/share/sysbench/tests/include /usr/share/sysbench/tests/include/mysql_common.sh /usr/share/sysbench/tests/include/script_select_random_legacy_common.sh /usr/share/sysbench/tests/include/oltp_legacy /usr/share/sysbench/tests/include/oltp_legacy/select.lua /usr/share/sysbench/tests/include/oltp_legacy/update_non_index.lua /usr/share/sysbench/tests/include/oltp_legacy/delete.lua /usr/share/sysbench/tests/include/oltp_legacy/oltp_simple.lua /usr/share/sysbench/tests/include/oltp_legacy/select_random_points.lua /usr/share/sysbench/tests/include/oltp_legacy/common.lua /usr/share/sysbench/tests/include/oltp_legacy/update_index.lua /usr/share/sysbench/tests/include/oltp_legacy/insert.lua /usr/share/sysbench/tests/include/oltp_legacy/select_random_ranges.lua /usr/share/sysbench/tests/include/oltp_legacy/parallel_prepare.lua /usr/share/sysbench/tests/include/oltp_legacy/oltp.lua /usr/share/sysbench/tests/include/oltp_legacy/bulk_insert.lua /usr/share/sysbench/tests/include/script_oltp_legacy_common.sh /usr/share/sysbench/tests/include/pgsql_common.sh /usr/share/sysbench/tests/include/config.sh /usr/share/sysbench/tests/include/inspect.lua /usr/share/sysbench/tests/include/script_select_random_common.sh /usr/share/sysbench/tests/include/script_oltp_common.sh /usr/share/sysbench/tests/include/api_sql_common.sh /usr/share/sysbench/tests/include/script_bulk_insert_common.sh /usr/share/sysbench/tests/include/drv_common.sh /usr/share/sysbench/tests/t /usr/share/sysbench/tests/t/api_rand.t /usr/share/sysbench/tests/t/cmd_prepare.t /usr/share/sysbench/tests/t/test_threads.t /usr/share/sysbench/tests/t/script_oltp_delete_mysql.t /usr/share/sysbench/tests/t/api_sql_mysql.t /usr/share/sysbench/tests/t/script_select_random_pgsql.t /usr/share/sysbench/tests/t/api_legacy_rand.t /usr/share/sysbench/tests/t/opt_version.t /usr/share/sysbench/tests/t/test_cpu.t /usr/share/sysbench/tests/t/api_basic.t /usr/share/sysbench/tests/t/cmd_run.t /usr/share/sysbench/tests/t/script_oltp_delete_pgsql.t /usr/share/sysbench/tests/t/script_oltp_insert_mysql.t /usr/share/sysbench/tests/t/commands.t /usr/share/sysbench/tests/t/script_select_random_mysql.t /usr/share/sysbench/tests/t/drv_pgsql.t /usr/share/sysbench/tests/t/script_oltp_point_select_mysql.t /usr/share/sysbench/tests/t/help_drv_pgsql.t /usr/share/sysbench/tests/t/script_bulk_insert_pgsql.t /usr/share/sysbench/tests/t/tests.t /usr/share/sysbench/tests/t/test_fileio.t /usr/share/sysbench/tests/t/opt_help.t /usr/share/sysbench/tests/t/script_bulk_insert_mysql.t /usr/share/sysbench/tests/t/opt_report_checkpoints.t /usr/share/sysbench/tests/t/drv_mysql.t /usr/share/sysbench/tests/t/cmdline.t /usr/share/sysbench/tests/t/script_oltp_help.t /usr/share/sysbench/tests/t/opt_report_interval.t /usr/share/sysbench/tests/t/1st.t /usr/share/sysbench/tests/t/api_legacy_basic.t /usr/share/sysbench/tests/t/cmd_cleanup.t /usr/share/sysbench/tests/t/cmd_help.t /usr/share/sysbench/tests/t/api_legacy_sql.t /usr/share/sysbench/tests/t/script_oltp_point_select_pgsql.t /usr/share/sysbench/tests/t/script_oltp_read_write_mysql.t /usr/share/sysbench/tests/t/script_oltp_read_write_pgsql.t /usr/share/sysbench/tests/t/opt_histogram.t /usr/share/sysbench/tests/t/api_reports.t /usr/share/sysbench/tests/t/script_oltp_insert_pgsql.t /usr/share/sysbench/tests/t/api_sql_pgsql.t /usr/share/sysbench/tests/t/drivers.t /usr/share/sysbench/tests/t/test_memory.t /usr/share/sysbench/tests/t/test_mutex.t /usr/share/sysbench/tests/t/help_drv_mysql.t /usr/share/sysbench/tests/t/api_histogram.t /usr/share/sysbench/tests/test_run.sh /usr/share/sysbench/select_random_points.lua /usr/share/sysbench/oltp_update_index.lua /usr/share/sysbench/oltp_read_only.lua /usr/share/sysbench/oltp_write_only.lua /usr/share/sysbench/select_random_ranges.lua /usr/share/sysbench/bulk_insert.lua /usr/bin /usr/bin/sysbench
Nas interesują wszystkie pliki kończące się na *.lua w katalogu /usr/share/sysbench/*.lua. Lista testów jest następująca:
/usr/share/sysbench/oltp_read_write.lua /usr/share/sysbench/oltp_delete.lua /usr/share/sysbench/oltp_common.lua /usr/share/sysbench/oltp_insert.lua /usr/share/sysbench/oltp_update_non_index.lua /usr/share/sysbench/oltp_point_select.lua /usr/share/sysbench/select_random_points.lua /usr/share/sysbench/oltp_update_index.lua /usr/share/sysbench/oltp_read_only.lua /usr/share/sysbench/oltp_write_only.lua /usr/share/sysbench/select_random_ranges.lua /usr/share/sysbench/bulk_insert.lua
Jeżeli macie problem z wyciągnięciem danych tylko nas interesujących to zapraszam do serii bash(ującego) w zbożu:
- Bash(ujący) w zbożu cz.1 - Zaczynamy
- Bash(ujący) w zbożu cz. 2 — automatyzacja użytkownika
- Bash(ujący) w zbożu cz. 3 — namespace
Przed uruchomieniem testu musimy naszą bazę danych przygotować. Przygotujmy bazę danych dla naszego testu, na przykład oltp_insert.lua
Doinstalujmy klienta mysql w naszym ubuntu by przetestować naszą baze danych.
apt-get install mysql-client
Wykonajmy połączenie do naszego kontenera z bazą danych mysql, przykładowe polecenie będzie wyglądało następująco:
mysql -h <IP> -u root -p
Adres naszego kontenera możemy uzyskać z polecenia:
docker container inspect <NAZWA_KONTENERA>
Uzyskamy bardzo dużo informacji na temat naszego kontenera w tym nasz adres IP. Bardziej konkretny output zwróci nam polecenie:
docker container inspect --format='{{range .NetworkSettings.Networks}}{{println .IPAddress}}{{end}}' mysql_db
Mamy nasz adres IP. Wróćmy do naszego kontenera z ubuntu.
root@cd980a8f8023:~# mysql -h 172.18.0.3 -u root -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 8 Server version: 5.7.22 MySQL Community Server (GPL) Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql>
Mamy konsolę cli mysql. Sysbench potrzebuję bazę danych na której, bedizen pracował. Taką bazę danych możemy utworzyć poleceniem:
CREATE DATABASE sysbench_my_own_test CHARACTER SET utf8 COLLATE utf8_general_ci;
Wykorzystajmy do sprawdzenia tego polecenia naszą aplikację z phpMyAdmin.
Jak widać wszystko działa.
Uprawnień nie musimy dodawać gdyż mamy root na bazie danych.
Czas teraz przygotować nowo utworzoną bazę danych do zabawy z sysbench. Zrobimy to już z poziomu sysbench.
sysbench /usr/share/sysbench/oltp_insert.lua --threads=1 --mysql-host=<IP> --mysql-user=root --mysql-password=rutek --mysql-port=3306 --mysql-db=sysbench_my_own_test --tables=4 --table-size=1000000 prepare
Pierwszy parametr polecenia to jest nasz test /usr/share/sysbench/oltp_insert.lua który, zostanie uruchomiony. Przeznaczamy na te przygotowania jeden wątek. Podajemy parametry logowania czyli host, user, pass oraz nazwa naszej bazy danych. Ostatnie to ilość utworzonych tabel w bazie danych i liczba naszych rekordów w każdej tabeli. Słowo kluczowe prepare przygotuje nam bazę danych. Enter.
sysbench 1.0.15 (using bundled LuaJIT 2.1.0-beta2) Creating table 'sbtest1'... Inserting 1000000 records into 'sbtest1' Creating a secondary index on 'sbtest1'... Creating table 'sbtest2'... Inserting 1000000 records into 'sbtest2' Creating a secondary index on 'sbtest2'... Creating table 'sbtest3'... Inserting 1000000 records into 'sbtest3' Creating a secondary index on 'sbtest3'... Creating table 'sbtest4'... Inserting 1000000 records into 'sbtest4' Creating a secondary index on 'sbtest4'...
Przygotowania rozpoczęte. Postęp można śledzić w naszej aplikacji.
Teraz czas na nasz pierwszy test. Opcje jakimi dysponujemy zobaczymy używając sysbench <NAZWA_TESTU> help. W naszym przypadku mamy:
root@cd980a8f8023:~# sysbench /usr/share/sysbench/oltp_insert.lua help sysbench 1.0.15 (using bundled LuaJIT 2.1.0-beta2) oltp_insert.lua options: --auto_inc[=on|off] Use AUTO_INCREMENT column as Primary Key (for MySQL), or its alternatives in other DBMS. When disabled, use client-generated IDs [on] --create_secondary[=on|off] Create a secondary index in addition to the PRIMARY KEY [on] --delete_inserts=N Number of DELETE/INSERT combinations per transaction [1] --distinct_ranges=N Number of SELECT DISTINCT queries per transaction [1] --index_updates=N Number of UPDATE index queries per transaction [1] --mysql_storage_engine=STRING Storage engine, if MySQL is used [innodb] --non_index_updates=N Number of UPDATE non-index queries per transaction [1] --order_ranges=N Number of SELECT ORDER BY queries per transaction [1] --pgsql_variant=STRING Use this PostgreSQL variant when running with the PostgreSQL driver. The only currently supported variant is 'redshift'. When enabled, create_secondary is automatically disabled, and delete_inserts is set to 0 --point_selects=N Number of point SELECT queries per transaction [10] --range_selects[=on|off] Enable/disable all range SELECT queries [on] --range_size=N Range size for range SELECT queries [100] --secondary[=on|off] Use a secondary index in place of the PRIMARY KEY [off] --simple_ranges=N Number of simple range SELECT queries per transaction [1] --skip_trx[=on|off] Don't start explicit transactions and execute all queries in the AUTOCOMMIT mode [off] --sum_ranges=N Number of SELECT SUM() queries per transaction [1] --table_size=N Number of rows per table [10000] --tables=N Number of tables [1]
Zatem czasem by nauczyć się chodzić trzeba zacząć biegać:
root@cd980a8f8023:~# sysbench /usr/share/sysbench/oltp_insert.lua --threads=1 --mysql-host=172.18.0.3 --mysql-user=root --mysql-password=rutek --mysql-port=3306 --mysql-db=sysbench_my_own_test --tables=4 --table-size=1000000 --histogram=on --time=60 --events=0 run
Output po 60 sekundach otrzymamy taki:
sysbench 1.0.15 (using bundled LuaJIT 2.1.0-beta2) Running the test with following options: Number of threads: 1 Initializing random number generator from current time Initializing worker threads... Threads started! Latency histogram (values are in milliseconds) value ------------- distribution ------------- count 0.608 | 2 0.619 | 8 0.630 | 31 0.642 |* 114 0.654 |**** 336 0.665 |********* 766 0.677 |***************** 1412 0.690 |*************************** 2271 0.702 |************************************* 3081 0.715 |**************************************** 3366 0.728 |*************************************** 3262 0.741 |********************************** 2847 0.755 |***************************** 2439 0.768 |************************ 2005 0.782 |******************** 1660 0.797 |**************** 1352 0.811 |************** 1220 0.826 |*********** 950 0.841 |*********** 893 0.856 |********* 760 0.872 |******* 614 0.888 |******* 622 0.904 |****** 476 0.920 |***** 395 0.937 |**** 374 0.954 |**** 322 0.971 |*** 227 0.989 |** 165 1.007 |** 129 1.025 |* 112 1.044 |* 76 1.063 |* 66 1.082 | 41 1.102 |* 46 1.122 | 34 1.142 | 36 1.163 | 33 1.184 | 17 1.205 | 24 1.227 | 19 1.250 | 10 1.272 | 13 1.295 | 14 1.319 | 21 1.343 | 13 1.367 | 13 1.392 | 16 1.417 | 9 1.443 | 13 1.469 | 18 1.496 | 23 1.523 | 19 1.551 | 12 1.579 | 19 1.608 | 13 1.637 | 28 1.667 |* 53 1.697 |* 94 1.728 |** 205 1.759 |***** 435 1.791 |********* 748 1.824 |************* 1068 1.857 |**************** 1369 1.891 |***************** 1435 1.925 |***************** 1421 1.960 |*************** 1251 1.996 |************ 1000 2.032 |********** 810 2.069 |******** 657 2.106 |****** 488 2.145 |***** 385 2.184 |**** 301 2.223 |*** 214 2.264 |** 139 2.305 |** 135 2.347 |* 81 2.389 |* 70 2.433 |* 81 2.477 |* 61 2.522 | 39 2.568 |* 44 2.615 |* 49 2.662 | 42 2.710 | 40 2.760 | 36 2.810 | 35 2.861 | 40 2.913 | 22 2.966 | 33 3.020 | 29 3.075 | 21 3.130 | 30 3.187 | 38 3.245 | 26 3.304 | 32 3.364 | 39 3.425 | 24 3.488 | 34 3.551 | 20 3.615 | 17 3.681 | 21 3.748 | 30 3.816 | 18 3.885 | 30 3.956 | 30 4.028 | 25 4.101 | 35 4.176 | 41 4.252 |* 59 4.329 | 37 4.407 | 42 4.487 |* 44 4.569 | 39 4.652 | 32 4.737 | 24 4.823 | 19 4.910 | 22 4.999 | 21 5.090 | 23 5.183 | 16 5.277 | 16 5.373 | 14 5.470 | 16 5.570 | 11 5.671 | 21 5.774 | 3 5.879 | 9 5.986 | 11 6.095 | 15 6.205 | 19 6.318 | 14 6.433 | 11 6.550 | 10 6.669 | 13 6.790 | 9 6.913 | 7 7.039 | 5 7.167 | 5 7.297 | 9 7.430 | 8 7.565 | 3 7.702 | 1 7.842 | 6 7.985 | 7 8.130 | 2 8.277 | 3 8.428 | 4 8.581 | 5 8.737 | 7 8.895 | 6 9.057 | 8 9.222 | 5 9.389 | 9 9.560 | 9 9.734 | 13 9.910 | 5 10.090 | 12 10.274 | 8 10.460 | 9 10.651 | 6 10.844 | 12 11.041 | 6 11.242 | 8 11.446 | 4 11.654 | 5 11.866 | 1 12.081 | 11 12.301 | 3 12.524 | 2 12.752 | 2 12.984 | 2 13.219 | 2 13.460 | 4 13.704 | 2 13.953 | 1 14.465 | 2 14.728 | 3 14.995 | 6 15.268 | 3 15.545 | 4 15.828 | 3 16.115 | 2 16.408 | 7 16.706 | 4 17.010 | 3 17.319 | 3 17.633 | 3 17.954 | 2 18.280 | 2 18.612 | 4 18.950 | 1 19.295 | 2 19.645 | 2 20.002 | 2 21.496 | 1 22.689 | 2 24.827 | 1 32.525 | 1 56.839 | 1 108.685 | 1 112.670 | 1 114.717 | 1 130.128 | 1 139.846 | 2 147.608 | 1 SQL statistics: queries performed: read: 0 write: 47146 other: 0 total: 47146 transactions: 47146 (785.43 per sec.) queries: 47146 (785.43 per sec.) ignored errors: 0 (0.00 per sec.) reconnects: 0 (0.00 per sec.) General statistics: total time: 60.0236s total number of events: 47146 Latency (ms): min: 0.61 avg: 1.27 max: 148.58 95th percentile: 2.22 sum: 59831.08 Threads fairness: events (avg/stddev): 47146.0000/0.00 execution time (avg/stddev): 59.8311/0.00
Ciąg dalszy nastąpi
W tym wpisie to już wszystko. W kolejnym postaram się przyjrzeć innym testom z wachlarza sysbench oraz ich graficznej interpretacji. Jeżeli wpis przypadł Ci do gustu, podobał się i chcesz więcej zostaw obiektywny komentarz, udostępnij. Zapraszam ponownie.