Ўсім прывітанне! У сваёй
Пачатак
Усё пачалося дажджлівым вераснёўскім увечар, калі я чысціў арандаваную за $5 машынку на Digital Ocean, якая намёртва павісла з-за таго што Докер апанаваў сваімі выявамі і кантэйнерамі ўсе 24 гігабайта даступнай дыскавай прасторы. Іронія была ў тым, што ўсе гэтыя выявы і кантэйнеры былі транзіентнымі і патрэбныя былі толькі для таго каб тэставаць працаздольнасць майго прыкладання кожны раз калі выходзіла новая версія якой-небудзь бібліятэкі ці фрэймворка. Я спрабаваў пісаць шелл-сркипты і наладжваць расклад крон для ачысткі смецця, але гэта не выратавала: кожны раз усё немінуча сканчалася тым, што дыскавая прастора майго сервера апынялася з'едзеным а сервер які завіс (у лепшым выпадку). У нейкі момант я натыкнуўся на артыкул пра тое як запускаць Jenkins у кантэйнеры і як ён можа ствараць і выдаляць зборачныя канвееры праз пракінуты ў яго сокет докер дэмана. Ідэя мне спадабалася, але я вырашыў пайсці далей і паспрабаваць паэксперыментаваць з непасрэдным запускам Докера ўнутры Докера. Мне тады здавалася цалкам лагічным рашэннем выпампоўваць докер выявы і ствараць кантэйнеры ўсіх прыкладанняў якія мне патрэбныя для тэставання ўсярэдзіне іншага кантэйнера (давайце назавем яго staging кантэйнер). Ідэя заключалася ў тым, каб запускаць staging кантэйнер са сцягам -rm, што аўтаматычна выдаляе ўвесь кантэйнер з усім яго змесцівам пры яго прыпынку. Я пакапаўся з докер чынам ад самога Докера (
Практыка. Шышкі
Я задаўся мэтай прымусіць кантэйнер працаваць так як мне было трэба і працягваў свае эксперыменты, вынікам якіх стала незлічоная колькасць гузоў. Вынікам майго самакатавання стаў наступны алгарытм:
-
Запускаем Докер кантэйнер у інтэрактыўным рэжыме.
docker run --privileged -it docker:18.09.6
Звярніце ўвагу на версію кантэйнера, крок направа або ў лева і ваш Дынд ператвараецца ў гарбуз. Насамрэч, усё ламаецца даволі часта з выхадам новай версіі.
Мы павінны адразу патрапіць у шелл. -
Спрабуем пазнаць, якія кантэйнеры запушчаныя (Адказ: ніякія), але давайце выканаем каманду ўсё-роўна:
docker ps
Вы будзеце крыху здзіўлены, але аказваецца Докер дэман нават не запушчаны:
error during connect: Get http://docker:2375/v1.40/containers/json: dial tcp: lookup docker on 192.168.65.1:53: no such host
-
Давайце запусцім яго самастойна:
dockerd &
Яшчэ адна непрыемная нечаканасць:
failed to start daemon: Error initializing network controller: error obtaining controller instance: failed to create NAT chain DOCKER: Iptables not found
-
Усталеўваны пакеты iptables і bash (у вежы ўсяка працаваць прыемней чым у sh):
apk add --no-cache iptables bash
-
Запускаем bash. Нарэшце мы зноў у звыклым шаўлі
-
паспрабуем запусціць Докер яшчэ раз:
dockerd &
Мы павінны ўбачыць доўгую прасціну логаў якая сканчаецца:
INFO[2019-11-25T19:51:19.448080400Z] Daemon has completed initialization INFO[2019-11-25T19:51:19.474439300Z] API listen on /var/run/docker.sock
-
Націскаем Enter. Мы зноў у вежы.
Пачынаючы з гэтага моманту мы можам спрабаваць запускаць іншыя кантэйнеры ўнутры нашага докер кантэйнера, але што калі мы хочам падняць яшчэ адзін докер кантэйнер ўнутры нашага докер кантэйнера ці нешта пойдзе не так і кантэйнер «вылеціць»? Пачынаць усё з пачатку.
Уласны DinD кантэйнер і новыя эксперыменты
Каб не паўтараць вышэйапісаныя крокі зноў і зноў я стварыў уласны DinD кантэйнер:
Рабочае DinD рашэнне дало мне магчымасць запускаць Докер ўнутры докер рэкурсіўна і праводзіць больш смелыя эксперыменты.
Адзін такі (удалы) эксперымент з запускам MySQL і Nodejs я збіраюся зараз апісаць.
Самыя нецярплівыя могуць паглядзець як гэта было тут
Такім чынам, пачнем:
-
Запускаем DinD у інтэрактыўным рэжыме. У дадзенай версіі DinD нам трэба ўручную замапіць усе парты якія могуць выкарыстоўваць нашы даччыныя кантэйнеры (я над гэтым ужо працую)
docker run --privileged -it -p 80:8080 -p 3306:3306 alekslitvinenk/dind
Мы трапляем у Баш, адкуль можам адразу прыступаць да запуску даччыных кантэйнераў.
-
Запускаем MySQL:
docker run --name mysql -e MYSQL_ROOT_PASSWORD=strongpassword -d -p 3306:3306 mysql
-
Падлучаемся да базы дадзеных гэтак жа як мы б падлучаліся да яе лакальна. Пераконваемся, што ўсё працуе.
-
Запускаем другі кантэйнер:
docker run -d --rm -p 8080:8080 alekslitvinenk/hello-world-nodejs-server
Звярніце ўвагу, што порт мапінг тут будзе менавіта 8080:8080, так як мы ўжо замапілі порт 80 з хаста ў бацькоўскі кантэйнер на порт 8080.
-
Ідзем на localhost у браўзэры, пераконваемся што сервер адказвае "Hello World!".
У маім выпадку эксперымент з укладзенымі Докер кантэйнерамі апынуўся даволі станоўчым і я працягну развіваць праект і выкарыстоўваць яго для стэйджынгу. Мне здаецца, што гэта значна больш легкаважнае рашэнне, чым той жа Kubernetes і Jenkins X. Але гэта маё суб'ектыўнае меркаванне.
Я думаю, што для сённяшняга артыкула - гэта ўсё. У наступным артыкуле я больш падрабязна апішу эксперыменты з рэкурсіўным запускам Докера ў Докера і мантаванне дырэкторый углыб укладзеных кантэйнераў.
PS Калі вы лічыце дадзены праект карысным, то калі ласка пастаўце яму зорачку на ГітХабе, зрабіце форк і раскажыце сябрам.
Edit1 Выправіў памылкі, зрабіў фокус на 2 відэа
Крыніца: habr.com