Mendoni mirë para se të përdorni Docker-in-Docker për CI ose ambientin e testimit

Mendoni mirë para se të përdorni Docker-in-Docker për CI ose ambientin e testimit

Docker-in-Docker paraqet një ambient të virtualizuar Docker-demon, i ekzekutuar brenda vetë kontejnerit për ndërtimin e imazheve të kontejnerëve. Qëllimi kryesor i krijimit të Docker-in-Docker ishte ndihma në zhvillimin e vetë Dockerit. Shumë njerëz e përdorin atë për të ekzekutuar Jenkins CI. Në fillim duket normale, por më pas shfaqen probleme që mund të shmangen duke instaluar Docker brenda kontejnerit Jenkins CI. Ky artikull shpjegon se si ta bëni këtë. Nëse jeni të interesuar për zgjidhjen përfundimtare pa detaje, thjesht lexoni seksionin e fundit të artikullit "Zgjidhja e problemit".

Mendoni mirë para se të përdorni Docker-in-Docker për CI ose ambientin e testimit

Docker-in-Docker: «I Mirë»

Më shumë se dy vjet më parë, unë përfshiva në Docker flaga -privilegjuar dhe shkrova versionin e parë dind. Qëllimi ishte që t'i ndihmoj ekipit kryesor të zhvillonte më shpejt Dockerin. Para se të ndodhte Docker-in-Docker, cikli tipik i zhvillimit ishte si më poshtë:

  • hackity hack;
  • ndĂ«rtimi (build);
  • ndalimi i Docker-demonit tĂ« ekzekutuar;
  • njoftimi i njĂ« Docker-demon tĂ« ri;
  • testimi;
  • ripĂ«rsĂ«ritja e ciklit.

Por nëse donit të bënit një ndërtim të bukur, të riprodhueshëm (pra, brenda kontejnerit), ato bëheshin më të ndërlikuara:

  • hackity hack;
  • sigurimi qĂ« versioni funksional i Docker ishte i ekzekutuar;
  • ndĂ«rtoni njĂ« Docker tĂ« ri me Dockerin e vjetĂ«r;
  • ndaloni demonin Docker;
  • nisni demonin e ri Docker;
  • testoni;
  • ndaloni demonin e ri Docker;
  • pĂ«rsĂ«ritni.

Me shfaqjen e Docker-in-Docker, procesi është bërë më i thjeshtë:

  • hackity hack;
  • ndĂ«rtimi + nisja nĂ« njĂ« hap;
  • ripĂ«rsĂ«ritja e ciklit.

A nuk është kështu shumë më mirë?

Mendoni mirë para se të përdorni Docker-in-Docker për CI ose ambientin e testimit

Docker-in-Docker: «I keqi»

Sidoqoftë, përkundër mendimit të zakonshëm, Docker-in-Docker nuk është 100% yje, ponj dhe njëhorna. Kam parasysh se ka disa probleme që zhvilluesi duhet të dijë.

NjĂ«ra prej tyre ka tĂ« bĂ«jĂ« me LSM (modulet e sigurisĂ« nĂ« Linux), si AppArmor dhe SELinux: gjatĂ« lançimit tĂ« kontejnerit, "Docker-i i brendshĂ«m" mund tĂ« pĂ«rpiqet tĂ« zbatojĂ« profile sigurie qĂ« do tĂ« krijonin konflikte ose konfuzion me "Docker-in e jashtĂ«m". Kjo ishte problemi mĂ« i komplikuar qĂ« duheshin zgjidhur kur pĂ«rpiqeshim tĂ« bashkonim implementimin origjinal tĂ« flag-ut –privileged. Ndryshimet e mia funksiononin, dhe tĂ« gjitha testet do tĂ« kalonin nĂ« makinĂ«n time Debian dhe nĂ« makinat virtuale testuese tĂ« Ubuntu, por ato do tĂ« dĂ«shtonin dhe digjeshin nĂ« makinĂ«n e Michael Crosby-t (po tĂ« kujtohem saktĂ«, ai kishte Fedora). Nuk mund ta kujtoj arsyen eksakte tĂ« problemit, por ndoshta ndodhi sepse Mike Ă«shtĂ« njĂ« njeri i mençur, i cili punon me SELINUX=enforce (unĂ« pĂ«rdora AppArmor), dhe ndryshimet e mia nuk merrnin parasysh profilet e SELinux.

Docker-in-Docker: "E keqe"

Problemi i dytë është lidhur me driverët e ruajtjes Docker. Kur ju filloni Docker-in-Docker, Docker-i jashtë punon mbi sistemin e zakonshëm të skedarëve (EXT4, BTRFS ose ndonjë tjetër që keni), ndërsa Docker-i i brendshëm punon mbi sistemin e kopjimit gjatë shkrimit (AUFS, BTRFS, Device Mapper etj., në varësi të asaj që është konfiguruar për të përdorur Docker-i i jashtëm). Kjo krijon një shumëllojshmëri kombinimesh që nuk do të funksionojnë. Për shembull, nuk mund të nisin AUFS mbi AUFS.

Nëse po përdorni BTRFS mbi BTRFS, fillimisht duhet të funksionojë, por sapo të shfaqen nënndërçarjet, nuk do të jetë e mundur të hiqet nënndërçarja prind. Moduli Device Mapper nuk ka hapësirë emrash, kështu që, nëse disa instance Docker-i e përdorin atë në një makinë, të gjitha do të mund ta shohin (dhe ndikojnë) në imazhet e njëra-tjetrës dhe në pajisjet e rezervës për konteinerët. Kjo është e keqe.

Ka janë disa përzgjidhje për të zgjidhur shumë nga këto probleme. Për shembull, nëse dëshironi të përdorni AUFS në Dockerin tuaj të brendshëm, thjesht kthejeni dosjen /var/lib/docker në një volum dhe gjithçka do të shkojë në rregull. Docker ka shtuar disa hapësira bazë të emrave në emrat e synimeve të Mapper të Pajisjeve, kështu që nëse disa thirrje Docker kryhen në të njëjtën makinë, ato nuk do të 'ngjiten' mbi njëra-tjetrën.

Megjithatë, një konfigURATION e tillë nuk është e lehtë, siç mund të shihet nga këto artikujsh në depozitën dind në GitHub.

Docker në Docker: bëhet edhe më keq

E çfarĂ« me cashin e ndĂ«rtimit? Kjo gjithashtu mund tĂ« jetĂ« mjaft e komplikuar. NjerĂ«zit shpesh mĂ« pyesin “nĂ«se po ekzekutoj Docker nĂ« Docker, si mund tĂ« pĂ«rdor imazhet qĂ« ndodhen nĂ« hostin tim, nĂ« vend qĂ« t'i sjell pĂ«rsĂ«ri tĂ« gjitha nĂ« Dockerin tim tĂ« brendshĂ«m?”

Disa njerëz sipërmarrës kanë përpiqur të lidhin /var/lib/docker nga hosti në konteinerin Docker në Docker. Ndonëse, ato shpesh ndajnë /var/lib/docker me disa konteinerë.

Mendoni mirë para se të përdorni Docker-in-Docker për CI ose ambientin e testimit
Dëshironi të dëmtosh të dhënat? Sepse kjo është pikërisht ajo që do të dëmtojë të dhënat tuaja!

Docker-dëmoni duket se është krijuar për të pasur qasje ekskluzive në /var/lib/docker. Asgjë tjetër nuk duhet "të prekë, gërmojë ose të zhyti" ndonjë skedar Docker që ndodhet në këtë dosje.

Pse është kështu? Sepse kjo është rezultat i një prej mësimeve më të vështira që kemi marrë gjatë zhvillimit të dotCloud. Mjet i konteinerëve të dotCloud ka punuar me disa procese që qasën njëkohësisht në /var/lib/dotcloud. Truket e mençura, si zëvendësimi atomik i skedave (në vend të redaktimit në vend), "spicing" e kodit me bllokime rekomanduese dhe të detyrueshme e eksperimente të tjera me sisteme të sigurta, si SQLite dhe BDB, nuk kanë funksionuar gjithmonë. Kur ne rishkruam mjetin tonë të konteinerëve, i cili përfundimisht u bë Docker, një nga vendimet kryesore të dizajnit ishte të grumbulloheshin të gjitha operacionet me konteinerët nën një demon të vetëm, për t'i dhënë fund gjithë kësaj marrëzie të aksesit njëkohësisht.

Mos ku e kuptoni gabim: është plotësisht e mundur të bëni diçka të mirë, të besueshme dhe të shpejtë, që përfshin disa procese dhe menaxhim bashkëkohor paralel. Por ne mendojmë se është më e lehtë dhe më e thjeshtë të shkruani dhe mbani kodin duke përdorur Docker si një lojtar të vetëm.

Kjo do të thotë se nëse ndihmoni një katalog /var/lib/docker ndërmjet disa instancave Docker, do të keni probleme. Sigurisht, kjo mund të funksionojë, veçanërisht në fazat e hershme të testeve. 'Dëgjo, Ma, mund ta nisim ubuntu me "docker"!' Por provo të bësh diçka më të komplikuar, për shembull, të nxjerrësh të njëjtin imazh nga dy instanca të ndryshme dhe do të shohësh si digjet bota.

Kjo do të thotë se nëse sistemi juaj CI kryen ndërtime dhe rindërtime, çdo herë që rinis një kontejner Docker-në-Docker rrezikoni të shkaktoni një shpërthim në cache të tij. Kjo nuk është aspak e këndshme!

Zgjidhja e problemit

Le të heqim një hap mbrapa. A ju nevojitet vërtet Docker-në-Docker apo thjesht dëshironi të keni mundësinë të nisim Docker, pra të ndërtoni dhe të nisni kontejnerë dhe imazhe nga sistemi juaj CI, kurse ky sistem CI vetë ndodhet brenda një kontejneri?

E sigurtë që shumicës së njerëzve u nevojitet versioni më i fundit, pra ata duan që sistemi CI, si Jenkins, të jetë në gjendje të drejtojë kontejnerët. Dhe mënyra më e thjeshtë për ta bërë këtë është të vendosni thjesht socket-in Docker në kontejnerin tuaj CI, duke e lidhur atë me flagun -v.

Thënë ndryshe, kur ekzekutoni kontejnerin tuaj CI (Jenkins ose ndonjë tjetër), në vend që të hidhni diçka duke përdorur Docker-in-Docker, filloni atë me komandën:

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

Tani ky kontejner do të ketë qasje në socket-in Docker dhe, për pasojë, do të jetë në gjendje të drejtojë kontejnerët. Përveç se, në vend të lançimit të kontejnerëve 'fëmijë', ai do të lançojë kontejnerë 'të afërt'.

Provoni këtë, duke përdorur imazhin zyrtar docker (i cili përmban skedarin binar të Docker):

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

Kjo duket dhe funksionon si Docker-in-Docker, por nuk është Docker-in-Docker: kur ky kontejner krijon kontejnerë shtesë, ata do të krijohen në Docker-in-suprem. Nuk do të përjetoni efekte anësore të thellësisë, dhe nëndërtesa do të përdorë të njëjtin cache për disa thirrje.

Shënim: versionet e mëparshme të këtij artikulli rekomandonin lidhjen e një skedari binar Docker nga hosti në kontejner. Tani kjo është bërë e pasigurt, sepse mekanizmi Docker nuk zgjerohet më mbi bibliotekat statike ose pothuajse statike.

Prandaj, nëse dëshironi të përdorni Docker nga Jenkins CI, keni 2 mundësi:
instalimi i Docker CLI duke përdorur sistemin bazë të paketave të imazhit (dmth, nëse imazhi juaj bazohet në Debian, përdorni paketat .deb), përdorimi i Docker API.

Pak reklamĂ« 🙂

Faleminderit që qëndroni me ne. Ju pëlqejnë artikujt tanë? Dëshironi të shihni më shumë materiale interesante? Na mbështetni duke bërë një porosi ose duke na rekomanduar njohurive tuaj, VPS cloud për zhvillues nga $4.99, një analog unik i serverëve entry-level, i ndërtuar për ju: E gjithë e vërteta rreth VPS (KVM) E5-2697 v3 (6 Nuclea) 10GB DDR4 480GB SSD 1Gbps nga $19 ose si ta ndajmë saktësisht serverin? (disponohen variante me RAID1 dhe RAID10, deri në 24 bërthama dhe deri në 40GB DDR4).

Dell R730xd dyfish mĂ« i lirĂ« nĂ« qendrĂ«n e tĂ« dhĂ«nave Equinix Tier IV nĂ« Amsterdam? VetĂ«m kĂ«tu 2 x Intel TetraDeca-Core Xeon 2x E5-2697v3 2.6GHz 14C 64GB DDR4 4x960GB SSD 1Gbps 100 TB nga $199 nĂ« HolandĂ«! Dell R420 — 2x E5-2430 2.2Ghz 6C 128GB DDR3 2x960GB SSD 1Gbps 100TB — nga $99! Lexoni rreth Si tĂ« ndĂ«rtosh njĂ« infrastrukturĂ« tĂ« klasĂ«s korporative me pĂ«rdorimin e serverĂ«ve Dell R730xd E5-2650 v4 me çmim prej 9000 euro pĂ«r pak para?

Burimi: habr.com

Bli njĂ« hosting tĂ« besueshĂ«m pĂ«r faqet me mbrojtje DDoS, VPS VDS serverĂ« đŸ”„ Bli njĂ« hosting tĂ« besueshĂ«m pĂ«r faqet me mbrojtje DDoS, VPS VDS serverĂ« | ProHoster