Denkt virsiichteg ier Dir Docker-in-Docker fir CI oder Testëmfeld benotzt

Denkt virsiichteg ier Dir Docker-in-Docker fir CI oder Testëmfeld benotzt

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."

Denkt virsiichteg ier Dir Docker-in-Docker fir CI oder Testëmfeld benotzt

Docker-in-Docker: "Gutt"

Viru méi wéi zwee Joer hunn ech an Docker gesat Fändel -privilegéiert a geschriwwen éischt Versioun vun dind. D'Zil war d'Kärteam ze hëllefen Docker méi séier z'entwéckelen. Virun Docker-in-Docker huet den typeschen Entwécklungszyklus esou ausgesinn:

  • 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?

Denkt virsiichteg ier Dir Docker-in-Docker fir CI oder Testëmfeld benotzt

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 Artikelen am dind Repository op GitHub.

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.

Denkt virsiichteg ier Dir Docker-in-Docker fir CI oder Testëmfeld benotzt
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, Cloud VPS fir Entwéckler vun $ 4.99, en eenzegaartegen Analog vun Entry-Level Serveren, dee vun eis fir Iech erfonnt gouf: Déi ganz Wourecht iwwer VPS (KVM) E5-2697 v3 (6 Cores) 10GB DDR4 480GB SSD 1Gbps vun $19 oder wéi een e Server deelt? (verfügbar mat RAID1 an RAID10, bis zu 24 Kären a bis zu 40GB DDR4).

Dell R730xd 2 Mol méi bëlleg an Equinix Tier IV Daten Zentrum zu Amsterdam? Nëmmen hei 2 x Intel TetraDeca-Core Xeon 2x E5-2697v3 2.6GHz 14C 64GB DDR4 4x960GB SSD 1Gbps 100 TV vun $199 an Holland! Dell R420 - 2x E5-2430 2.2Ghz 6C 128GB DDR3 2x960GB SSD 1Gbps 100TB - vun $99! Liest iwwer Wéi bauen ech Infrastructure Corp. Klass mat der Benotzung vun Dell R730xd E5-2650 v4 Serveren Wäert 9000 Euro fir e Penny?

Source: will.com

Setzt e Commentaire