Hogyan indítottam el a Dockert a Dockerben, és mi sült ki ebből

Üdv mindenkinek! A saját előző cikkben, í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.

Hogyan indítottam el a Dockert a Dockerben, és mi sült ki ebből

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 (https://hub.docker.com/_/docker), 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:

  1. Futtassuk a Docker konténert interaktív módban.

    docker run --privileged -it docker:18.09.6

    Figyeljü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.

  2. Próbáljuk meg kideríteni, hogy mely konténerek futnak (Válasz: egy sem), de fussunk le a parancsot amúgy is:

    docker ps

    Kicsit 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 host

  3. Indí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 found

  4. Telepítsük az iptables és bash csomagokat (a bashban mindig kényelmesebb dolgozni, mint a sh-ban):

    apk add --no-cache iptables bash

  5. Futtatjuk a bash-t. Végre újra a megszokott shellben vagyunk.

  6. 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.sock

  7. Megnyomjuk 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

Hogyan indítottam el a Dockert a Dockerben, és mi sült ki ebből
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:

https://github.com/alekslitvinenk/dind

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.

Videó lejátszása

Tehát kezdjük el:

  1. 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/dind

    Belépünk a konténerbe, ahonnan azonnal elkezdhetjük a gyermekkonténerek indítását.

  2. MySQL indítása:

    docker run --name mysql -e MYSQL_ROOT_PASSWORD=strongpassword -d -p 3306:3306 mysql

  3. A adatbázishoz ugyanúgy csatlakozunk, ahogy helyben tennénk. Ellenőrizzük, hogy minden működik.

  4. A második konténer indítása:

    docker run -d --rm -p 8080:8080 alekslitvinenk/hello-world-nodejs-server

    Vegye 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.

  5. 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

Megbízható hosting vásárlása weboldalak számára, DDoS védelemmel, VPS VDS szerverek. 🔥 Megbízható webtárhely vásárlása DDoS védelemmel, VPS VDS szerverek | ProHoster