Hoe ik Docker binnen Docker heb uitgevoerd en wat daarvan het resultaat was

Hallo iedereen! In mijn vorig artikel, beloofde ik te vertellen over het draaien van Docker in Docker en de praktische aspecten van deze activiteit. Het is tijd om mijn belofte in te lossen. Een ervaren DevOps zal misschien betogen dat degenen die Docker binnen Docker nodig hebben, gewoon de socket van de Docker daemon van de host naar binnen in de container doorgeven en dat dit in 99% van de gevallen genoeg is. Maar wees niet te snel om koekjes naar me te gooien, want het gaat om het daadwerkelijke draaien van Docker binnen Docker. Deze oplossing heeft veel mogelijke toepassingsgebieden en over een daarvan gaat dit artikel, dus leun achterover en strek je handen voor je uit.

Hoe ik Docker binnen Docker heb uitgevoerd en wat daarvan het resultaat was

Inleiding

Alles begon op een regenachtige septemberavond, toen ik de voor $5 gehuurde machine op Digital Ocean schoonmaakte, die vastliep omdat Docker al zijn images en containers in de 24 gigabyte beschikbare opslagruimte had gekoloniseerd. De ironie was dat al deze images en containers transient waren en alleen nodig waren om de functionaliteit van mijn applicatie te testen elke keer dat er een nieuwe versie van een bibliotheek of framework uitkwam. Ik probeerde shell-scripts te schrijven en cron-taken in te stellen om de rommel op te ruimen, maar dat hielp niet: elke keer eindigde het onvermijdelijk met de opslagruimte van mijn server die opgegeten werd en de server die vastliep (in het beste geval). Op een gegeven moment stuitte ik op een artikel over het draaien van Jenkins in een container en hoe het in staat was om build pipelines te maken en te verwijderen via de doorgestuurde socket van de Docker daemon. Het idee sprak me aan, maar ik besloot om verder te gaan en te experimenteren met het rechtstreeks draaien van Docker binnen Docker. Het leek me toen een logische oplossing om Docker images te downloaden en containers van alle applicaties die ik nodig had voor testen binnen een andere container te creƫren (laten we deze de staging container noemen). Het idee was om de staging container te draaien met de vlag -rm, die automatisch de hele container samen met al zijn inhoud verwijdert wanneer deze wordt gestopt. Ik heb wat rondgekeken met het Docker image van Docker zelf (https://hub.docker.com/_/docker), maar het bleek te omslachtig en ik kon het niet laten werken zoals ik wilde, en ik wilde de hele weg zelf gaan.

Praktijk. Stoten

Ik had als doel gesteld om de container te laten werken zoals ik het nodig had en zette mijn experimenten voort, met als resultaat een ontelbaar aantal stoten. Het resultaat van mijn zelfkwelling was het volgende algoritme:

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

    docker run --privileged -it docker:18.09.6

    Let op de versie van de container, een stap naar rechts of links en je DinD wordt een pompoen. In werkelijkheid gaat alles behoorlijk vaak kapot met de uitkomst van een nieuwe versie.
    We moeten meteen naar de shell.

  2. Laten we proberen te ontdekken welke containers draaien (Antwoord: geen), maar laten we de opdracht toch uitvoeren:

    docker ps

    Je zult een beetje verrast zijn, maar het blijkt dat de Docker-daemon zelfs niet draait:

    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 starten:

    dockerd &

    Nog een vervelende verrassing:

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

  4. We installeren de iptables en bash-pakketten (werken in bash is altijd prettiger dan in sh):

    apk add --no-cache iptables bash

  5. We starten bash. Eindelijk zijn we terug in de vertrouwde shell.

  6. laten we proberen Docker opnieuw te starten:

    dockerd &

    We moeten een lange lijst logs zien eindigend 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. We drukken op Enter. We zijn weer in bash.

Vanaf dit moment kunnen we proberen andere containers te draaien binnen onze Docker-container, maar wat als we nog een Docker-container willen opstarten binnen onze Docker-container of als er iets misgaat en de container 'valt'? We beginnen weer helemaal opnieuw.

Eigen DinD-container en nieuwe experimenten

Hoe ik Docker binnen Docker heb uitgevoerd en wat daarvan het resultaat was
Om de bovenstaande stappen niet steeds opnieuw te hoeven herhalen, heb ik mijn eigen DinD-container gemaakt:

https://github.com/alekslitvinenk/dind

Een werkende DinD-oplossing gaf me de mogelijkheid om Docker binnen Docker recursief te draaien en dapperdere experimenten uit te voeren.
Een van die (succesvolle) experimenten met het draaien van MySQL en Nodejs ga ik nu beschrijven.
De meest ongeduldige kunnen zien hoe het hier was

Video afspelen

Laten we beginnen:

  1. We starten DinD in interactieve modus. In deze versie van DinD moeten we handmatig alle poorten mappen die onze kindcontainer kunnen gebruiken (daaraan werk ik al).

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

    We komen in de shell terecht, waar we meteen kunnen beginnen met het opstarten van kindcontainers.

  2. We starten MySQL:

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

  3. We verbinden met de database zoals we lokaal zouden doen. We zorgen ervoor dat alles werkt.

  4. We starten de tweede container:

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

    Houd er rekening mee dat de poortmapping hier zal zijn 8080:8080, omdat we poort 80 van de host al naar de bovenliggende container op poort 8080 hebben gemapped.

  5. We gaan naar localhost in de browser en controleren of de server "Hello World!" antwoordt.

In mijn geval was het experiment met geneste Docker-containers behoorlijk positief en ik zal het project verder ontwikkelen en gebruiken voor staging. Ik denk dat dit een veel lichtere oplossing is dan Kubernetes en Jenkins X. Maar dat is mijn subjektieve mening.

Ik denk dat dit het voor vandaag is. In het volgende artikel zal ik dieper ingaan op de experimenten met het recursief starten van Docker in Docker en het in de diepte mounten van directories binnen geneste containers.

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

Edit1 Ik heb de fouten gecorrigeerd en de focus gelegd op 2 video's.

Bron: habr.com

Koop betrouwbare webhosting met bescherming tegen DDoS, VPS VDS servers šŸ”„ Koop betrouwbare webhosting met bescherming tegen DDoS, VPS VDS servers | ProHoster