Hur jag körde Docker i Docker och vad som kom ut ur det

Hej alla! I hans tidigare artikel, jag lovade att prata om att köra Docker i Docker och de praktiska aspekterna av att använda den här lektionen. Det är dags att hålla ditt löfte. En erfaren devopser kommer förmodligen att invända att de som behöver Docker inuti Docker helt enkelt vidarebefordrar Docker-demonsocket från värden till behållaren och detta kommer att räcka i 99% av fallen. Men skynda dig inte att kasta kakor på mig, för vi kommer att prata om att faktiskt köra Docker i Docker. Denna lösning har många möjliga tillämpningar och den här artikeln handlar om en av dem, så luta dig tillbaka och räta ut armarna framför dig.

Hur jag körde Docker i Docker och vad som kom ut ur det

börjar

Allt började en regnig septemberkväll när jag städade maskinen jag hyrde för 5 USD på Digital Ocean, som frystes på grund av att Docker hade fyllt alla 24 gigabyte tillgängligt diskutrymme med sina bilder och behållare. Det ironiska var att alla dessa bilder och behållare var övergående och behövdes bara för att testa prestandan för min applikation varje gång en ny version av ett bibliotek eller ramverk släpptes. Jag försökte skriva skalskript och sätta upp ett cron-schema för att städa upp skräp, men det hjälpte inte: varje gång slutade det oundvikligen med att min servers diskutrymme äts upp och servern hängde (i bästa fall). Vid något tillfälle stötte jag på en artikel om hur man kör Jenkins i en behållare och hur den kan skapa och ta bort byggpipelines genom en docker-demonsocket som skickas in i den. Jag gillade idén, men jag bestämde mig för att gå längre och försöka experimentera med att köra Docker direkt i Docker. På den tiden verkade det för mig som en helt logisk lösning att ladda ner Docker-bilder och skapa behållare för alla applikationer som jag behövde för att testa inuti en annan behållare (låt oss kalla det en iscensättningsbehållare). Tanken var att starta en iscensättningscontainer med flaggan -rm, som automatiskt tar bort hela containern och allt dess innehåll när den stoppas. Jag pysslade med Docker-bilden från Docker själv (https://hub.docker.com/_/docker), men det visade sig vara för krångligt och jag lyckades aldrig få det att fungera som jag behövde det och jag ville gå hela vägen själv.

Öva. Kottar

Jag satte mig för att få behållaren att fungera som jag behövde och fortsatte mina experiment, vilket resulterade i en myriad av knoppar. Resultatet av min självplågeri var följande algoritm:

  1. Vi lanserar Docker-behållaren i interaktivt läge.

    docker run --privileged -it docker:18.09.6

    Var uppmärksam på versionen av behållaren, steg åt höger eller vänster och din DinD förvandlas till en pumpa. Faktum är att saker går sönder ganska ofta när en ny version släpps.
    Vi måste omedelbart komma in i skalet.

  2. Vi försöker ta reda på vilka behållare som körs (Svar: inga), men låt oss köra kommandot ändå:

    docker ps

    Du kommer att bli lite förvånad, men det visar sig att Docker-demonen inte ens körs:

    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. Låt oss köra det själva:

    dockerd &

    Ytterligare en obehaglig överraskning:

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

  4. Installera iptables och bash-paketen (allt är trevligare att arbeta i bash än i sh):

    apk add --no-cache iptables bash

  5. Låt oss starta bash. Äntligen är vi tillbaka i det vanliga skalet

  6. Låt oss försöka köra Docker igen:

    dockerd &

    Vi borde se ett långt ark med loggar som slutar med:

    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. Tryck enter. Vi är tillbaka i bash.

Från och med nu kan vi försöka starta andra containrar inuti vår Docker-container, men vad händer om vi vill starta en annan Docker-container inuti vår Docker-container eller något går fel och containern kraschar? Börja om från början.

Egen DinD-behållare och nya experiment

Hur jag körde Docker i Docker och vad som kom ut ur det
För att undvika att upprepa stegen ovan om och om igen skapade jag min egen DinD-behållare:

https://github.com/alekslitvinenk/dind

Den fungerande DinD-lösningen gav mig möjligheten att köra Docker inuti Docker rekursivt och göra mer äventyrliga experiment.
Jag kommer att beskriva ett sådant (lyckat) experiment med att köra MySQL och Nodejs nu.
Den mest otåliga kan se hur det var här

Så låt oss börja:

  1. Vi lanserar DinD i interaktivt läge. I den här versionen av DinD måste vi manuellt kartlägga alla portar som våra underordnade containrar kan använda (jag jobbar redan med detta)

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

    Vi går in i bashen, varifrån vi omedelbart kan börja sjösätta barncontainrar.

  2. Starta MySQL:

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

  3. Vi ansluter till databasen på samma sätt som vi skulle ansluta till den lokalt. Låt oss se till att allt fungerar.

  4. Starta den andra behållaren:

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

    Observera att portmappningen kommer att vara exakt 8080:8080, eftersom vi redan har mappat port 80 från värden till den överordnade behållaren till port 8080.

  5. Vi går till localhost i webbläsaren, se till att servern svarar "Hello World!"

I mitt fall visade sig experimentet med kapslade Docker-behållare vara ganska positivt och jag kommer att fortsätta att utveckla projektet och använda det för iscensättning. Det verkar för mig att detta är en mycket lättare lösning än Kubernetes och Jenkins X. Men detta är min subjektiva åsikt.

Jag tror att det var allt för dagens artikel. I nästa artikel kommer jag att beskriva mer detaljerat experiment med att köra Docker rekursivt i Docker och montera kataloger djupt in i kapslade behållare.

PS Om du tycker att det här projektet är användbart, vänligen ge det en stjärna på GitHub, dela det och berätta för dina vänner.

Edit1 Rättade fel, fokuserade på 2 videor

Källa: will.com

Lägg en kommentar