Como executei Docker dentro de Docker e que saíu del

Ola a todos! No seu artigo anterior, Prometín falar sobre a execución de Docker en Docker e os aspectos prácticos do uso desta lección. É hora de cumprir a túa promesa. Probablemente, un devopser experimentado obxectará que aqueles que necesiten Docker dentro de Docker simplemente reenvíen o socket daemon Docker do host ao contedor e isto será suficiente no 99% dos casos. Pero non te apresures a botarme galletas, porque falaremos de executar realmente Docker dentro de Docker. Esta solución ten moitas aplicacións posibles e este artigo trata sobre unha delas, así que senta e endereita os brazos diante de ti.

Como executei Docker dentro de Docker e que saíu del

Comezar

Todo comezou nunha noite chuviosa de setembro cando estaba a limpar a máquina que aluguei por 5 dólares en Digital Ocean, que estaba conxelada debido ao feito de que Docker enchera os 24 gigabytes de espazo dispoñible en disco coas súas imaxes e contedores. A ironía foi que todas estas imaxes e contedores eran transitorios e só eran necesarios para probar o rendemento da miña aplicación cada vez que se publicaba unha nova versión dunha biblioteca ou marco. Tentei escribir scripts de shell e configurar unha programación cron para limpar o lixo, pero non axudou: cada vez remataba inevitablemente co espazo en disco do meu servidor consumido e o servidor colgado (no mellor dos casos). Nalgún momento, atopeime cun artigo sobre como executar Jenkins nun contedor e como pode crear e eliminar canalizacións de construción a través dun socket daemon docker que se envía a el. Gustoume a idea, pero decidín ir máis aló e tentar experimentar coa execución directa de Docker dentro de Docker. Nese momento, pareceume unha solución completamente lóxica descargar imaxes de Docker e crear contedores para todas as aplicacións que necesitaba para probar dentro doutro contenedor (chamémoslle un contedor de preparación). A idea era iniciar un contedor de preparación coa bandeira -rm, que elimina automaticamente todo o contenedor e todo o seu contido cando se detén. Retoquei a imaxe de Docker do propio Docker (https://hub.docker.com/_/docker), pero resultou demasiado engorroso e nunca conseguín que funcionase como o necesitaba e quería facer eu mesmo.

Práctica. Conos

Púxenme a facer que o recipiente funcionase como necesitaba e continuei os meus experimentos, que deron como resultado unha infinidade de xemas. O resultado da miña auto-tortura foi o seguinte algoritmo:

  1. Lanzamos o contedor Docker en modo interactivo.

    docker run --privileged -it docker:18.09.6

    Presta atención á versión do recipiente, paso á dereita ou á esquerda e o teu DinD convértese nunha cabaza. De feito, as cousas rompen con bastante frecuencia cando se publica unha nova versión.
    Debemos entrar inmediatamente na cuncha.

  2. Estamos tentando descubrir que contedores están a executarse (Resposta: ningún), pero executemos o comando de todos os xeitos:

    docker ps

    Sorprenderás un pouco, pero resulta que o daemon Docker nin sequera se está a executar:

    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. Imos executalo nós mesmos:

    dockerd &

    Outra sorpresa desagradable:

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

  4. Instala os paquetes iptables e bash (todo é máis agradable traballar en bash que en sh):

    apk add --no-cache iptables bash

  5. Imos lanzar bash. Por fin volvemos ao caparazón de sempre

  6. Tentemos iniciar Docker de novo:

    dockerd &

    Deberíamos ver unha longa folla de rexistros que remata con:

    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. Preme Intro. Voltamos á festa.

A partir de agora, podemos tentar lanzar outros contedores dentro do noso contedor Docker, pero que pasa se queremos lanzar outro contedor Docker dentro do noso contedor Docker ou algo sae mal e o contedor falla? Empeza todo de novo.

Contador DinD propio e novos experimentos

Como executei Docker dentro de Docker e que saíu del
Para evitar repetir os pasos anteriores unha e outra vez, creei o meu propio contenedor DinD:

https://github.com/alekslitvinenk/dind

A solución DinD que funciona me deu a posibilidade de executar Docker dentro de Docker de forma recursiva e facer experimentos máis aventureiros.
Vou describir un experimento deste tipo (exitoso) coa execución de MySQL e Nodejs agora.
Os máis impacientes poden ver como foi aquí

Entón, imos comezar:

  1. Lanzamos DinD en modo interactivo. Nesta versión de DinD, necesitamos mapear manualmente todos os portos que poden usar os nosos contedores fillos (xa estou traballando nisto)

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

    Entramos no bash, desde onde podemos comezar inmediatamente a lanzar contedores infantís.

  2. Iniciar MySQL:

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

  3. Conectámonos á base de datos do mesmo xeito que nos conectariamos a ela localmente. Asegurémonos de que todo funcione.

  4. Inicia o segundo contedor:

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

    Teña en conta que o mapeo do porto será exactamente 8080:8080, xa que xa mapeamos o porto 80 do host ao contenedor principal ao porto 8080.

  5. Imos a localhost no navegador, asegúrese de que o servidor responde "Ola mundo!"

No meu caso, o experimento con contedores Docker aniñados resultou bastante positivo e seguirei desenvolvendo o proxecto e usándoo para a posta en escena. Paréceme que esta é unha solución moito máis lixeira que Kubernetes e Jenkins X. Pero esta é a miña opinión subxectiva.

Creo que iso é todo para o artigo de hoxe. No seguinte artigo describirei con máis detalle experimentos coa execución de Docker de forma recursiva en Docker e o montaxe de directorios en contedores aniñados.

PS Se cres que este proxecto é útil, dálle unha estrela en GitHub, quítao e dillo aos teus amigos.

Edit1 Erros corrixidos, centrados en 2 vídeos

Fonte: www.habr.com

Engadir un comentario