Salut tuturor! În cadrul meu , Țin să vă spun despre rularea Docker-ului în Docker și despre aspectele practice ale acestei activități. A sosit momentul să-mi îndeplinesc promisiunea. Un DevOps experimentat ar putea argumenta că pentru cei care au nevoie de Docker în interiorul Docker-ului, se poate pur și simplu să se redirecționeze socket-ul demonului Docker din gazdă în container, iar asta ar fi suficient în 99% din cazuri. Dar nu vă grăbiți să-mi aruncați biscuiți, deoarece vorbim despre o rulare reală a Docker-ului în interiorul Docker-ului. Această soluție are multe aplicații posibile și despre una dintre ele este acest articol, așa că așezați-vă confortabil și întindeți-vă mâinile în fața dumneavoastră.

Început
Totul a început într-o seară ploioasă de septembrie, când curățam o mașină închiriată pentru 5$ pe Digital Ocean, care s-a blocat complet deoarece Docker a ocupat toate cele 24 de gigaocteți de spațiu disc disponibil cu imaginile și containerele sale. Ironia era că toate aceste imagini și containere erau tranzitorii și erau necesare doar pentru a testa funcționalitatea aplicației mele de fiecare dată când ieșea o nouă versiune a unei biblioteci sau a unui cadru. Am încercat să scriu scripturi bash și să configurez un program de tip cron pentru a curăța gunoiul, dar asta nu m-a salvat: de fiecare dată, era inevitabil ca spațiul pe disc al serverului meu să fie consumat, iar serverul să se blocheze (în cel mai bun caz). La un moment dat, am dat peste un articol despre cum să rulezi Jenkins într-un container și cum el poate crea și șterge pipe-urile de construcție prin socket-ul redirecționat al demonului Docker. Mie mi-a plăcut ideea, dar am decis să merg mai departe și să încerc să experimentez cu rularea Docker-ului în interiorul Docker-ului. Atunci mi s-a părut o soluție logică să descarc imaginile Docker și să creez containere pentru toate aplicațiile de care aveam nevoie pentru testare în interiorul unui alt container (să-l numim containerul staging). Ideea era să rulez containerul staging cu flag-ul -rm, care șterge automat întregul container cu tot conținutul său la oprire. Am săpat în imaginea Docker a Docker-ului,, dar s-a dovedit a fi prea greoaie și nu am reușit să o fac să funcționeze așa cum aveam nevoie și am vrut să parcurg întregul proces singur.
Practică. Bătăi de cap
M-am decis să fac containerul să funcționeze așa cum aveam nevoie și am continuat experimentele mele, rezultatul cărora a fost un număr imens de greșeli. Concluzia autodistanțării mele este următorul algoritm:
Lansăm containerul Docker în modul interactiv.
docker run --privileged -it docker:18.09.6Atenție la versiunea containerului, un pas în dreapta sau în stânga și DinD-ul tău devine o dovleac. De fapt, totul se strică destul de des odată cu lansarea unei noi versiuni.
Trebuie să ajungem imediat în shell.Încercăm să aflăm ce containere sunt active (Răspuns: niciunul), dar să executăm comanda oricum:
docker psVei fi puțin surprins, dar se pare că demonul Docker nici măcar nu este pornit:
eroare în timpul conectării: Get http://docker:2375/v1.40/containers/json: dial tcp: lookup docker on 192.168.65.1:53: nu există un astfel de gazdăHai să-l pornim manual:
dockerd &Încă o neplăcere:
a eșuat să pornească demonul: Eroare la inițializarea controlerului de rețea: eroare obținând instanța controlerului: nu a reușit să creeze lanțul NAT DOCKER: Iptables nu au fost găsiteInstalăm pachetele iptables și bash (în bash este mult mai plăcut să lucrezi decât în sh):
apk add --no-cache iptables bashLansăm bash. În sfârșit, suntem din nou în shell-ul obișnuit
încercăm să lansăm Docker încă o dată:
dockerd &Trebuie să vedem o lungă listă de jurnale care se termină cu:
INFO[2019-11-25T19:51:19.448080400Z] Demonul a finalizat inițializarea INFO[2019-11-25T19:51:19.474439300Z] API-ul ascultă pe /var/run/docker.sockApăsăm Enter. Suntem din nou în bash.
Începând cu acest moment, putem încerca să lansăm alte containere în interiorul containerului nostru Docker, dar ce se întâmplă dacă dorim să ridicăm încă un container Docker în interiorul containerului nostru Docker sau ceva nu va merge bine și containerul „se va cufunda”? Începem din nou.
Containerul nostru propriu DinD și noi experimente
Pentru a nu repeta pașii descriși mai sus iar și iar, am creat propriul meu container DinD:
Soluția de lucru DinD mi-a permis să rulez Docker în interiorul Docker-ului în mod recursiv și să fac experimente mai îndrăznețe.
Un astfel de experiment (de succes) cu lansarea MySQL și Nodejs pe care mă pregătesc să-l descriu acum.
Cei mai nerăbdători pot vedea cum a fost aici

Așadar, să începem:
Lansăm DinD în modul interactiv. În această versiune DinD, trebuie să mapăm manual toate porturile care ar putea fi utilizate de containerele noastre fiice (lucrez deja la asta)
docker run --privileged -it -p 80:8080 -p 3306:3306 alekslitvinenk/dindAjungem în Bash, de unde putem începe imediat să lansăm containerele secundare.
Lansăm MySQL:
docker run --name mysql -e MYSQL_ROOT_PASSWORD=strongpassword -d -p 3306:3306 mysqlNe conectăm la baza de date la fel cum ne-am conecta local. Ne asigurăm că totul funcționează.
Lansăm al doilea container:
docker run -d --rm -p 8080:8080 alekslitvinenk/hello-world-nodejs-serverRețineți că port mapping-ul aici va fi exact 8080:8080, deoarece am mapat deja portul 80 de pe host în containerul părinte pe portul 8080.
Accesăm localhost în browser și ne asigurăm că serverul răspunde cu „Hello World!”.
În cazul meu, experimentul cu containere Docker înlănțuite s-a dovedit a fi destul de pozitiv și voi continua să dezvolt proiectul și să-l folosesc pentru staging. Mi se pare că aceasta este o soluție mult mai ușoară decât Kubernetes sau Jenkins X. Dar aceasta este părerea mea subiectivă.
Cred că pentru articolul de astăzi – asta e tot. În următorul articol, voi detalia mai multe experimente cu lansarea recursive a Docker-ului în Docker și montarea directorilor în adâncimea containerelor înlănțuite.
P.S. Dacă considerați că acest proiect este util, vă rog să-i dați o stea pe GitHub, să-l fork-uți și să povestiți prietenilor.
Edit1 Am corectat erorile, am pus accent pe 2 videoclipuri
Sursa: habr.com
