Hvordan jeg kjørte Docker inne i Docker og hva som kom ut av det

Hei alle sammen! I hans forrige artikkel, lovet jeg å snakke om å kjøre Docker i Docker og de praktiske aspektene ved å bruke denne leksjonen. Det er på tide å holde løftet ditt. En erfaren devopser vil sannsynligvis innvende at de som trenger Docker inne i Docker ganske enkelt videresender Docker daemon-socket fra verten til containeren og dette vil være nok i 99% av tilfellene. Men ikke skynd deg å kaste informasjonskapsler på meg, for vi vil snakke om å faktisk kjøre Docker inne i Docker. Denne løsningen har mange mulige bruksområder og denne artikkelen handler om en av dem, så len deg tilbake og rett ut armene foran deg.

Hvordan jeg kjørte Docker inne i Docker og hva som kom ut av det

begynner

Det hele startet en regntung septemberkveld da jeg vasket maskinen jeg leide for $5 på Digital Ocean, som ble frosset på grunn av det faktum at Docker hadde fylt alle 24 gigabyte med tilgjengelig diskplass med bildene og beholderne. Ironien var at alle disse bildene og beholderne var forbigående og var nødvendige bare for å teste ytelsen til applikasjonen min hver gang en ny versjon av et bibliotek eller rammeverk ble utgitt. Jeg prøvde å skrive shell-skript og sette opp en cron-plan for å rydde opp i søppel, men det hjalp ikke: hver gang endte det uunngåelig med at serverens diskplass ble spist opp og serveren hang (i beste fall). På et tidspunkt kom jeg over en artikkel om hvordan man kjører Jenkins i en beholder og hvordan den kan opprette og slette byggerørledninger gjennom en docker-demon-socket videresendt til den. Jeg likte ideen, men jeg bestemte meg for å gå videre og prøve å eksperimentere med å kjøre Docker direkte i Docker. På det tidspunktet virket det for meg som en helt logisk løsning å laste ned Docker-bilder og lage containere for alle applikasjonene jeg trengte for å teste inne i en annen container (la oss kalle det en staging-container). Tanken var å starte en staging container med flagget -rm, som automatisk sletter hele containeren og alt innholdet når den stoppes. Jeg fiklet med Docker-bildet fra Docker selv (https://hub.docker.com/_/docker), men det viste seg å være for tungvint og jeg klarte aldri å få det til å fungere slik jeg trengte det, og jeg ville gå hele veien selv.

Øve på. Kjegler

Jeg satte meg for å få beholderen til å fungere slik jeg trengte og fortsatte eksperimentene mine, noe som resulterte i et utall av knopper. Resultatet av min selvtortur var følgende algoritme:

  1. Vi lanserer Docker-beholderen i interaktiv modus.

    docker run --privileged -it docker:18.09.6

    Vær oppmerksom på versjonen av beholderen, gå til høyre eller venstre og DinD blir til et gresskar. Faktisk går ting i stykker ganske ofte når en ny versjon slippes.
    Vi må umiddelbart inn i skallet.

  2. Vi prøver å finne ut hvilke containere som kjører (Svar: ingen), men la oss kjøre kommandoen likevel:

    docker ps

    Du vil bli litt overrasket, men det viser seg at Docker-demonen ikke en gang kjø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. La oss kjøre det selv:

    dockerd &

    Nok 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-pakkene (alt er mer behagelig å jobbe i bash enn i sh):

    apk add --no-cache iptables bash

  5. La oss starte bash. Endelig er vi tilbake i det vanlige skallet

  6. La oss prøve å starte Docker igjen:

    dockerd &

    Vi bør se et langt ark med logger som 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. Trykk enter. Vi er tilbake i bash.

Fra nå av kan vi prøve å lansere andre containere inne i Docker-containeren vår, men hva om vi vil starte en annen Docker-container inne i Docker-containeren eller noe går galt og containeren krasjer? Start på nytt.

Egen DinD-beholder og nye eksperimenter

Hvordan jeg kjørte Docker inne i Docker og hva som kom ut av det
For å unngå å gjenta trinnene ovenfor om og om igjen, laget jeg min egen DinD-beholder:

https://github.com/alekslitvinenk/dind

Den fungerende DinD-løsningen ga meg muligheten til å kjøre Docker inne i Docker rekursivt og gjøre mer eventyrlige eksperimenter.
Jeg skal beskrive et slikt (vellykket) eksperiment med å kjøre MySQL og Nodejs nå.
De mest utålmodige kan se hvordan det var her

Så, la oss starte:

  1. Vi lanserer DinD i interaktiv modus. I denne versjonen av DinD må vi manuelt kartlegge alle portene som våre underordnede containere kan bruke (jeg jobber allerede med dette)

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

    Vi kommer inn i bashen, hvorfra vi umiddelbart kan begynne å lansere barnecontainere.

  2. Start MySQL:

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

  3. Vi kobler til databasen på samme måte som vi ville koblet til den lokalt. La oss sørge for at alt fungerer.

  4. Start den andre beholderen:

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

    Vær oppmerksom på at portkartleggingen vil være nøyaktig 8080:8080, siden vi allerede har kartlagt port 80 fra verten til den overordnede containeren til port 8080.

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

I mitt tilfelle viste eksperimentet med nestede Docker-beholdere seg å være ganske positivt, og jeg vil fortsette å utvikle prosjektet og bruke det til iscenesettelse. Det virker for meg som om dette er en mye lettere løsning enn Kubernetes og Jenkins X. Men dette er min subjektive mening.

Jeg tror det var alt for dagens artikkel. I den neste artikkelen vil jeg beskrive mer detaljert eksperimenter med å kjøre Docker rekursivt i Docker og montere kataloger dypt inn i nestede beholdere.

PS Hvis du synes dette prosjektet er nyttig, vennligst gi det en stjerne på GitHub, fortell det og fortell det til vennene dine.

Edit1 Rettet feil, fokusert på 2 videoer

Kilde: www.habr.com

Legg til en kommentar