Üdv mindenkinek! A saját , ígéretet tettem arra, hogy elmondom, hogyan indítható el a Dockerben a Docker, és a gyakorlati oldalairól is beszélek. Itt az ideje, hogy teljesítsem az ígéretemet. Egy tapasztalt devops szakember talán azt fogja mondani, hogy akinek szüksége van a Dockerre a Dockerben, az egyszerűen áttolja a Docker démon socketet a hostból a konténerbe, és ez 99%-ban elegendő. De ne siessetek, hogy süsd el a sütiket, mert valóban a Docker indításáról fogunk beszélni a Dockerben. Ennek a megoldásnak sok lehetséges felhasználási területe van, és e cikk egy ilyenről szól, úgyhogy foglaljatok helyet és nyújtsátok ki a kezeiteket magatok előtt.

Kezdet
Minden egy esős szeptemberi estén kezdődött, amikor a Digital Ocean-on bérelt $5-os gépemet takarítottam, amely megállt, mert a Docker tele volt képekkel és konténerekkel, és minden 24 gigabájt elérhető lemezterületet elfoglalt. A szomorú irónia az volt, hogy ezek az összes képek és konténerek átmenetiek voltak, és csak arra kellettek, hogy minden alkalommal teszteljem az alkalmazásom működését, amikor új verzió jelent meg bármelyik könyvtár vagy keretrendszer esetén. Próbáltam shell szkripteket írni és krónikus ütemezést beállítani a szemét eltávolítására, de ez sem segített: minden alkalommal elkerülhetetlenül azzal végződött, hogy a szerverem lemezterülete elfogyott, és a szerver megakadt (jobb esetben). Egy bizonyos pillanatban belefutottam egy cikkbe arról, hogyan lehet a Jenkinst konténerben futtatni, és hogyan hozhat létre és törölhet építési pipeline-okat az áthidalva a Docker démon socketet. Tetszett az ötlet, de úgy döntöttem, hogy továbbmegyek, és kísérletet teszek a Docker közvetlen indítására a Dockerben. Akkoriban logikus megoldásnak tűnt, hogy a szükséges Docker képeket és konténereket mindegyik alkalmazáshoz letöltsem egy másik konténeren belül (hívjuk staging konténernek). Az ötlet az volt, hogy a staging konténert az -rm kapcsolóval indítom, amely automatikusan törli az egész konténert minden tartalmával a leállításakor. Végigböngésztem a Docker saját Docker képét (), de az túl terjedelmesnek bizonyult, és nem sikerült beállítanom, hogy úgy működjön, ahogy szeretném, és azt akartam, hogy magam járjam végig az utat.
Gyakorlat. Pofonok
Arra törekedtem, hogy a konténer úgy működjön, ahogy szeretném, és folytattam a kísérletezést, aminek eredményeként számos hibát vétettem. Az önsanyargatásom eredménye a következő algoritmus lett:
Futtassuk a Docker konténert interaktív módban.
docker run --privileged -it docker:18.09.6Figyeljünk a konténer verziójára, egy lépés jobbra vagy balra, és a DinD tökös lesz. Valójában a dolgok gyakran összezúzódnak egy új verzió megjelenésével.
Azonnal a shellbe kell kerülnünk.Próbáljuk meg kideríteni, hogy mely konténerek futnak (Válasz: egy sem), de fussunk le a parancsot amúgy is:
docker psKicsit meglepődhet, de kiderül, hogy a Docker démon még el sem indult:
error during connect: Get http://docker:2375/v1.40/containers/json: dial tcp: lookup docker on 192.168.65.1:53: no such hostIndítsuk el magunk:
dockerd &Még egy kellemetlen meglepetés:
failed to start daemon: Error initializing network controller: error obtaining controller instance: failed to create NAT chain DOCKER: Iptables not foundTelepítsük az iptables és bash csomagokat (a bashban mindig kényelmesebb dolgozni, mint a sh-ban):
apk add --no-cache iptables bashFuttatjuk a bash-t. Végre újra a megszokott shellben vagyunk.
Próbáljuk meg újraindítani a Dockert:
dockerd &Látnunk kell egy hosszú naplófájl végét:
INFO[2019-11-25T19:51:19.448080400Z] Daemon has completed initialization INFO[2019-11-25T19:51:19.474439300Z] API listen on /var/run/docker.sockMegnyomjuk az Entert. Újra a bash-ben vagyunk.
Mostantól kezdve kipróbálhatunk más konténereket a Docker konténerünk belsejében, de mi van, ha egy másik Docker konténert akarunk indítani a Docker konténerünk belsejében, vagy ha valami elromlik és a konténer "kidől"? Kezdjük az elejéről.
Saját DinD konténer és új kísérletek
Annak érdekében, hogy ne kelljen újra és újra a fent leírt lépéseket megtenni, létrehoztam a saját DinD kontényemet:
A működő DinD megoldás lehetővé tette számomra, hogy rekurszívan Docker-t futtassak a Docker belsejében, és merészebb kísérleteket végezzek.
Egy ilyen (sikeres) kísérletet a MySQL és Nodejs indításáról most fogok leírni.
A legizgatottabbak itt tudják megnézni, hogyan történt.

Tehát kezdjük el:
Indítsuk el a DinD-t interaktív módban. A DinD ezen verziójában manuálisan kell térképeznünk az összes portot, amelyet a gyermekkonténereink használhatnak (már dolgozom ezen).
docker run --privileged -it -p 80:8080 -p 3306:3306 alekslitvinenk/dindBelépünk a konténerbe, ahonnan azonnal elkezdhetjük a gyermekkonténerek indítását.
MySQL indítása:
docker run --name mysql -e MYSQL_ROOT_PASSWORD=strongpassword -d -p 3306:3306 mysqlA adatbázishoz ugyanúgy csatlakozunk, ahogy helyben tennénk. Ellenőrizzük, hogy minden működik.
A második konténer indítása:
docker run -d --rm -p 8080:8080 alekslitvinenk/hello-world-nodejs-serverVegye figyelembe, hogy a porttovábbítás itt pontosan 8080:8080, mivel már a 80-as portot a gazdagépről a szülőkonténer 8080-as portjára mappeltük.
Nyissuk meg a localhost-ot a böngészőben, és ellenőrizzük, hogy a szerver "Hello World!"-ot válaszol.
Saját tapasztalatom szerint a beágyazott Docker konténerekkel végzett kísérlet meglehetősen pozitív volt, és folytatni fogom a projekt fejlesztését, és használni fogom a stádiumozáshoz. Úgy érzem, hogy ez sokkal könnyebb megoldás, mint a Kubernetes vagy a Jenkins X. De ez az én szubjektív véleményem.
Azt hiszem, hogy a mai cikkhez ennyi. A következő cikkben részletesebben írok a Docker rekurszív indításával és a mappák mélyebbre történő csatolásával kapcsolatos kísérletekről.
P.S. Ha hasznosnak találja ezt a projektet, kérjük, adjon neki csillagot a GitHub-on, készítse el a fork-ot, és meséljen barátainak.
Edit1 Kijavítottam a hibákat, fókuszáltam 2 videóra.
Forrás: habr.com
