Prieš naudodami „Docker-in-Docker“, skirtą CI arba bandomajai aplinkai, gerai pagalvokite

Prieš naudodami „Docker-in-Docker“, skirtą CI arba bandomajai aplinkai, gerai pagalvokite

„Docker-in-Docker“ yra virtualizuota „Docker“ demono aplinka, veikianti pačiame konteineryje, kad būtų galima kurti konteinerio vaizdus. Pagrindinis „Docker-in-Docker“ kūrimo tikslas buvo padėti sukurti patį „Docker“. Daugelis žmonių jį naudoja Jenkins CI paleisti. Iš pradžių tai atrodo normalu, bet tada iškyla problemų, kurių galima išvengti įdiegus Docker į Jenkins CI konteinerį. Šiame straipsnyje aprašoma, kaip tai padaryti. Jei jus domina galutinis sprendimas be detalių, tiesiog perskaitykite paskutinę straipsnio dalį „Problemos sprendimas“.

Prieš naudodami „Docker-in-Docker“, skirtą CI arba bandomajai aplinkai, gerai pagalvokite

Docker-in-Docker: „Gerai“

Daugiau nei prieš dvejus metus įsijungiau į Docker vėliava – privilegijuotas ir rašė pirmoji dind versija. Tikslas buvo padėti pagrindinei komandai greičiau vystyti „Docker“. Prieš „Docker-in-Docker“ tipiškas kūrimo ciklas atrodė taip:

  • hackity hack;
  • statyti;
  • veikiančio Docker demono sustabdymas;
  • naujo Docker demono paleidimas;
  • bandymai;
  • pakartokite ciklą.

Jei norėjote padaryti gražų, atkuriamą komplektą (ty konteineryje), tada jis tapo sudėtingesnis:

  • hackity hack;
  • įsitikinkite, kad veikia veikianti Docker versija;
  • sukurti naują Docker su senu Docker;
  • sustabdyti Docker demoną;
  • paleisti naują Docker demoną;
  • bandymas;
  • sustabdyti naują Docker demoną;
  • kartoti.

Atsiradus Docker-in-Docker, procesas tapo paprastesnis:

  • hackity hack;
  • surinkimas + paleidimas vienu etapu;
  • pakartokite ciklą.

Ar ne daug geriau tokiu būdu?

Prieš naudodami „Docker-in-Docker“, skirtą CI arba bandomajai aplinkai, gerai pagalvokite

Docker-in-Docker: „Blogas“

Tačiau, priešingai nei manoma, Docker-in-Docker nėra 100% žvaigždės, poniai ir vienaragiai. Turiu omenyje tai, kad yra keletas problemų, kurias kūrėjas turi žinoti.

Vienas iš jų yra susijęs su LSM („Linux“ saugos moduliais), tokiais kaip „AppArmor“ ir „SELinux“: paleisdamas konteinerį „vidinis dokeris“ gali bandyti pritaikyti saugos profilius, kurie prieštaraus arba supainios „išorinį dokerį“. Tai yra sunkiausiai išsprendžiama problema, kai bandoma sujungti pirminį privilegijuotosios vėliavos įgyvendinimą. Mano pakeitimai veikė ir visi testai buvo perduoti mano Debian mašinai ir Ubuntu bandomiesiems VM, bet jie suduždavo ir sudegdavo Michaelo Crosby kompiuteryje (jis turėjo Fedora, kaip aš prisimenu). Neprisimenu tikslios problemos priežasties, bet tai galėjo būti todėl, kad Mike'as yra išmintingas vaikinas, dirbantis su SELINUX=enforce (naudojau AppArmor), o mano pakeitimuose nebuvo atsižvelgta į SELinux profilius.

Docker-in-Dokeris: „Blogis“

Antroji problema yra su „Docker“ saugojimo tvarkyklėmis. Kai paleidžiate „Docker-in-Docker“, išorinis „Docker“ veikia ant įprastos failų sistemos (EXT4, BTRFS ar bet kokios jūsų turimos), o vidinis „Docker“ veikia ant kopijavimo rašant sistemą (AUFS, BTRFS, įrenginių žemėlapių sudarytojas). ir tt). , priklausomai nuo to, kas sukonfigūruota naudoti išorinį Docker). Taip sukuriama daug derinių, kurie neveiks. Pavyzdžiui, negalėsite paleisti AUFS kartu su AUFS.

Jei BTRFS paleisite ant BTRFS, iš pradžių ji turėtų veikti, bet kai yra įdėtų antrinių tomų, nepavyks ištrinti pirminio antrinio tomo. „Device Mapper“ modulis neturi vardų erdvės, todėl jei keli „Docker“ egzemplioriai paleidžia jį tame pačiame įrenginyje, jie visi galės matyti (ir paveikti) vaizdus vienas kitam ir konteinerio atsarginių kopijų įrenginiuose. Tai yra blogai.

Yra būdų, kaip išspręsti daugelį šių problemų. Pavyzdžiui, jei norite naudoti AUFS vidiniame Docker, tiesiog pasukite aplanką /var/lib/docker į tomą ir viskas bus gerai. „Docker“ pridėjo kai kurias bazines vardų sritis prie „Device Mapper“ tikslinių pavadinimų, kad, jei tame pačiame įrenginyje vykdomi keli „Docker“ skambučiai, jie vienas kito neveiktų.

Tačiau toks nustatymas nėra visai paprastas, kaip matyti iš šių straipsniai „Dind“ saugykloje „GitHub“.

Docker-in-Docker: tai blogėja

Ką apie kūrimo talpyklą? Tai taip pat gali būti gana sunku. Žmonės dažnai manęs klausia: „Jei aš naudoju „Docker-in-Docker“, kaip galiu naudoti savo pagrindiniame kompiuteryje esančius vaizdus, ​​o ne viską grąžinti į savo vidinį „Docker“?

Kai kurie iniciatyvūs žmonės bandė susieti /var/lib/docker iš pagrindinio kompiuterio su Docker-in-Docker konteineriu. Kartais jie bendrina /var/lib/docker su keliais konteineriais.

Prieš naudodami „Docker-in-Docker“, skirtą CI arba bandomajai aplinkai, gerai pagalvokite
Ar norite sugadinti savo duomenis? Nes būtent tai sugadins jūsų duomenis!

„Docker“ demonas buvo aiškiai sukurtas taip, kad turėtų išskirtinę prieigą prie /var/lib/docker. Niekas kitas neturėtų „liesti, kišti ar duoti“ jokių šiame aplanke esančių „Docker“ failų.

Kodėl taip yra? Nes tai yra vienos iš sunkiausių pamokų, išmoktų kuriant dotCloud, rezultatas. „DotCloud“ konteinerio variklis veikė, kai keli procesai vienu metu pasiekia /var/lib/dotcloud. Gudrios gudrybės, tokios kaip atominių failų pakeitimas (vietoj redagavimo vietoje), kodo papildymas patariamaisiais ir privalomais užraktais ir kiti eksperimentai su saugiomis sistemomis, tokiomis kaip SQLite ir BDB, ne visada pasiteisino. Kai perprojektavome savo konteinerių variklį, kuris galiausiai tapo Docker, vienas iš pagrindinių projektavimo sprendimų buvo sujungti visas konteinerių operacijas vienu demonu, kad būtų panaikintos visos vienalaikiškumo nesąmonės.

Nesupraskite manęs neteisingai: visiškai įmanoma sukurti kažką gero, patikimo ir greito, naudojant kelis procesus ir modernią lygiagrečią valdymą. Tačiau manome, kad naudojant „Docker“ kaip vienintelį grotuvą kodą rašyti ir prižiūrėti yra paprasčiau ir lengviau.

Tai reiškia, kad jei bendrinsite /var/lib/docker katalogą tarp kelių Docker egzempliorių, turėsite problemų. Žinoma, tai gali padėti, ypač ankstyvosiose bandymų stadijose. „Klausyk, mama, aš galiu paleisti ubuntu kaip dokeris! Tačiau pabandykite ką nors sudėtingesnio, pavyzdžiui, ištraukite tą patį vaizdą iš dviejų skirtingų atvejų, ir pamatysite, kad pasaulis sudegs.

Tai reiškia, kad jei jūsų CI sistema atlieka kūrimą ir atkūrimą, kiekvieną kartą iš naujo paleisdami Docker-in-Docker konteinerį, rizikuojate numesti branduolinį ginklą į jo talpyklą. Tai visai nepuiku!

Sprendimas

Ženkime žingsnį atgal. Ar jums tikrai reikia „Docker in-Docker“, ar tiesiog norite turėti galimybę paleisti „Docker“ ir kurti bei paleisti konteinerius ir vaizdus iš savo CI sistemos, kai pati CI sistema yra konteineryje?

Lažinuosi, kad dauguma žmonių nori pastarojo varianto, o tai reiškia, kad jie nori, kad tokia CI sistema kaip Jenkins galėtų paleisti konteinerius. Lengviausias būdas tai padaryti yra tiesiog įkišti Docker lizdą į savo CI konteinerį ir susieti jį su -v vėliava.

Paprasčiau tariant, kai paleidžiate CI konteinerį (Jenkins ar kitą), užuot ką nors įsilaužę kartu su Docker-in-Docker, pradėkite jį nuo eilutės:

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

Dabar šis konteineris turės prieigą prie „Docker“ lizdo, todėl galės paleisti konteinerius. Išskyrus tai, kad užuot paleidę „vaikų“ sudėtinius rodinius, jis paleis „brolius“ konteinerius.

Išbandykite tai naudodami oficialų „Docker“ vaizdą (kuriame yra „Docker“ dvejetainis failas):

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

Tai atrodo ir veikia kaip „Docker-in-Docker“, bet tai nėra „Docker-in-Docker“: kai šis konteineris sukuria papildomus konteinerius, jie bus sukurti aukščiausio lygio „Docker“. Nepatirsite įdėjimo šalutinio poveikio, o surinkimo talpykla bus bendrinama keliais skambučiais.

Pastaba: Ankstesnėse šio straipsnio versijose buvo rekomenduojama susieti Docker dvejetainį failą iš pagrindinio kompiuterio su konteineriu. Dabar tai tapo nepatikima, nes „Docker“ variklis nebeapima statinių ar beveik statinių bibliotekų.

Taigi, jei norite naudoti „Docker“ iš Jenkins CI, turite 2 parinktis:
„Docker“ CLI įdiegimas naudojant pagrindinę vaizdų pakavimo sistemą (t. y. jei jūsų vaizdas pagrįstas „Debian“, naudokite .deb paketus), naudojant „Docker“ API.

Kai kurie skelbimai 🙂

Dėkojame, kad likote su mumis. Ar jums patinka mūsų straipsniai? Norite pamatyti įdomesnio turinio? Palaikykite mus pateikdami užsakymą ar rekomenduodami draugams, debesies VPS kūrėjams nuo 4.99 USD, unikalus pradinio lygio serverių analogas, kurį mes sugalvojome jums: Visa tiesa apie VPS (KVM) E5-2697 v3 (6 branduoliai) 10GB DDR4 480GB SSD 1Gbps nuo 19$ arba kaip dalintis serveriu? (galima su RAID1 ir RAID10, iki 24 branduolių ir iki 40 GB DDR4).

„Dell R730xd“ 2 kartus pigiau „Equinix Tier IV“ duomenų centre Amsterdame? Tik čia 2 x Intel TetraDeca-Core Xeon 2x E5-2697v3 2.6GHz 14C 64GB DDR4 4x960GB SSD 1Gbps 100 televizoriai nuo 199 USD Olandijoje! „Dell R420“ – 2 x E5-2430 2.2 GHz 6C 128 GB DDR3 2 x 960 GB SSD 1 Gbps 100 TB – nuo ​​99 USD! Skaityti apie Kaip sukurti infrastruktūros korp. klasę naudojant Dell R730xd E5-2650 v4 serverius, kurių vertė 9000 eurų už centą?

Šaltinis: www.habr.com

Добавить комментарий