Mõelge hoolikalt enne Docker-in-Dockeri CI või testkeskkonna jaoks kasutamist

Mõelge hoolikalt enne Docker-in-Dockeri CI või testkeskkonna jaoks kasutamist

Docker-in-Docker on virtualiseeritud Dockeri deemonkeskkond, mis töötab konteineris endas konteineri kujutiste loomiseks. Docker-in-Dockeri loomise peamine eesmärk oli aidata arendada Dockerit ennast. Paljud inimesed kasutavad seda Jenkins CI käitamiseks. See tundub alguses normaalne, kuid siis tekivad probleemid, mida saab vältida, kui installite Dockeri Jenkinsi CI konteinerisse. See artikkel räägib teile, kuidas seda teha. Kui olete huvitatud lõplikust lahendusest ilma üksikasjadeta, lugege lihtsalt artikli viimast jaotist "Probleemi lahendamine".

Mõelge hoolikalt enne Docker-in-Dockeri CI või testkeskkonna jaoks kasutamist

Docker-in-Docker: "Hea"

Rohkem kui kaks aastat tagasi panin rakendusse Docker lipp – privilegeeritud ja kirjutas dindi esimene versioon. Eesmärk oli aidata põhimeeskonnal Dockerit kiiremini arendada. Enne Docker-in-Dockerit nägi tüüpiline arendustsükkel välja selline:

  • hackity hack;
  • ehitada;
  • töötava Dockeri deemoni peatamine;
  • uue Dockeri deemoni käivitamine;
  • katsetamine;
  • korrake tsüklit.

Kui tahtsite teha ilusat reprodutseeritavat koostu (st konteineris), siis muutus see keerulisemaks:

  • hackity hack;
  • veenduge, et töötaks Dockeri tööversioon;
  • ehitada uus Docker koos vana Dockeriga;
  • peatada Dockeri deemon;
  • käivitage uus Dockeri deemon;
  • test;
  • peatada uus Dockeri deemon;
  • korda.

Docker-in-Dockeri tulekuga on protsess muutunud lihtsamaks:

  • hackity hack;
  • kokkupanek + käivitamine ühes etapis;
  • korrake tsüklit.

Kas pole nii palju parem?

Mõelge hoolikalt enne Docker-in-Dockeri CI või testkeskkonna jaoks kasutamist

Docker-in-Docker: "halb"

Kuid vastupidiselt levinud arvamusele ei ole Docker-in-Docker 100% staarid, ponid ja ükssarved. Pean silmas seda, et arendaja peab teadma mitmeid probleeme.

Üks neist puudutab LSM-e (Linuxi turvamooduleid), nagu AppArmor ja SELinux: konteineri käitamisel võib "sisemine dokkija" proovida rakendada turvaprofiile, mis lähevad vastuollu või ajavad segadusse "välise dokkeriga". See on privilegeeritud lipu algse teostuse liitmisel kõige keerulisem probleem. Minu muudatused töötasid ja kõik testid edastasid mu Debiani masinale ja Ubuntu test-VM-idele, kuid need jooksid kokku ja põlesid Michael Crosby masinas (minu mäletamist mööda oli tal Fedora). Ma ei mäleta probleemi täpset põhjust, kuid see võis olla tingitud sellest, et Mike on tark mees, kes töötab SELINUX=enforce'iga (kasutasin AppArmor) ja minu muudatused ei võtnud SELinuxi profiile arvesse.

Docker-in-Docker: "Kuri"

Teine probleem on seotud Dockeri salvestusdraiveritega. Kui käivitate Docker-in-Dockeri, töötab väline Docker tavalise failisüsteemi peal (EXT4, BTRFS või mis iganes teil on) ja sisemine Docker töötab kirjutamisel kopeerimise süsteemi (AUFS, BTRFS, Device Mapper) peal. jne). , olenevalt sellest, mis on välise Dockeri kasutamiseks konfigureeritud). See loob palju kombinatsioone, mis ei tööta. Näiteks ei saa te AUFS-i peale AUFS-i käivitada.

Kui käivitate BTRFS-i BTRFS-i peal, peaks see alguses töötama, kuid kui pesastatud alamköiteid on olemas, siis ülem-alamköite kustutamine nurjub. Device Mapperi moodulil pole nimeruumi, nii et kui mitu Dockeri eksemplari käitavad seda samas masinas, saavad nad kõik üksteise ja konteineri varundusseadmete pilte näha (ja mõjutada). See on halb.

Paljude nende probleemide lahendamiseks on olemas lahendused. Näiteks kui soovite sisemises Dockeris kasutada AUFS-i, muutke lihtsalt kaust /var/lib/docker köiteks ja kõik on korras. Docker on lisanud Device Mapperi sihtnimedele mõned põhinimeruumid, nii et kui samas masinas töötab mitu Dockeri kõnet, ei hakkaks need üksteisele peale astuma.

Selline seadistus pole aga sugugi lihtne, nagu nendest näha artiklid GitHubi dindi hoidlas.

Docker-in-Docker: see läheb hullemaks

Aga ehitusvahemälu? See võib olla ka üsna keeruline. Inimesed küsivad minult sageli: "Kui ma kasutan Docker-in-Dockerit, siis kuidas ma saan kasutada hostis hostitud pilte, selle asemel, et kõik oma sisemisse Dockerisse tagasi tõmmata"?

Mõned ettevõtlikud inimesed on püüdnud siduda hostist faili /var/lib/docker Docker-in-Dockeri konteineriga. Mõnikord jagavad nad /var/lib/dockerit mitme konteineriga.

Mõelge hoolikalt enne Docker-in-Dockeri CI või testkeskkonna jaoks kasutamist
Kas soovite oma andmeid rikkuda? Sest just see kahjustab teie andmeid!

Dockeri deemon oli selgelt loodud nii, et sellel oleks eksklusiivne juurdepääs failile /var/lib/docker. Mitte miski muu ei tohiks selles kaustas asuvaid Dockeri faile puudutada, torkida ega toota.

Miks see nii on? Sest see on dotCloudi arendamisel saadud ühe raskeima õppetunni tulemus. DotCloudi konteineri mootor töötas nii, et mitu protsessi pääses korraga juurde /var/lib/dotcloudile. Kavalad nipid, nagu aatomifailide asendamine (kohapealse redigeerimise asemel), koodi lisamine nõustavate ja kohustuslike lukkudega ning muud katsetused turvaliste süsteemidega, nagu SQLite ja BDB, ei töötanud alati. Kui kujundasime ümber oma konteinerimootorit, millest lõpuks sai Docker, oli üks suuremaid projekteerimisotsuseid koondada kõik konteinerite toimingud ühe deemoni alla, et kaotada kogu samaaegsuse jama.

Ärge saage minust valesti aru: on täiesti võimalik teha midagi head, usaldusväärset ja kiiret, mis hõlmab mitut protsessi ja kaasaegset paralleeljuhtimist. Kuid me arvame, et Dockeri kui ainsa mängija abil on koodi kirjutamine ja hooldamine lihtsam ja lihtsam.

See tähendab, et kui jagate kataloogi /var/lib/docker mitme Dockeri eksemplari vahel, tekib probleeme. Muidugi võib see toimida, eriti testimise algfaasis. "Kuule, ema, ma võin ubuntut dokkijana käivitada!" Kuid proovige midagi keerukamat, näiteks võtke sama pilt kahest erinevast eksemplarist, ja näete, et maailm põleb.

See tähendab, et kui teie CI-süsteem teostab järge ja ümberehitusi, siis iga kord, kui Docker-in-Dockeri konteinerit taaskäivitate, on oht, et selle vahemällu kukub tuumarelva. See pole üldse lahe!

Lahendus

Astume sammu tagasi. Kas teil on tõesti Docker-in-Dockerit vaja või soovite lihtsalt käitada Dockerit ning luua ja käitada oma CI-süsteemist konteinereid ja pilte, kui see CI-süsteem ise on konteineris?

Vean kihla, et enamik inimesi soovib viimast võimalust, mis tähendab, et nad tahavad, et CI-süsteem nagu Jenkins saaks konteinereid käitada. Ja kõige lihtsam viis seda teha on lihtsalt sisestada Dockeri pesa oma CI konteinerisse ja seostada see lipuga -v.

Lihtsamalt öeldes, kui käitate oma CI konteinerit (Jenkins või muu), selle asemel, et midagi koos Docker-in-Dockeriga häkkida, alustage seda reaga:

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

Sellel konteineril on nüüd juurdepääs Dockeri pistikupesale ja seetõttu saab see konteinereid käitada. Välja arvatud see, et „lapskonteinerite” käitamise asemel käivitab see „vend” konteinerid.

Proovige seda ametliku dockeri kujutisega (mis sisaldab Dockeri kahendfaili):

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

See näeb välja ja töötab nagu Docker-in-Docker, kuid see pole Docker-in-Docker: kui see konteiner loob täiendavaid konteinereid, luuakse need tipptasemel Dockeris. Te ei koge pesastumise kõrvalmõjusid ja koostevahemälu jagatakse mitme kõne vahel.

Märkus. Selle artikli eelmised versioonid soovitasid linkida hosti Dockeri binaarfaili konteineriga. See on muutunud ebausaldusväärseks, kuna Dockeri mootor ei kata enam staatilisi ega peaaegu staatilisi teeke.

Seega, kui soovite kasutada Jenkins CI Dockerit, on teil kaks võimalust:
Dockeri CLI installimine põhilise pildipakendamise süsteemi abil (st kui teie pilt põhineb Debianil, kasutage .deb-pakette), kasutades Dockeri API-d.

Mõned reklaamid 🙂

Täname, et jäite meiega. Kas teile meeldivad meie artiklid? Kas soovite näha huvitavamat sisu? Toeta meid, esitades tellimuse või soovitades sõpradele, pilve VPS arendajatele alates 4.99 dollarist, algtaseme serverite ainulaadne analoog, mille me teie jaoks leiutasime: Kogu tõde VPS (KVM) E5-2697 v3 (6 tuuma) 10GB DDR4 480GB SSD 1Gbps kohta alates 19 dollarist või kuidas serverit jagada? (saadaval RAID1 ja RAID10, kuni 24 tuuma ja kuni 40 GB DDR4-ga).

Dell R730xd 2x odavam Amsterdami Equinixi Tier IV andmekeskuses? Ainult siin 2 x Intel TetraDeca-Core Xeon 2x E5-2697v3 2.6 GHz 14C 64GB DDR4 4x960GB SSD 1Gbps 100 telerit alates 199 dollarist Hollandis! Dell R420 – 2x E5-2430 2.2Ghz 6C 128GB DDR3 2x960GB SSD 1Gbps 100TB – alates 99 dollarist! Millegi kohta lugema Kuidas ehitada infrastruktuuri ettevõtet. klassis koos Dell R730xd E5-2650 v4 serverite kasutusega 9000 eurot senti?

Allikas: www.habr.com

Lisa kommentaar