Tink foarsichtich foardat jo Docker-in-Docker brûke foar CI as testomjouwing

Tink foarsichtich foardat jo Docker-in-Docker brûke foar CI as testomjouwing

Docker-in-Docker is in virtualisearre Docker-daemon-omjouwing dy't binnen de kontener sels rint om kontenerôfbyldings te bouwen. It haaddoel fan it meitsjen fan Docker-in-Docker wie om Docker sels te ûntwikkeljen. In protte minsken brûke it om Jenkins CI út te fieren. Dit liket earst normaal, mar dan ûntsteane problemen dy't kinne wurde foarkommen troch Docker te ynstallearjen yn in Jenkins CI-kontener. Dit artikel fertelt jo hoe't jo dit dwaan. As jo ​​​​ynteressearre binne yn 'e definitive oplossing sûnder details, lês gewoan de lêste seksje fan it artikel, "It probleem oplosse."

Tink foarsichtich foardat jo Docker-in-Docker brûke foar CI as testomjouwing

Docker-in-Docker: "Goed"

Mear dan twa jier lyn haw ik yn Docker set flagge - befoarrjochte en skreau earste ferzje fan dind. It doel wie om it kearnteam te helpen Docker rapper te ûntwikkeljen. Foar Docker-in-Docker seach de typyske ûntwikkelingssyklus der sa út:

  • hackity hack;
  • bouwe;
  • it stopjen fan in rinnende Docker-daemon;
  • in nije Docker-daemon lansearje;
  • testen;
  • werhelje de syklus.

As jo ​​​​in prachtige, reprodusearbere gearstalling wolle meitsje (dat is, yn in kontener), dan waard it yngewikkelder:

  • hackity hack;
  • soargje derfoar dat in wurkferzje fan Docker rint;
  • bouwe nije Docker mei âlde Docker;
  • stop Docker daemon;
  • begjinne in nije Docker-daemon;
  • toets;
  • stopje nije Docker-daemon;
  • werhelje.

Mei de komst fan Docker-in-Docker is it proses ienfâldiger wurden:

  • hackity hack;
  • gearstalling + lansearring yn ien etappe;
  • werhelje de syklus.

Is it net folle better op dizze manier?

Tink foarsichtich foardat jo Docker-in-Docker brûke foar CI as testomjouwing

Docker-in-Docker: "Min"

Yn tsjinstelling ta populêr leauwen is Docker-in-Docker lykwols gjin 100% stjerren, pony's en ienhoarnen. Wat ik bedoel is dat d'r ferskate problemen binne wêrfan in ûntwikkelder bewust wêze moat.

Ien fan har giet it om LSM's (Linux-befeiligingsmodules) lykas AppArmor en SELinux: by it útfieren fan in kontener kin de "ynterne Docker" besykje befeiligingsprofilen oan te passen dy't de "eksterne Docker" yn konflikt of betize sille. Dit is it dreechste probleem om op te lossen as jo besykje de oarspronklike ymplemintaasje fan 'e -privileged flagge te fusearjen. Myn wizigingen wurken en alle testen soene trochjaan op myn Debian-masine en Ubuntu-test-VM's, mar se soene crashe en ferbaarne op Michael Crosby's masine (hy hie Fedora sa't ik my herinner). Ik kin de krekte oarsaak fan it probleem net ûnthâlde, mar it kin west hawwe om't Mike in wiis man is dy't wurket mei SELINUX = hanthavenje (ik brûkte AppArmor) en myn wizigingen namen gjin rekken mei SELinux-profilen.

Docker-in-Docker: "Kwea"

It twadde probleem is mei Docker-opslachbestjoerders. As jo ​​Docker-in-Docker útfiere, rint eksterne Docker boppe op in gewoan bestânsysteem (EXT4, BTRFS, of wat jo ek hawwe) en ynterne Docker rint boppe op in kopy-op-skriuwe-systeem (AUFS, BTRFS, Device Mapper) , ensfh.). , ôfhinklik fan wat is konfigurearre om eksterne Docker te brûken). Dit soarget foar in protte kombinaasjes dy't net wurkje. Jo kinne bygelyks AUFS net boppe AUFS útfiere.

As jo ​​​​BTRFS boppe op BTRFS útfiere, soe it earst moatte wurkje, mar as d'r ienris geneste subvolumes binne, sil it wiskjen fan it âldersubvolume mislearje. De Device Mapper-module hat gjin nammeromte, dus as meardere Docker-eksimplaren it op deselde masine útfiere, sille se allegear de ôfbyldings op elkoar en op 'e kontener-backup-apparaten kinne sjen (en beynfloedzje). Dit is min.

D'r binne oplossingen om in protte fan dizze problemen op te lossen. As jo ​​​​bygelyks AUFS wolle brûke yn ynterne Docker, draai dan gewoan de map /var/lib/docker yn in folume en jo sille goed wêze. Docker hat wat basisnammeromten tafoege oan Device Mapper-doelnammen, sadat as meardere Docker-oproppen op deselde masine rinne, se net op elkoar stappe.

Sa'n opset is lykwols hielendal net ienfâldich, sa't hjirút bliken kin artikels yn it dind repository op GitHub.

Docker-in-Docker: It wurdt slimmer

Hoe sit it mei de build-cache? Dit kin ek frij lestich wêze. Minsken freegje my faaks "as ik Docker-in-Docker útfiere, hoe kin ik ôfbyldings brûke op myn host yn plak fan alles werom te lûken yn myn ynterne Docker"?

Guon ûndernimmende minsken hawwe besocht /var/lib/docker te binen fan 'e host nei in Docker-in-Docker-container. Soms diele se /var/lib/docker mei meardere konteners.

Tink foarsichtich foardat jo Docker-in-Docker brûke foar CI as testomjouwing
Wolle jo jo gegevens korrupsje? Want dit is krekt wat jo gegevens skealje sil!

De Docker-daemon wie dúdlik ûntworpen om eksklusive tagong te hawwen ta /var/lib/docker. Neat oars soe "oanreitsje, poke, of prod" alle Docker-bestannen yn dizze map.

Wêrom is dit sa? Om't dit it resultaat is fan ien fan 'e hurdste lessen leard by it ûntwikkeljen fan dotCloud. De dotCloud-kontenermotor rûn troch meardere prosessen tagelyk tagong te krijen ta /var/lib/dotcloud. Slimme trúkjes lykas atomic file replacement (ynstee fan in-place editing), peppering koade mei advisearjende en ferplichte slûzen, en oare eksperiminten mei feilige systemen lykas SQLite en BDB net altyd wurke. Doe't wy ús kontenermotor werûntwerpen, dy't úteinlik Docker waard, wie ien fan 'e grutte ûntwerpbeslissingen om alle konteneroperaasjes ûnder ien daemon te konsolidearjen om alle ûnsin te ferwiderjen.

Begryp my net ferkeard: it is folslein mooglik om wat goed, betrouber en fluch te meitsjen dat meardere prosessen en moderne parallelle kontrôle omfettet. Mar wy tinke dat it ienfâldiger en makliker is om koade te skriuwen en te ûnderhâlden mei Docker as de ienige spiler.

Dit betsjut dat as jo de map /var/lib/docker diele tusken meardere Docker-eksimplaren, sille jo problemen hawwe. Fansels kin dit wurkje, foaral yn 'e iere stadia fan testen. "Harkje, mem, ik kin ubuntu as docker útfiere!" Mar besykje wat komplekser, lykas it lûken fan deselde ôfbylding út twa ferskillende eksimplaren, en jo sille de wrâld ferbaarne sjen.

Dit betsjut dat as jo CI-systeem builds en rebuilds útfiert, elke kear as jo jo Docker-in-Docker-container opnij starte, jo it risiko in nuke yn syn cache falle. Dit is hielendal net cool!

Troubleshooting

Litte wy in stap werom dwaan. Binne jo Docker-in-Docker wirklik nedich of wolle jo gewoan Docker kinne útfiere en konteners en ôfbyldings fan jo CI-systeem bouwe en útfiere, wylst dat CI-systeem sels yn in kontener is?

Ik wedde dat de measte minsken de lêste opsje wolle, wat betsjut dat se wolle dat in CI-systeem lykas Jenkins konteners kin útfiere. En de maklikste manier om dit te dwaan is gewoan in Docker-socket yn jo CI-kontener yn te foegjen en it te assosjearjen mei de -v-flagge.

Simply set, as jo jo CI-container (Jenkins of oare) útfiere, ynstee fan wat te hacken tegearre mei Docker-in-Docker, begjin it mei de line:

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

Dizze kontener sil no tagong hawwe ta de Docker-socket en kin dêrom konteners útfiere. Utsein dat ynstee fan "bern"-konteners út te fieren, sil it "sibling"-konteners lansearje.

Besykje dit mei de offisjele docker-ôfbylding (dy't de Docker-binêre befettet):

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

It liket en wurket as Docker-in-Docker, mar it is gjin Docker-in-Docker: as dizze kontener ekstra konteners oanmakket, wurde se oanmakke yn 'e Docker op boppeste nivo. Jo sille de side-effekten fan nêsten net ûnderfine en de assemblage-cache sil wurde dield oer meardere oproppen.

Opmerking: Foarige ferzjes fan dit artikel advisearre om de Docker-binêr te keppeljen fan 'e host nei de kontener. Dit is no ûnbetrouber wurden, om't de Docker-motor net langer statyske of hast statyske bibleteken dekt.

Dus, as jo Docker fan Jenkins CI wolle brûke, hawwe jo 2 opsjes:
it ynstallearjen fan de Docker CLI mei it basisferpakkingsysteem foar ôfbyldings (dus as jo ôfbylding basearre is op Debian, brûk dan .deb-pakketten), mei de Docker API.

Guon advertinsjes 🙂

Tankewol foar it bliuwen by ús. Hâld jo fan ús artikels? Wolle jo mear ynteressante ynhâld sjen? Stypje ús troch in bestelling te pleatsen of oan te befeljen oan freonen, wolk VPS foar ûntwikkelders fan $ 4.99, in unike analoog fan servers op yngongsnivo, dy't troch ús foar jo útfûn is: De hiele wierheid oer VPS (KVM) E5-2697 v3 (6 Cores) 10GB DDR4 480GB SSD 1Gbps fan $19 of hoe te dielen in tsjinner? (beskikber mei RAID1 en RAID10, oant 24 kearnen en oant 40GB DDR4).

Dell R730xd 2 kear goedkeaper yn Equinix Tier IV data sintrum yn Amsterdam? Allinne hjir 2 x Intel TetraDeca-Core Xeon 2x E5-2697v3 2.6GHz 14C 64GB DDR4 4x960GB SSD 1Gbps 100 TV fan $199 yn Nederlân! Dell R420 - 2x E5-2430 2.2Ghz 6C 128GB DDR3 2x960GB SSD 1Gbps 100TB - fan $99! Lêze oer Hoe kinne jo Infrastructure Corp. klasse mei it brûken fan Dell R730xd E5-2650 v4 tsjinners wurdich 9000 euro foar in penny?

Boarne: www.habr.com

Add a comment