Dink mooi voordat jy Docker-in-Docker vir CI of toetsomgewing gebruik

Dink mooi voordat jy Docker-in-Docker vir CI of toetsomgewing gebruik

Docker-in-Docker is 'n gevirtualiseerde Docker daemon-omgewing wat binne die houer self loop om houerbeelde te bou. Die hoofdoel van die skep van Docker-in-Docker was om Docker self te help ontwikkel. Baie mense gebruik dit om Jenkins CI te bestuur. Dit lyk aanvanklik normaal, maar dan ontstaan ​​probleme wat vermy kan word deur Docker in 'n Jenkins CI-houer te installeer. Hierdie artikel vertel jou hoe om dit te doen. As jy belangstel in die finale oplossing sonder besonderhede, lees net die laaste afdeling van die artikel, "Die oplossing van die probleem."

Dink mooi voordat jy Docker-in-Docker vir CI of toetsomgewing gebruik

Docker-in-Docker: "Goed"

Meer as twee jaar gelede het ek in Docker gesit vlag –bevoorreg en geskryf eerste weergawe van dind. Die doel was om die kernspan te help om Docker vinniger te ontwikkel. Voor Docker-in-Docker het die tipiese ontwikkelingsiklus soos volg gelyk:

  • hackity hack;
  • bou;
  • stop 'n lopende Docker-demoon;
  • die bekendstelling van 'n nuwe Docker-demon;
  • toets;
  • herhaal die siklus.

As jy 'n pragtige, reproduceerbare samestelling (dit wil sê in 'n houer) wou maak, dan het dit meer ingewikkeld geword:

  • hackity hack;
  • maak seker dat 'n werkende weergawe van Docker loop;
  • bou nuwe Docker met ou Docker;
  • stop Docker daemon;
  • begin 'n nuwe Docker-demon;
  • toets;
  • stop nuwe Docker daemon;
  • herhaal.

Met die koms van Docker-in-Docker het die proses eenvoudiger geword:

  • hackity hack;
  • samestelling + lansering in een stadium;
  • herhaal die siklus.

Is dit nie baie beter op hierdie manier nie?

Dink mooi voordat jy Docker-in-Docker vir CI of toetsomgewing gebruik

Docker-in-Docker: "Sleg"

In teenstelling met die algemene opvatting, is Docker-in-Docker egter nie 100% sterre, ponies en eenhorings nie. Wat ek bedoel is dat daar verskeie kwessies is waarvan 'n ontwikkelaar bewus moet wees.

Een daarvan het betrekking op LSM'e (Linux-sekuriteitsmodules) soos AppArmor en SELinux: wanneer 'n houer bestuur word, kan die "interne Docker" probeer om sekuriteitsprofiele toe te pas wat die "eksterne Docker" sal konflik of verwar. Dit is die moeilikste probleem om op te los wanneer jy probeer om die oorspronklike implementering van die –bevoorregte vlag saam te voeg. My veranderinge het gewerk en alle toetse sou op my Debian-masjien en Ubuntu-toets-VM's slaag, maar hulle het op Michael Crosby se masjien neergestort en gebrand (hy het Fedora gehad soos ek onthou). Ek kan nie die presiese oorsaak van die probleem onthou nie, maar dit was dalk omdat Mike 'n wyse ou is wat met SELINUX=enforce werk (ek het AppArmor gebruik) en my veranderinge het nie SELinux-profiele in ag geneem nie.

Docker-in-Docker: "Evil"

Die tweede probleem is met Docker-bergingsbestuurders. Wanneer jy Docker-in-Docker hardloop, loop eksterne Docker bo-op 'n gewone lêerstelsel (EXT4, BTRFS, of wat jy ook al het) en interne Docker loop bo-op 'n kopieer-op-skryf-stelsel (AUFS, BTRFS, Device Mapper) , ens.). , afhangende van wat opgestel is om eksterne Docker te gebruik). Dit skep baie kombinasies wat nie sal werk nie. Byvoorbeeld, jy sal nie AUFS bo-op AUFS kan laat loop nie.

As jy BTRFS bo-op BTRFS hardloop, behoort dit eers te werk, maar sodra daar geneste subvolumes is, sal die uitvee van die ouersubvolume misluk. Die Device Mapper-module het geen naamspasie nie, so as verskeie Docker-instansies dit op dieselfde masjien laat loop, sal hulle almal die beelde op mekaar en op die houer-rugsteuntoestelle kan sien (en beïnvloed). Dit is sleg.

Daar is oplossings om baie van hierdie probleme op te los. Byvoorbeeld, as u AUFS in interne Docker wil gebruik, verander net die /var/lib/docker-lêergids in 'n volume en dit sal goed wees. Docker het 'n paar basisnaamruimtes by Device Mapper-teikenname gevoeg sodat as verskeie Docker-oproepe op dieselfde masjien loop, hulle nie op mekaar sal trap nie.

Sulke opstelling is egter glad nie eenvoudig nie, soos hieruit gesien kan word artikels in die dind-bewaarplek op GitHub.

Docker-in-Docker: Dit word erger

Wat van die boukas? Dit kan ook nogal moeilik wees. Mense vra my dikwels "as ek Docker-in-Docker gebruik, hoe kan ek beelde gebruik wat op my gasheer gehuisves word in plaas daarvan om alles terug te trek na my interne Docker"?

Sommige ondernemende mense het probeer om /var/lib/docker van die gasheer aan 'n Docker-in-Docker-houer te bind. Soms deel hulle /var/lib/docker met verskeie houers.

Dink mooi voordat jy Docker-in-Docker vir CI of toetsomgewing gebruik
Wil jy jou data korrupteer? Want dit is presies wat jou data sal beskadig!

Die Docker-demoon is duidelik ontwerp om eksklusiewe toegang tot /var/lib/docker te hê. Niks anders moet enige Docker-lêers wat in hierdie vouer geleë is "aanraak, steek of prod" nie.

Hoekom is dit so? Omdat dit die resultaat is van een van die moeilikste lesse wat geleer is tydens die ontwikkeling van dotCloud. Die dotCloud-houer-enjin het gehardloop deur verskeie prosesse te hê wat gelyktydig toegang tot /var/lib/dotcloud het. Slinkse truuks soos atoomlêervervanging (in plaas van in-plek redigering), deurdringende kode met raadgewende en verpligte slotte, en ander eksperimente met veilige stelsels soos SQLite en BDB het nie altyd gewerk nie. Toe ons ons houer-enjin herontwerp het, wat uiteindelik Docker geword het, was een van die groot ontwerpbesluite om alle houerbedrywighede onder 'n enkele daemoon te konsolideer om weg te doen met al die gelyktydige nonsens.

Moet my nie verkeerd verstaan ​​nie: dit is heeltemal moontlik om iets goed, betroubaar en vinnig te maak wat veelvuldige prosesse en moderne parallelle beheer behels. Maar ons dink dit is eenvoudiger en makliker om kode te skryf en in stand te hou met Docker as die enigste speler.

Dit beteken dat as u die /var/lib/docker-gids tussen verskeie Docker-gevalle deel, u probleme sal hê. Natuurlik kan dit werk, veral in die vroeë stadiums van toetsing. "Luister, Ma, ek kan ubuntu as 'n dokwerker bestuur!" Maar probeer iets meer kompleks, soos om dieselfde beeld uit twee verskillende gevalle te trek, en jy sal sien hoe die wêreld brand.

Dit beteken dat as jou CI-stelsel bouwerk en herbou uitvoer, elke keer as jy jou Docker-in-Docker-houer herbegin, jy die risiko loop om 'n nuke in sy kas te laat val. Dit is glad nie cool nie!

Die oplossing

Kom ons gee 'n tree terug. Het jy regtig Docker-in-Docker nodig of wil jy net Docker kan laat loop en houers en beelde vanaf jou CI-stelsel bou en laat loop terwyl daardie CI-stelsel self in 'n houer is?

Ek wed dat die meeste mense laasgenoemde opsie wil hê, wat beteken dat hulle 'n CI-stelsel soos Jenkins wil hê om houers te laat loop. En die maklikste manier om dit te doen, is om eenvoudig 'n Docker-sok in jou CI-houer te plaas en dit met die -v-vlag te assosieer.

Eenvoudig gestel, wanneer jy jou CI-houer (Jenkins of ander) bestuur, in plaas daarvan om iets saam met Docker-in-Docker te hack, begin dit met die lyn:

docker run -v /var/run/docker.sock:/var/run/docker.sock ...

Hierdie houer sal nou toegang tot die Docker-sok hê en dus houers kan laat loop. Behalwe dat in plaas daarvan om "kind"-houers te laat loop, dit "broer-houers" sal begin.

Probeer dit met die amptelike docker-beeld (wat die Docker-binêre bevat):

docker run -v /var/run/docker.sock:/var/run/docker.sock 
           -ti docker

Dit lyk en werk soos Docker-in-Docker, maar dit is nie Docker-in-Docker nie: wanneer hierdie houer bykomende houers skep, sal hulle in die topvlak Docker geskep word. Jy sal nie die newe-effekte van nes ervaar nie en die samestellingkas sal oor verskeie oproepe gedeel word.

Let wel: Vorige weergawes van hierdie artikel het aangeraai om die Docker-binêre van die gasheer na die houer te koppel. Dit het nou onbetroubaar geword aangesien die Docker-enjin nie meer statiese of byna statiese biblioteke dek nie.

Dus, as u Docker van Jenkins CI wil gebruik, het u 2 opsies:
die installering van die Docker CLI met behulp van die basiese beeldverpakkingstelsel (d.w.s. as jou beeld op Debian gebaseer is, gebruik .deb-pakkette), met behulp van die Docker API.

Sommige advertensies 🙂

Dankie dat jy by ons gebly het. Hou jy van ons artikels? Wil jy meer interessante inhoud sien? Ondersteun ons deur 'n bestelling te plaas of by vriende aan te beveel, wolk VPS vir ontwikkelaars vanaf $4.99, 'n unieke analoog van intreevlakbedieners, wat deur ons vir jou uitgevind is: Die hele waarheid oor VPS (KVM) E5-2697 v3 (6 Cores) 10GB DDR4 480GB SSD 1Gbps vanaf $19 of hoe om 'n bediener te deel? (beskikbaar met RAID1 en RAID10, tot 24 kerne en tot 40 GB DDR4).

Dell R730xd 2x goedkoper in Equinix Tier IV-datasentrum in Amsterdam? Net hier 2 x Intel TetraDeca-Core Xeon 2x E5-2697v3 2.6GHz 14C 64GB DDR4 4x960GB SSD 1Gbps 100 TV vanaf $199 in Nederland! Dell R420 - 2x E5-2430 2.2Ghz 6C 128GB DDR3 2x960GB SSD 1Gbps 100TB - vanaf $99! Lees van Hoe om infrastruktuur korp. klas met die gebruik van Dell R730xd E5-2650 v4-bedieners ter waarde van 9000 XNUMX euro vir 'n sent?

Bron: will.com

Voeg 'n opmerking