Hvordan jeg kørte Docker inde i Docker, og hvad der kom ud af det

Hej alle! I hans forrige artikel, jeg lovede at tale om at køre Docker i Docker og de praktiske aspekter ved at bruge denne lektion. Det er tid til at holde dit løfte. En erfaren devopser vil sandsynligvis indvende, at de, der har brug for Docker inde i Docker, blot sender Docker-dæmon-socket fra værten ind i containeren, og dette vil være nok i 99% af tilfældene. Men skynd dig ikke at smide cookies efter mig, for vi vil tale om faktisk at køre Docker inde i Docker. Denne løsning har mange anvendelsesmuligheder, og denne artikel handler om en af ​​dem, så læn dig tilbage og ret armene foran dig.

Hvordan jeg kørte Docker inde i Docker, og hvad der kom ud af det

begynder

Det hele startede en regnfuld septemberaften, da jeg rensede den maskine, jeg lejede for $5 på Digital Ocean, som var frosset på grund af det faktum, at Docker havde fyldt alle 24 gigabyte ledig diskplads med sine billeder og containere. Det ironiske var, at alle disse billeder og beholdere var forbigående og kun var nødvendige for at teste min applikations ydeevne, hver gang en ny version af et bibliotek eller en ramme blev frigivet. Jeg prøvede at skrive shell-scripts og oprette en cron-tidsplan for at rydde op i skrald, men det hjalp ikke: hver gang endte det uundgåeligt med, at min servers diskplads blev spist op, og serveren hang (i bedste fald). På et tidspunkt stødte jeg på en artikel om, hvordan man kører Jenkins i en container, og hvordan den kan oprette og slette build-pipelines gennem en docker-dæmon-socket, der sendes ind i den. Jeg kunne godt lide ideen, men jeg besluttede at gå videre og prøve at eksperimentere med at køre Docker direkte inde i Docker. På det tidspunkt forekom det mig at være en fuldstændig logisk løsning at downloade Docker-billeder og oprette containere til alle de applikationer, jeg havde brug for til at teste inde i en anden container (lad os kalde det en staging-container). Ideen var at starte en staging container med flaget -rm, som automatisk sletter hele containeren og alt dens indhold, når den stoppes. Jeg pillede med Docker-billedet fra Docker selv (https://hub.docker.com/_/docker), men det viste sig at være for besværligt, og det lykkedes mig aldrig at få det til at fungere, som jeg havde brug for det, og jeg ville selv gå hele vejen.

Øve sig. Kegler

Jeg satte mig for at få beholderen til at fungere som jeg havde brug for og fortsatte mine eksperimenter, hvilket resulterede i et utal af knopper. Resultatet af min selvtortur var følgende algoritme:

  1. Vi starter Docker-beholderen i interaktiv tilstand.

    docker run --privileged -it docker:18.09.6

    Vær opmærksom på versionen af ​​beholderen, gå til højre eller venstre og din DinD bliver til et græskar. Faktisk går tingene i stykker ret ofte, når en ny version udgives.
    Vi skal straks ind i skallen.

  2. Vi forsøger at finde ud af, hvilke containere der kører (Svar: ingen), men lad os køre kommandoen alligevel:

    docker ps

    Du vil blive lidt overrasket, men det viser sig, at Docker-dæmonen ikke engang kører:

    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. Lad os køre det selv:

    dockerd &

    Endnu en ubehagelig overraskelse:

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

  4. Installer iptables og bash-pakkerne (alt er mere behageligt at arbejde i bash end i sh):

    apk add --no-cache iptables bash

  5. Lad os starte bash. Endelig er vi tilbage i den sædvanlige skal

  6. Lad os prøve at køre Docker igen:

    dockerd &

    Vi skulle se et langt ark med logfiler, der slutter 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. Tryk på Enter. Vi er tilbage i bash.

Fra nu af kan vi prøve at starte andre containere inde i vores Docker-container, men hvad nu hvis vi vil starte en anden Docker-container inde i vores Docker-container, eller noget går galt, og containeren går ned? Start forfra.

Egen DinD container og nye eksperimenter

Hvordan jeg kørte Docker inde i Docker, og hvad der kom ud af det
For at undgå at gentage ovenstående trin igen og igen, oprettede jeg min egen DinD-beholder:

https://github.com/alekslitvinenk/dind

Den fungerende DinD-løsning gav mig muligheden for at køre Docker inde i Docker rekursivt og lave mere eventyrlige eksperimenter.
Jeg vil beskrive et sådant (vellykket) eksperiment med at køre MySQL og Nodejs nu.
De mest utålmodige kan se, hvordan det var her

Så lad os starte:

  1. Vi lancerer DinD i interaktiv tilstand. I denne version af DinD skal vi manuelt kortlægge alle de porte, som vores underordnede containere kan bruge (jeg arbejder allerede på dette)

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

    Vi kommer ind i bashen, hvorfra vi straks kan begynde at søsætte børnecontainere.

  2. Start MySQL:

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

  3. Vi forbinder til databasen på samme måde, som vi ville forbinde til den lokalt. Lad os sikre os, at alt fungerer.

  4. Start den anden beholder:

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

    Bemærk venligst, at portkortlægningen vil være nøjagtigt 8080:8080, da vi allerede har kortlagt port 80 fra værten til den overordnede container til port 8080.

  5. Vi går til localhost i browseren, sørg for at serveren svarer "Hello World!"

I mit tilfælde viste eksperimentet med indlejrede Docker-containere sig at være ret positivt, og jeg vil fortsætte med at udvikle projektet og bruge det til iscenesættelse. Det forekommer mig, at dette er en meget mere letvægtsløsning end Kubernetes og Jenkins X. Men dette er min subjektive mening.

Jeg tror, ​​det var alt for dagens artikel. I den næste artikel vil jeg beskrive mere detaljeret eksperimenter med at køre Docker rekursivt i Docker og montere mapper dybt i indlejrede containere.

PS Hvis du finder dette projekt nyttigt, så giv det en stjerne på GitHub, forkast det og fortæl det til dine venner.

Edit1 Rettet fejl, fokuseret på 2 videoer

Kilde: www.habr.com

Tilføj en kommentar