Dag Allemaal! In zijn
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 (
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:
-
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. -
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
-
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
-
Installeer de iptables en bash-pakketten (alles is prettiger om in bash te werken dan in sh):
apk add --no-cache iptables bash
-
Laten we bash lanceren. Eindelijk zitten we weer in de gebruikelijke schelp
-
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
-
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
Om te voorkomen dat bovenstaande stappen steeds opnieuw worden herhaald, heb ik mijn eigen DinD-container gemaakt:
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:
-
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.
-
MySQL starten:
docker run --name mysql -e MYSQL_ROOT_PASSWORD=strongpassword -d -p 3306:3306 mysql
-
We maken verbinding met de database op dezelfde manier als we er lokaal verbinding mee zouden maken. Laten we ervoor zorgen dat alles werkt.
-
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.
-
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