Pred použitím Docker-in-Docker pre CI alebo testovacie prostredie si dôkladne premyslite

Pred použitím Docker-in-Docker pre CI alebo testovacie prostredie si dôkladne premyslite

Docker-in-Docker je virtualizované prostredie démona Docker spustené v samotnom kontajneri na vytváranie obrázkov kontajnera. Hlavným účelom vytvorenia Docker-in-Docker bolo pomôcť pri vývoji samotného Dockera. Mnoho ľudí ho používa na spustenie Jenkins CI. Spočiatku sa to zdá normálne, ale potom nastanú problémy, ktorým sa dá predísť inštaláciou Dockera do kontajnera Jenkins CI. Tento článok vám povie, ako to urobiť. Ak vás zaujíma konečné riešenie bez podrobností, stačí si prečítať poslednú časť článku „Riešenie problému“.

Pred použitím Docker-in-Docker pre CI alebo testovacie prostredie si dôkladne premyslite

Docker-in-Docker: "Dobré"

Pred viac ako dvoma rokmi som vložil do Docker vlajka – privilegovaný a písal prvá verzia dind. Cieľom bolo pomôcť hlavnému tímu vyvinúť Docker rýchlejšie. Pred Docker-in-Docker vyzeral typický vývojový cyklus takto:

  • hackerský hack;
  • stavať;
  • zastavenie bežiaceho démona Docker;
  • spustenie nového démona Docker;
  • testovanie;
  • opakujte cyklus.

Ak ste chceli vytvoriť krásnu, reprodukovateľnú zostavu (to znamená v kontajneri), potom to bolo zložitejšie:

  • hackerský hack;
  • uistite sa, že je spustená pracovná verzia Docker;
  • vytvoriť nový Docker so starým Dockerom;
  • zastaviť démona Docker;
  • spustiť nového démona Docker;
  • test;
  • zastaviť nového démona Docker;
  • opakovať.

S príchodom Docker-in-Docker sa proces zjednodušil:

  • hackerský hack;
  • montáž + spustenie v jednej fáze;
  • opakujte cyklus.

Nie je to takto oveľa lepšie?

Pred použitím Docker-in-Docker pre CI alebo testovacie prostredie si dôkladne premyslite

Docker-in-Docker: "Zlý"

Na rozdiel od všeobecného presvedčenia však Docker-in-Docker nie sú 100% hviezdy, poníky a jednorožce. Chcem tým povedať, že existuje niekoľko problémov, ktoré si vývojár musí uvedomiť.

Jeden z nich sa týka LSM (bezpečnostných modulov Linuxu), ako sú AppArmor a SELinux: pri spustení kontajnera sa môže „interný Docker“ pokúsiť použiť bezpečnostné profily, ktoré budú v konflikte alebo zmätku s „externým Dockerom“. Toto je najťažší problém, ktorý sa rieši pri pokuse o zlúčenie pôvodnej implementácie príznaku –privileged. Moje zmeny fungovali a všetky testy prešli na mojom počítači Debian a testovacích virtuálnych počítačoch Ubuntu, ale na počítači Michaela Crosbyho (mal Fedora, ako si spomínam) zlyhali a zhoreli. Nepamätám si presnú príčinu problému, ale mohlo to byť spôsobené tým, že Mike je múdry človek, ktorý pracuje so SELINUX=enforce (používal som AppArmor) a moje zmeny nezohľadnili profily SELinux.

Docker-in-Docker: "Zlo"

Druhý problém je s ovládačmi úložiska Docker. Keď spustíte Docker-in-Docker, externý Docker beží nad bežným súborovým systémom (EXT4, BTRFS alebo čokoľvek, čo máte) a interný Docker beží nad systémom kopírovania pri zápise (AUFS, BTRFS, Device Mapper , atď.). v závislosti od toho, čo je nakonfigurované na používanie externého Dockera). Vznikne tak veľa kombinácií, ktoré nebudú fungovať. Napríklad nebudete môcť spustiť AUFS nad AUFS.

Ak spustíte BTRFS nad BTRFS, malo by to najprv fungovať, ale keď už existujú vnorené podzväzky, odstránenie nadradeného podzväzku zlyhá. Modul Device Mapper nemá žiadny menný priestor, takže ak ho na tom istom počítači beží viacero inštancií Docker, všetky budú môcť vidieť (a ovplyvňovať) obrázky na sebe a na zariadeniach na zálohovanie kontajnerov. Je to zlé.

Na vyriešenie mnohých z týchto problémov existujú riešenia. Napríklad, ak chcete použiť AUFS v internom Dockeri, jednoducho premeňte priečinok /var/lib/docker na zväzok a budete v poriadku. Docker pridal niektoré základné menné priestory do cieľových názvov Device Mapper, takže ak na tom istom počítači beží viacero hovorov Docker, nebudú na seba šliapať.

Takéto nastavenie však nie je vôbec jednoduché, ako je z nich zrejmé články v úložisku Dind na GitHub.

Docker-in-Docker: Zhoršuje sa to

A čo vyrovnávacia pamäť zostavovania? To môže byť tiež dosť ťažké. Ľudia sa ma často pýtajú: „Ak používam Docker-in-Docker, ako môžem použiť obrázky hostené na mojom hostiteľovi namiesto sťahovania všetkého späť do môjho interného Dockera“?

Niektorí podnikaví ľudia sa pokúsili naviazať /var/lib/docker z hostiteľa na kontajner Docker-in-Docker. Niekedy zdieľajú /var/lib/docker s viacerými kontajnermi.

Pred použitím Docker-in-Docker pre CI alebo testovacie prostredie si dôkladne premyslite
Chcete poškodiť svoje údaje? Pretože práve toto poškodí vaše dáta!

Démon Docker bol jasne navrhnutý tak, aby mal výhradný prístup k /var/lib/docker. Nič iné by sa nemalo „dotýkať, šťouchať alebo pichať“ do žiadnych súborov Docker nachádzajúcich sa v tomto priečinku.

Prečo je to tak? Pretože toto je výsledok jednej z najťažších lekcií získaných pri vývoji dotCloud. Kontajnerový engine dotCloud bežal tak, že viacero procesov súčasne pristupovalo k /var/lib/dotcloud. Prefíkané triky, ako napríklad nahradenie atómového súboru (namiesto úpravy na mieste), okorenenie kódu pomocou poradných a povinných zámkov a ďalšie experimenty so zabezpečenými systémami, ako sú SQLite a BDB, nie vždy fungovali. Keď sme prerábali náš kontajnerový engine, z ktorého sa nakoniec stal Docker, jedným z veľkých návrhových rozhodnutí bolo zjednotiť všetky kontajnerové operácie pod jedného démona, aby sme odstránili všetky nezmysly o súbežnosti.

Nechápte ma zle: je úplne možné vyrobiť niečo dobré, spoľahlivé a rýchle, čo zahŕňa viacero procesov a moderné paralelné riadenie. Ale myslíme si, že je jednoduchšie a jednoduchšie písať a udržiavať kód pomocou Dockera ako jediného hráča.

To znamená, že ak zdieľate adresár /var/lib/docker medzi viacerými inštanciami Dockeru, budete mať problémy. Samozrejme, že to môže fungovať, najmä v počiatočných fázach testovania. "Počúvaj, mami, môžem spustiť ubuntu ako doker!" Skúste však niečo zložitejšie, napríklad vytiahnutie rovnakého obrázka z dvoch rôznych inštancií, a uvidíte, ako svet horí.

To znamená, že ak váš systém CI vykonáva zostavy a prestavby, pri každom reštartovaní kontajnera Docker-in-Docker riskujete zničenie jeho vyrovnávacej pamäte. Toto vôbec nie je cool!

Riešenie

Urobme krok späť. Naozaj potrebujete Docker-in-Docker alebo len chcete mať možnosť spúšťať Docker a vytvárať a spúšťať kontajnery a obrázky z vášho systému CI, zatiaľ čo samotný systém CI je v kontajneri?

Stavím sa, že väčšina ľudí chce druhú možnosť, čo znamená, že chcú, aby systém CI ako Jenkins mohol prevádzkovať kontajnery. A najjednoduchší spôsob, ako to urobiť, je jednoducho vložiť zásuvku Docker do kontajnera CI a priradiť ju k príznaku -v.

Jednoducho povedané, keď spustíte svoj kontajner CI (Jenkins alebo iný), namiesto toho, aby ste niečo hackli spolu s Docker-in-Docker, začnite ho riadkom:

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

Tento kontajner bude mať teraz prístup k zásuvke Docker, a preto bude môcť spúšťať kontajnery. Až na to, že namiesto spúšťania „detských“ kontajnerov spustí „súrodenecké“ kontajnery.

Skúste to pomocou oficiálneho obrázka dockera (ktorý obsahuje binárny súbor Docker):

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

Vyzerá a funguje ako Docker-in-Docker, ale nie je Docker-in-Docker: keď tento kontajner vytvorí ďalšie kontajnery, vytvoria sa v Dockeri najvyššej úrovne. Nezaznamenáte vedľajšie účinky vnorenia a vyrovnávacia pamäť zostavy bude zdieľaná v rámci viacerých hovorov.

Poznámka: Predchádzajúce verzie tohto článku odporúčali prepojenie binárneho súboru Docker z hostiteľa na kontajner. Toto sa teraz stalo nespoľahlivým, pretože motor Docker už nepokrýva statické alebo takmer statické knižnice.

Ak teda chcete používať Docker od Jenkins CI, máte 2 možnosti:
inštalácia Docker CLI pomocou základného systému balenia obrázkov (t. j. ak je váš obrázok založený na Debiane, použite balíky .deb) pomocou Docker API.

Nejaké inzeráty 🙂

Ďakujeme, že ste zostali s nami. Páčia sa vám naše články? Chcete vidieť viac zaujímavého obsahu? Podporte nás zadaním objednávky alebo odporučením priateľom, cloud VPS pre vývojárov od 4.99 USD, jedinečný analóg serverov základnej úrovne, ktorý sme pre vás vymysleli: Celá pravda o VPS (KVM) E5-2697 v3 (6 jadier) 10GB DDR4 480GB SSD 1Gbps od 19 USD alebo ako zdieľať server? (k dispozícii s RAID1 a RAID10, až 24 jadier a až 40 GB DDR4).

Dell R730xd 2 krát lacnejší v dátovom centre Equinix Tier IV v Amsterdame? Len tu 2 x Intel TetraDeca-Core Xeon 2x E5-2697v3 2.6 GHz 14C 64 GB DDR4 4 x 960 GB SSD 1 Gbps 100 TV od 199 USD v Holandsku! Dell R420 – 2x E5-2430 2.2 GHz 6C 128 GB DDR3 2 x 960 GB SSD 1 Gb/s 100 TB – od 99 USD! Čítať o Ako vybudovať infraštruktúru spol. triedy s využitím serverov Dell R730xd E5-2650 v4 v hodnote 9000 XNUMX eur za cent?

Zdroj: hab.com

Pridať komentár