Docker-in-Docker ass e virtualiséiert Docker Daemon Ëmfeld, deen am Container selwer leeft fir Container Biller ze bauen. Den Haaptzweck fir Docker-in-Docker ze kreéieren war ze hëllefen Docker selwer z'entwéckelen. Vill Leit benotzen et fir Jenkins CI ze lafen. Dëst schéngt am Ufank normal, awer dann entstinn Probleemer déi vermeit kënne ginn andeems Dir Docker an engem Jenkins CI Container installéiert. Dësen Artikel seet Iech wéi dëst ze maachen. Wann Dir un der definitiver Léisung ouni Detailer interesséiert sidd, liest just déi lescht Sektioun vum Artikel, "De Problem léisen."
Docker-in-Docker: "Gutt"
Viru méi wéi zwee Joer hunn ech an Docker gesat
- Hackitéit Hack;
- bauen;
- Stoppen vun engem lafende Docker Daemon;
- lancéiert en neien Docker Daemon;
- Testen;
- widderhuelen den Zyklus.
Wann Dir eng schéi, reproduzéierbar Versammlung wollt maachen (dat ass an engem Container), da gouf et méi komplizéiert:
- Hackitéit Hack;
- sécherstellen datt eng funktionéierend Versioun vum Docker leeft;
- bauen neien Docker mat alen Docker;
- Stop Docker Daemon;
- en neien Docker Daemon starten;
- Test;
- stoppen neien Docker Daemon;
- widderhuelen.
Mam Advent vum Docker-in-Docker ass de Prozess méi einfach ginn:
- Hackitéit Hack;
- Assemblée + Start an enger Etapp;
- widderhuelen den Zyklus.
Ass et net vill besser esou?
Docker-in-Docker: "Schlecht"
Wéi och ëmmer, am Géigesaz zum populäre Glawen, ass Docker-in-Docker net 100% Stären, Ponyen an Eenhornen. Wat ech mengen ass datt et e puer Themen sinn déi en Entwéckler muss bewosst sinn.
Ee vun hinnen betrëfft LSMs (Linux Sécherheetsmoduler) wéi AppArmor a SELinux: wann Dir e Container leeft, kann den "internen Docker" probéieren Sécherheetsprofile z'applizéieren déi den "externen Docker" konfliktéieren oder duercherneen bréngen. Dëst ass dee schwieregste Problem ze léisen wann Dir probéiert d'originell Ëmsetzung vum –privileged Fändel ze fusionéieren. Meng Ännerungen hunn geschafft an all Tester géifen op meng Debian Maschinn an Ubuntu Test VMs passéieren, awer si wäerten op dem Michael Crosby seng Maschinn crashen a verbrennen (hien hat Fedora wéi ech mech erënneren). Ech erënnere mech net un déi genee Ursaach vum Problem, awer et kann gewiescht sinn datt de Mike e weise Guy ass dee mat SELINUX = erzwéngen schafft (Ech hunn AppArmor benotzt) a meng Ännerungen hunn SELinux Profiler net berücksichtegt.
Docker-in-Docker: "Béis"
Déi zweet Ausgab ass mat Docker Späichertreiber. Wann Dir Docker-in-Docker leeft, leeft den externen Docker uewen op engem normale Dateiesystem (EXT4, BTRFS, oder wat och ëmmer Dir hutt) an intern Docker leeft uewen op engem Copy-on-Write System (AUFS, BTRFS, Device Mapper) , etc.). , ofhängeg vun deem wat konfiguréiert ass fir extern Docker ze benotzen). Dëst schaaft vill Kombinatioune datt net Aarbecht wäert. Zum Beispill kënnt Dir AUFS net uewen op AUFS lafen.
Wann Dir BTRFS uewen op BTRFS leeft, sollt et am Ufank funktionnéieren, awer wann et nestéiert Ënnervolumen gëtt, wäert d'Läschen vum Elterendeel-Subvolumen feelen. Den Device Mapper Modul huet keen Nummraum, also wa verschidde Docker Instanzen et op der selwechter Maschinn lafen, kënnen se all d'Biller openeen an op de Container Backup-Geräter gesinn (an beaflossen). Dëst ass schlecht.
Et gi Léisunge fir vill vun dëse Probleemer ze léisen. Zum Beispill, wann Dir AUFS am internen Docker benotze wëllt, verwandelt just den /var/lib/docker Dossier an e Volumen an Dir wäert gutt sinn. Docker huet e puer Basis Nummraim zu Device Mapper Zilnimm bäigefüügt, sou datt wa verschidde Docker Uriff op der selwechter Maschinn lafen, se net openeen trëppelen.
Wéi och ëmmer, sou eng Opstellung ass guer net einfach, wéi aus dësen ze gesinn ass
Docker-in-Docker: Et gëtt méi schlëmm
Wat iwwer de Build Cache? Dëst kann och zimlech schwéier sinn. D'Leit froe mech dacks "wann ech Docker-in-Docker lafen, wéi kann ech Biller benotzen déi op mengem Host gehost ginn anstatt alles zréck a mengem internen Docker ze zéien"?
E puer entreprise Leit hu probéiert /var/lib/docker vum Host an en Docker-in-Docker Container ze binden. Heiansdo deelen se /var/lib/docker mat multiple Container.
Wëllt Dir Är Donnéeën korruptéieren? Well dat ass genau dat wat Är Donnéeën beschiedegt!
Den Docker Daemon war kloer entworf fir exklusiv Zougang zu /var/lib/docker ze hunn. Näischt anescht soll all Docker Dateien an dësem Dossier "beréieren, pochen oder prodéieren".
Firwat ass dat esou? Well dëst ass d'Resultat vun enger vun den haardsten Lektioune geléiert wärend DotCloud entwéckelt. Den dotCloud Containermotor leeft andeems verschidde Prozesser Zougang zu /var/lib/dotcloud gläichzäiteg hunn. Knaschteg Tricken wéi Atomer Datei Ersatz (amplaz vun der Plaz Redaktioun), Pepper Code mat berodend an obligatoresch Spären, an aner Experimenter mat sécher Systemer wéi SQLite an BDB net ëmmer geschafft. Wéi mir eise Containermotor nei designen, dee schlussendlech Docker gouf, war eng vun de groussen Designentscheedungen all Containeroperatioune ënner engem eenzegen Daemon ze konsolidéieren fir all de concurrency Nonsense ze läschen.
Verstitt mech net falsch: et ass ganz méiglech eppes Guddes, zouverlässeg a séier ze maachen, wat verschidde Prozesser a modern parallel Kontroll involvéiert. Awer mir mengen et ass méi einfach a méi einfach Code ze schreiwen an z'erhalen mat Docker als eenzegen Spiller.
Dëst bedeit datt wann Dir den /var/lib/docker Verzeichnis tëscht verschidde Docker Instanzen deelt, hutt Dir Probleemer. Natierlech kann dëst funktionnéieren, besonnesch an de fréie Stadien vum Test. "Lauschtert, Ma, ech kann Ubuntu als Docker lafen!" Awer probéiert eppes méi komplex, wéi datselwecht Bild aus zwee verschiddenen Instanzen ze zéien, an Dir gesitt d'Welt verbrennt.
Dëst bedeit datt wann Äre CI System Builds a Rebuilds ausféiert, all Kéier wann Dir Ären Docker-in-Docker Container nei start, riskéiert Dir en Nuke a säi Cache ze falen. Dëst ass guer net cool!
Problem mat der Problembehandlung
Loosst eis e Schrëtt zréck huelen. Braucht Dir wierklech Docker-in-Docker oder wëllt Dir just fäeg sinn Docker auszeféieren a Container a Biller vun Ärem CI System ze bauen a lafen, während dee CI System selwer an engem Container ass?
Ech wetten datt déi meescht Leit déi lescht Optioun wëllen, dat heescht datt se e CI System wéi Jenkins wëllen fir Container ze lafen. An deen einfachste Wee fir dëst ze maachen ass einfach en Docker Socket an Ärem CI Container ze setzen an et mam -v Fändel ze associéieren.
Einfach gesot, wann Dir Ären CI Container leeft (Jenkins oder soss), anstatt eppes mat Docker-in-Docker ze hacken, fänkt et mat der Linn un:
docker run -v /var/run/docker.sock:/var/run/docker.sock ...
Dëse Container wäert elo Zougang zum Docker Socket hunn an dofir fäeg sinn Container ze lafen. Ausser datt amplaz "Kand" Container ze lafen, wäert et "Geschwëster" Container starten.
Probéiert dëst mam offiziellen Docker Bild (wat den Docker Binär enthält):
docker run -v /var/run/docker.sock:/var/run/docker.sock
-ti docker
Et gesäit aus a funktionnéiert wéi Docker-in-Docker, awer et ass net Docker-in-Docker: wann dëse Container zousätzlech Container erstellt, gi se am Top-Level Docker erstallt. Dir wäert d'Nebenwirkungen vum Nesting net erliewen an de Versammlungscache gëtt iwwer verschidde Uruff gedeelt.
Bemierkung: Virdru Versioune vun dësem Artikel hunn ugeroden den Docker Binär vum Host an de Container ze verbannen. Dëst ass elo onzouverlässeg ginn well den Docker Motor net méi statesch oder bal statesch Bibliothéiken ofdeckt.
Also, wann Dir Docker vum Jenkins CI benotze wëllt, hutt Dir 2 Optiounen:
d'Installatioun vum Docker CLI mat der Basis Bildverpackungssystem (dh wann Äert Bild op Debian baséiert, benotzt .deb Packagen), mat der Docker API.
Puer Annoncen 🙂
Merci datt Dir bei eis bleift. Hutt Dir eis Artikelen gär? Wëllt Dir méi interessant Inhalt gesinn? Ënnerstëtzt eis andeems Dir eng Bestellung maacht oder Frënn empfeelt,
Dell R730xd 2 Mol méi bëlleg an Equinix Tier IV Daten Zentrum zu Amsterdam? Nëmmen hei
Source: will.com