Hoe ik Docker in Docker draaide en wat eruit kwam

Dag Allemaal! In zijn vorige artikel, beloofde ik te praten over het uitvoeren van Docker in Docker en de praktische aspecten van het gebruik van deze les. Het is tijd om je belofte na te komen. Een ervaren devopser zal waarschijnlijk tegenwerpen dat degenen die Docker in Docker nodig hebben, eenvoudigweg de Docker-daemon-socket van de host naar de container doorsturen en dit zal in 99% van de gevallen voldoende zijn. Maar haast je niet om koekjes naar me te gooien, want we zullen het hebben over het daadwerkelijk draaien van Docker in Docker. Deze oplossing heeft veel mogelijke toepassingen en dit artikel gaat over een daarvan, dus leun achterover en strek uw armen voor u.

Hoe ik Docker in Docker draaide en wat eruit kwam

begin

Het begon allemaal op een regenachtige septemberavond toen ik de machine aan het schoonmaken was die ik voor $ 5 had gehuurd op Digital Ocean, die vastliep vanwege het feit dat Docker alle 24 gigabyte aan beschikbare schijfruimte had gevuld met zijn images en containers. De ironie was dat al deze afbeeldingen en containers van voorbijgaande aard waren en alleen nodig waren om de prestaties van mijn applicatie te testen telkens wanneer een nieuwe versie van een bibliotheek of raamwerk werd uitgebracht. Ik heb geprobeerd shell-scripts te schrijven en een cron-schema op te zetten om rommel op te ruimen, maar het hielp niet: elke keer eindigde het onvermijdelijk dat de schijfruimte van mijn server werd opgegeten en de server bleef hangen (op zijn best). Op een gegeven moment kwam ik een artikel tegen over hoe je Jenkins in een container kunt draaien en hoe het build-pijplijnen kan maken en verwijderen via een docker-daemon-socket die ernaar wordt doorgestuurd. Ik vond het een leuk idee, maar ik besloot verder te gaan en te proberen te experimenteren met het rechtstreeks uitvoeren van Docker in Docker. Op dat moment leek het mij een volkomen logische oplossing om Docker-images te downloaden en containers te maken voor alle applicaties die ik nodig had om te testen in een andere container (laten we het een staging-container noemen). Het idee was om een ​​staging-container te starten met de vlag -rm, die automatisch de hele container en de volledige inhoud ervan verwijdert wanneer deze wordt gestopt. Ik heb gesleuteld aan de Docker-image van Docker zelf (https://hub.docker.com/_/docker), maar het bleek te omslachtig en het is mij nooit gelukt om het werkend te krijgen zoals ik het nodig had en ik wilde er zelf helemaal voor gaan.

Oefening. Kegels

Ik wilde de container laten werken zoals ik dat wilde en ging door met mijn experimenten, wat resulteerde in een groot aantal toppen. Het resultaat van mijn zelfmarteling was het volgende algoritme:

  1. We lanceren de Docker-container in interactieve modus.

    docker run --privileged -it docker:18.09.6

    Let op de uitvoering van de container, stap naar rechts of links en je DinD verandert in een pompoen. Er gaan zelfs nogal eens dingen stuk als er een nieuwe versie wordt uitgebracht.
    We moeten onmiddellijk in de schaal kruipen.

  2. We proberen erachter te komen welke containers actief zijn (antwoord: geen), maar laten we toch de opdracht uitvoeren:

    docker ps

    Je zult een beetje verrast zijn, maar het blijkt dat de Docker-daemon niet eens actief is:

    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. Laten we het zelf uitvoeren:

    dockerd &

    Nog een onaangename verrassing:

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

  4. Installeer de iptables en bash-pakketten (alles is prettiger om in bash te werken dan in sh):

    apk add --no-cache iptables bash

  5. Laten we bash lanceren. Eindelijk zitten we weer in de gebruikelijke schelp

  6. Laten we Docker opnieuw proberen te starten:

    dockerd &

    We zouden een lang blad met logboeken moeten zien dat eindigt met:

    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. Druk op Enter. We zijn weer terug in de bash.

Vanaf nu kunnen we proberen andere containers in onze Docker-container te lanceren, maar wat als we een andere Docker-container in onze Docker-container willen lanceren of als er iets misgaat en de container crasht? Helemaal opnieuw beginnen.

Eigen DinD-container en nieuwe experimenten

Hoe ik Docker in Docker draaide en wat eruit kwam
Om te voorkomen dat bovenstaande stappen steeds opnieuw worden herhaald, heb ik mijn eigen DinD-container gemaakt:

https://github.com/alekslitvinenk/dind

De werkende DinD-oplossing gaf me de mogelijkheid om Docker recursief binnen Docker te draaien en meer avontuurlijke experimenten uit te voeren.
Ik ga nu een dergelijk (succesvol) experiment beschrijven met het uitvoeren van MySQL en Nodejs.
De meest ongeduldigen kunnen zien hoe het hier was

Dus laten we beginnen:

  1. We lanceren DinD in interactieve modus. In deze versie van DinD moeten we alle poorten die onze onderliggende containers kunnen gebruiken handmatig in kaart brengen (ik ben hier al mee bezig)

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

    We stappen in de bash, vanwaar we onmiddellijk kunnen beginnen met het lanceren van kindercontainers.

  2. MySQL starten:

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

  3. We maken verbinding met de database op dezelfde manier als we er lokaal verbinding mee zouden maken. Laten we ervoor zorgen dat alles werkt.

  4. Lanceer de tweede container:

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

    Houd er rekening mee dat de poorttoewijzing exact zal zijn 8080:8080, omdat we poort 80 al in kaart hebben gebracht van de host naar de bovenliggende container naar poort 8080.

  5. We gaan naar localhost in de browser, zorgen ervoor dat de server antwoordt “Hallo wereld!”

In mijn geval bleek het experiment met geneste Docker-containers behoorlijk positief en ik zal het project blijven ontwikkelen en gebruiken voor staging. Het lijkt mij dat dit een veel lichtere oplossing is dan Kubernetes en Jenkins X. Maar dit is mijn subjectieve mening.

Ik denk dat dit alles is voor het artikel van vandaag. In het volgende artikel zal ik in meer detail experimenten beschrijven met het recursief uitvoeren van Docker in Docker en het koppelen van mappen diep in geneste containers.

PS Als je dit project nuttig vindt, geef het dan een ster op GitHub, fork het en vertel het aan je vrienden.

Edit1 Fouten gecorrigeerd, gericht op 2 video's

Bron: www.habr.com

Voeg een reactie