Ahojte všetci! V jeho
začiatok
Všetko to začalo v daždivý septembrový večer, keď som čistil stroj, ktorý som si prenajal za 5 dolárov na Digital Ocean, ktorý bol zmrazený kvôli skutočnosti, že Docker zaplnil všetkých 24 gigabajtov dostupného miesta na disku svojimi obrázkami a kontajnermi. Iróniou bolo, že všetky tieto obrázky a kontajnery boli prechodné a boli potrebné len na testovanie výkonu mojej aplikácie zakaždým, keď bola vydaná nová verzia knižnice alebo rámca. Pokúsil som sa písať skripty shellu a nastaviť plán cron na vyčistenie odpadu, ale nepomohlo to: zakaždým to nevyhnutne skončilo tým, že miesto na disku môjho servera bolo spotrebované a server visel (v najlepšom prípade). V určitom momente som narazil na článok o tom, ako spustiť Jenkins v kontajneri a ako môže vytvárať a odstraňovať zostavovacie potrubia cez docker daemon socket, ktorý je doň odovzdaný. Tento nápad sa mi páčil, ale rozhodol som sa ísť ďalej a skúsiť experimentovať s priamym spustením Dockera v Dockeri. Vtedy sa mi zdalo úplne logické riešenie stiahnuť si obrázky Docker a vytvoriť kontajnery pre všetky aplikácie, ktoré som potreboval na testovanie vo vnútri iného kontajnera (nazvime to stagingový kontajner). Myšlienkou bolo spustiť prípravný kontajner s príznakom -rm, ktorý po zastavení automaticky vymaže celý kontajner a celý jeho obsah. Pohral som si s obrázkom Docker zo samotného Dockera (
Prax. Šišky
Dal som si za cieľ, aby nádoba fungovala tak, ako som potrebovala, a pokračovala som v experimentoch, ktorých výsledkom bolo nespočetné množstvo púčikov. Výsledkom môjho sebatrýznenia bol nasledujúci algoritmus:
-
Kontajner Docker spustíme v interaktívnom režime.
docker run --privileged -it docker:18.09.6
Venujte pozornosť verzii nádoby, urobte krok doprava alebo doľava a váš DinD sa zmení na tekvicu. V skutočnosti sa veci pokazia pomerne často, keď vyjde nová verzia.
Musíme sa okamžite dostať do škrupiny. -
Snažíme sa zistiť, ktoré kontajnery sú spustené (odpoveď: žiadne), ale aj tak príkaz spustíme:
docker ps
Budete trochu prekvapení, ale ukáže sa, že démon Docker ani nebeží:
error during connect: Get http://docker:2375/v1.40/containers/json: dial tcp: lookup docker on 192.168.65.1:53: no such host
-
Poďme to spustiť sami:
dockerd &
Ďalšie nepríjemné prekvapenie:
failed to start daemon: Error initializing network controller: error obtaining controller instance: failed to create NAT chain DOCKER: Iptables not found
-
Nainštalujte balíky iptables a bash (v bash je všetko príjemnejšie ako v sh):
apk add --no-cache iptables bash
-
Spustíme bash. Konečne sme späť v bežnej ulite
-
Skúsme znova spustiť Docker:
dockerd &
Mali by sme vidieť dlhý list denníkov končiaci na:
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
-
Stlačte Enter. Sme späť v bash.
Odteraz sa môžeme pokúsiť spustiť ďalšie kontajnery v našom kontajneri Docker, ale čo ak chceme spustiť ďalší kontajner Docker v našom kontajneri Docker alebo sa niečo pokazí a kontajner zlyhá? Začnite odznova.
Vlastný kontajner DinD a nové experimenty
Aby som sa vyhol opakovaniu vyššie uvedených krokov znova a znova, vytvoril som si vlastný kontajner DinD:
Pracovné riešenie DinD mi dalo možnosť rekurzívne spúšťať Docker vo vnútri Dockera a robiť dobrodružnejšie experimenty.
Jeden taký (úspešný) experiment s prevádzkovaním MySQL a Nodejs teraz popíšem.
Tí najnetrpezlivejší sa môžu pozrieť, ako to tu bolo
Začnime teda:
-
DinD spúšťame v interaktívnom režime. V tejto verzii DinD musíme manuálne zmapovať všetky porty, ktoré môžu naše podriadené kontajnery používať (už na tom pracujem)
docker run --privileged -it -p 80:8080 -p 3306:3306 alekslitvinenk/dind
Dostaneme sa do bash, odkiaľ môžeme okamžite začať spúšťať detské kontajnery.
-
Spustite MySQL:
docker run --name mysql -e MYSQL_ROOT_PASSWORD=strongpassword -d -p 3306:3306 mysql
-
K databáze sa pripájame rovnakým spôsobom, ako by sme sa k nej pripájali lokálne. Uistime sa, že všetko funguje.
-
Spustite druhý kontajner:
docker run -d --rm -p 8080:8080 alekslitvinenk/hello-world-nodejs-server
Upozorňujeme, že mapovanie portov bude presné 8080:8080, keďže sme už namapovali port 80 z hostiteľa do nadradeného kontajnera na port 8080.
-
V prehliadači prejdeme na localhost a uistite sa, že server odpovedá "Ahoj svet!"
V mojom prípade experiment s vnorenými kontajnermi Docker dopadol celkom pozitívne a projekt budem ďalej rozvíjať a využívať na staging. Zdá sa mi, že je to oveľa odľahčenejšie riešenie ako Kubernetes a Jenkins X. Ale toto je môj subjektívny názor.
Myslím, že to je pre dnešný článok všetko. V ďalšom článku podrobnejšie popíšem experimenty s rekurzívnym spúšťaním Dockera v Dockeri a pripájaním adresárov hlboko do vnorených kontajnerov.
PS Ak považujete tento projekt za užitočný, dajte mu hviezdičku na GitHub, rozdeľte ho a povedzte to svojim priateľom.
Upraviť1 Opravené chyby, zameraná na 2 videá
Zdroj: hab.com