
Docker-in-Docker predstavuje virtualizované prostredie Docker demona, ktoré beží priamo v kontejnery na stavbu kontajnerových obrazov. Hlavným cieľom vytvorenia Docker-in-Docker bola pomoc pri vývoji samotného Dockera. Mnoho ľudí ho používa na spustenie Jenkins CI. Na prvý pohľad to vyzerá normálne, ale neskôr sa vyskytnú problémy, ktorým sa dá predísť, ak nainštalujete Docker do kontejneru Jenkins CI. Tento článok popisuje, ako to urobiť. Ak hľadáte konečné riešenie bez podrobností, jednoducho prečítajte poslednú časť článku 'Riešenie problému'.

Docker-in-Docker: 'Dobrý'
Pred viac ako dvoma rokmi som vložil do Dockera --privileged a napísal . Cieľom bolo pomôcť hlavnej skupine vyvíjať Docker rýchlejšie. Pred vznikom Docker-in-Docker bol typický vývojový cyklus takýto:
- hackity hack;
- build;
- zastavenie bežiaceho Docker demona;
- spustenie nového Docker demona;
- testovanie;
- opakovať cyklus.
Ak ste však chceli vytvoriť peknú, reprodukovateľnú zostavu (t.j. v kontajneri), bolo to zložitejšie:
- hackity hack;
- uistiť sa, že beží funkčná verzia Dockera;
- postaviť nový Docker so starým Dockerom;
- zastaviť Docker demona;
- spustiť nového Docker demona;
- oTESTOVAŤ;
- zastaviť nového Docker demona;
- opakovať.
S príchodom Docker-in-Docker sa proces zjednodušil:
- hackity hack;
- build + spustenie v jednom kroku;
- opakovať cyklus.
Není to pravda, je to oveľa lepšie?

Docker-in-Docker: 'Zlý'
Napriek rozšírenému presvedčeniu však Docker-in-Docker nie je 100% z hviezd, poníkov a jednorožcov. Mám na mysli, že existuje niekoľko problémov, o ktorých by mal vývojár vedieť.
Jedna sa všetkých týchto otázok sa týka LSM (bezpečnostných modulov Linuxu), ako sú AppArmor a SELinux: pri spustení kontajnera môže 'vnútorný Docker' skúsiť aplikovať bezpečnostné profily, ktoré budú konfliktovať alebo zamieňať 'vonkajší Docker'. Toto bola najzložitejšia otázka, ktorú bolo potrebné vyriešiť pri pokuse o zlúčenie pôvodnej implementácie flagu –privileged. Moje zmeny fungovali a všetky testy by prebehli aj na mojom stroji Debian a na testovacích virtuálnych strojoch Ubuntu, ale zrútili by sa a spálili na stroji Michaela Crosbyho (tak si pamätám, že mal Fedoru). Nemôžem si spomenúť na presný dôvod problému, ale možno to bolo preto, že Mike je múdry človek, ktorý pracuje s SELINUX=enforce (ja som používal AppArmor) a moje zmeny nezohľadňovali profily SELinux.
Docker-in-Docker: 'Zlý'
Druhý problém sa týka ovládačov úložísk Docker. Keď spustíte Docker-in-Docker, vonkajší Docker funguje nad bežným súborovým systémom (EXT4, BTRFS alebo akýkoľvek iný, ktorý máte k dispozícii), zatiaľ čo vnútorný Docker funguje nad systémom kopírovania pri zápise (AUFS, BTRFS, Device Mapper a pod., v závislosti od toho, čo je nastavené používať vonkajší Docker). Týmto vzniká mnoho kombinácií, ktoré nebudú fungovať. Napríklad nemôžete spustiť AUFS nad AUFS.
Ak spustíte BTRFS nad BTRFS, spočiatku by to malo fungovať, ale akonáhle sa objavia vnorené podobjemy, nebude možné odstrániť rodičovský podobjem. Modul Device Mapper nemá priestorové názvy, takže ak viaceré inštancie Dockeru používajú na jednom stroji tento modul, všetky budú môcť vidieť (a ovplyvňovať) obrazy navzájom a zariadenia na zálohovanie kontajnerov. To je zlé.
Existujú obchádzky pre riešenie mnohých z týchto problémov. Napríklad, ak chcete používať AUFS vo vnútornom Dockeri, jednoducho premeňte priečinok /var/lib/docker na tento a všetko bude v poriadku. Docker pridáva niektoré základné priestorové názvy do cieľových názvov Device Mapper, takže ak by viacero volaní Docker prebehlo na jednom stroji, nebudú si 'stúpať' na nohy.
Napriek tomu, takáto konfigurácia nie je vôbec jednoduchá, ako je možné vidieť z týchto v repozitári dind na GitHub.
Docker-in-Docker: je to ešte horšie
A čo s cache zostavení? To môže byť tiež dosť zložitá záležitosť. Ľudia sa ma často pýtajú: „ak spúšťam Docker-in-Docker, ako môžem využívať obrazy uložené na mojom hostite, namiesto toho, aby som všetko znova sťahoval do svojho interného Dockeru?“
Niektorí podnikaví ľudia sa pokúsili namapovať /var/lib/docker z hostiteľa do kontajnera Docker-in-Docker. Niekedy zdieľajú /var/lib/docker medzi viacerými kontajnermi.

Chcete poškodiť dáta? Pretože to je presne to, čo poškodí vaše dáta!
Docker démon bol jasne navrhnutý tak, aby mal exkluzívny prístup k /var/lib/docker. Nič iné by nemalo „dotýkať sa, ťukať alebo šmýkať“ akékoľvek súbory Docker nachádzajúce sa v tejto zložke.
Prečo je to tak? Pretože je to výsledok jedného z najťažších lekcií, ktoré sme sa naučili pri vývoji dotCloud. Kontajnerový motor dotCloud pracoval so viacerými procesmi, ktoré sa súčasne obracali na /var/lib/dotcloud. Šikovné triky, ako je atomická výmena súborov (namiesto úpravy na mieste), „ochutenie“ kódu odporúčaniami a povinnými zámkami a ďalšie experimenty s bezpečnými systémami, ako SQLite a BDB, nefungovali vždy. Keď sme prestavovali náš kontajnerový motor, ktorý sa nakoniec premenil na Docker, jedným z hlavných dizajnérskych rozhodnutí bolo konsolidovať všetky operácie s kontajnerami pod jediným démonom, aby sme sa zbavili tejto hlúposti súbežného prístupu.
Nepochopte ma zle: je možné urobiť niečo dobré, spoľahlivé a rýchle, čo bude obsahovať niekoľko procesov a moderné paralelné riadenie. Ale myslíme si, že je jednoduchšie a ľahšie písať a udržiavať kód s použitím Dockeru ako jediného hráča.
To znamená, že ak zdieľate adresár /var/lib/docker medzi viacerými inštanciami Docker, narazíte na problémy. Samozrejme, môže to fungovať, najmä v počiatočných fázach testovania. „Počuj, mami, môžem spustiť ubuntu pomocou 'dockera'!“ Ale skúste spraviť niečo zložitejšie, napríklad vytiahnuť ten istý obraz z dvoch rôznych inštancií, a uvidíte, ako sa svet zapáli.
To znamená, že ak váš CI systém vykonáva zostavenia a pre zostavenia, zakaždým pri reštarte kontajnera Docker-in-Docker riskujete resetovanie y jeho cache jadrovú bombu. To nie je vôbec fajn!
Riešenie problému
Poďme sa na to pozrieť z inej stránky. Skutočne potrebujete Docker-in-Docker alebo len chcete mať možnosť spúšťať Docker a to konkrétne zostavovať a spúšťať kontajnery a obrazy z vášho CI systému, zatiaľ čo tento CI systém je umiestnený v konte?
Stavím sa, že väčšina ľudí potrebuje poslednú možnosť, t.j. chcú, aby CI systém, ako je Jenkins, mohol spúšťať kontajnery. A najjednoduchší spôsob, ako to dosiahnuť, je jednoducho pripojiť socket Docker do vášho CI kontajnera spojením s flagom -v.
Jednoducho povedané, keď spúšťate svoj CI kontajner (Jenkins alebo iný), namiesto toho, aby ste hackovali niečo spoločne s Docker-in-Docker, spustite ho s príkazom:
docker run -v /var/run/docker.sock:/var/run/docker.sock ...Teraz tento kontajner bude mať prístup k socketu Docker a teda bude môcť spúšťať kontajnery. S tým rozdielom, že namiesto spúšťania "podriadených" kontajnerov, bude spúšťať "príbuzné" kontajnery.
Skúste to s oficiálnym obrazom docker (ktorý obsahuje binárny súbor Docker):
docker run -v /var/run/docker.sock:/var/run/docker.sock
-ti dockerVyzerá to a funguje to ako Docker-in-Docker, ale nie je to Docker-in-Docker: keď tento kontajner vytvorí ďalšie kontajnery, budú vytvorené v nadriadenom Dockeri. Nebudete mať vedľajšie účinky vnorenia a cache zostavenia bude spoločná pre viacero volaní.
Poznámka: predchádzajúce verzie tohto článku odporúčali pripojiť binárny súbor Docker z hostiteľa do kontajnera. Teraz je to nespolehlivé, pretože mechanizmus Docker sa už neuplatňuje na statické alebo takmer statické knižnice.
Takže, ak chcete používať Docker z Jenkins CI, máte 2 možnosti:
inštalácia Docker CLI použitím základného systému balíkového obrazu (t.j. ak je váš obraz založený na Debiane, použite balíky .deb), použitie Docker API.
Trochu reklamy 🙂
Ďakujeme, že ostávate s nami. Páčia sa vám naše články? Chcete vidieť viac zaujímavých materiálov? Podporte nás, vytvorením objednávky alebo odporúčaním známym, , unikátny ekvivalent entry-level serverov, ktorý sme pre vás vytvorili: (k dispozícii varianty s RAID1 a RAID10, až 24 jadier a až 40GB DDR4).
Dell R730xd je dvakrát lacnejší v dátovom centre Equinix Tier IV v Amsterdame? Len u nás v Holandsku! Dell R420 — 2x E5-2430 2.2Ghz 6C 128GB DDR3 2x960GB SSD 1Gbps 100TB — od 99 dolárov! Prečítajte si o tom
Zdroj: habr.com
