Com vaig executar Docker dins de Docker i què en va sortir

Hola a tots! En el seu article anterior, em vaig comprometre a parlar de l'execució de Docker a Docker i dels aspectes pràctics d'utilitzar aquesta lliçó. És hora de complir la teva promesa. Un devopser experimentat probablement s'oposarà que aquells que necessiten Docker dins de Docker simplement reenvien el sòcol del dimoni Docker de l'amfitrió al contenidor i això serà suficient en el 99% dels casos. Però no us afanyeu a llançar-me galetes, perquè parlarem d'executar realment Docker dins de Docker. Aquesta solució té moltes aplicacions possibles i aquest article tracta sobre una d'elles, així que asseieu-vos i estireu els braços davant vostre.

Com vaig executar Docker dins de Docker i què en va sortir

Начало

Tot va començar un vespre plujós de setembre quan estava netejant la màquina que vaig llogar per 5 dòlars a Digital Ocean, que es va congelar perquè Docker havia omplert els 24 gigabytes d'espai disponible amb les seves imatges i contenidors. La ironia era que totes aquestes imatges i contenidors eren transitoris i només es necessitaven per provar el rendiment de la meva aplicació cada vegada que es publicava una nova versió d'una biblioteca o marc. Vaig provar d'escriure scripts d'intèrpret d'ordres i configurar una programació de cron per netejar les escombraries, però no va ajudar: cada vegada inevitablement acabava amb l'espai de disc del meu servidor que s'esgotava i el servidor es penjava (en el millor dels casos). En algun moment, em vaig trobar amb un article sobre com executar Jenkins en un contenidor i com es pot crear i suprimir canalitzacions de construcció a través d'un sòcol de dimoni docker enviat a ell. Em va agradar la idea, però vaig decidir anar més enllà i intentar experimentar amb l'execució directa de Docker dins de Docker. En aquell moment, em va semblar una solució completament lògica per descarregar imatges de Docker i crear contenidors per a totes les aplicacions que necessitava per provar dins d'un altre contenidor (diguem-ne un contenidor de prova). La idea era iniciar un contenidor de prova amb el senyalador -rm, que esborra automàticament tot el contenidor i tot el seu contingut quan s'atura. Vaig jugar amb la imatge de Docker del mateix Docker (https://hub.docker.com/_/docker), però va resultar massa feixuc i mai vaig aconseguir que funcionés com ho necessitava i vaig voler anar jo mateix.

Pràctica. Cons

Em vaig proposar fer que el recipient funcionés de la manera que necessitava i vaig continuar els meus experiments, que van donar com a resultat una infinitat de cabdells. El resultat de la meva autotortura va ser el següent algorisme:

  1. Llencem el contenidor Docker en mode interactiu.

    docker run --privileged -it docker:18.09.6

    Fixeu-vos en la versió del recipient, feu un pas a la dreta o a l'esquerra i el vostre DinD es converteix en una carbassa. De fet, les coses es trenquen amb força freqüència quan es publica una nova versió.
    Hem d'entrar immediatament a la closca.

  2. Estem intentant esbrinar quins contenidors s'estan executant (Resposta: cap), però executem l'ordre de totes maneres:

    docker ps

    Us sorprendrà una mica, però resulta que el dimoni Docker ni tan sols s'està executant:

    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. Anem a executar-ho nosaltres mateixos:

    dockerd &

    Una altra sorpresa desagradable:

    failed to start daemon: Error initializing network controller: error obtaining controller instance: failed 
    to create NAT chain DOCKER: Iptables not found

  4. Instal·leu els paquets iptables i bash (tot és més agradable treballar en bash que en sh):

    apk add --no-cache iptables bash

  5. Anem a llançar bash. Per fi tornem a la closca de sempre

  6. Intentem tornar a iniciar Docker:

    dockerd &

    Hauríem de veure un full de registre llarg que acaba amb:

    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. Premeu Intro. Tornem a la festa.

A partir d'ara, podem intentar llançar altres contenidors dins del nostre contenidor Docker, però què passa si volem llançar un altre contenidor Docker dins del nostre contenidor Docker o alguna cosa va malament i el contenidor es bloqueja? Començar de nou.

Contenidor DinD propi i nous experiments

Com vaig executar Docker dins de Docker i què en va sortir
Per evitar repetir els passos anteriors una i altra vegada, vaig crear el meu propi contenidor DinD:

https://github.com/alekslitvinenk/dind

La solució DinD que funcionava em va donar la possibilitat d'executar Docker dins de Docker de forma recursiva i fer experiments més aventurers.
Vaig a descriure un d'aquests experiments (èxit) amb l'execució de MySQL i Nodejs ara.
Els més impacients poden veure com era aquí

Comencem doncs:

  1. Llencem DinD en mode interactiu. En aquesta versió de DinD, hem de mapejar manualment tots els ports que poden utilitzar els nostres contenidors fills (ja estic treballant en això)

    docker run --privileged -it 
    -p 80:8080 
    -p 3306:3306 
    alekslitvinenk/dind

    Entrem a la bash, des d'on podem començar immediatament a llançar contenidors infantils.

  2. Inicieu MySQL:

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

  3. Ens connectem a la base de dades de la mateixa manera que ens connectaríem a ella localment. Assegurem-nos que tot funcioni.

  4. Inicieu el segon contenidor:

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

    Tingueu en compte que el mapeig del port serà exactament 8080:8080, ja que ja hem assignat el port 80 de l'amfitrió al contenidor principal al port 8080.

  5. Anem a localhost al navegador, assegureu-vos que el servidor respon "Hola món!"

En el meu cas, l'experiment amb contenidors Docker imbricats va resultar força positiu i continuaré desenvolupant el projecte i utilitzant-lo per a la posada en escena. Em sembla que aquesta és una solució molt més lleugera que Kubernetes i Jenkins X. Però aquesta és la meva opinió subjectiva.

Crec que això és tot per l'article d'avui. Al següent article descriuré amb més detall experiments amb l'execució recursiva de Docker a Docker i el muntatge de directoris a fons en contenidors imbricats.

PS Si trobeu útil aquest projecte, poseu-li una estrella a GitHub, forqueu-lo i digueu-lo als vostres amics.

Edit1 Errors corregits, centrats en 2 vídeos

Font: www.habr.com

Afegeix comentari