Pensate bè prima di utilizà Docker-in-Docker per CI o ambienti di prova

Pensate bè prima di utilizà Docker-in-Docker per CI o ambienti di prova

Docker-in-Docker hè un ambiente daemon Docker virtualizatu chì funziona in u cuntainer stessu per custruisce l'imaghjini di u containeru. U scopu principale di creà Docker-in-Docker era di aiutà à sviluppà Docker stessu. Parechje persone l'utilizanu per eseguisce Jenkins CI. Questu pare normale in prima, ma poi si sviluppanu prublemi chì ponu esse evitati installendu Docker in un containeru Jenkins CI. Questu articulu vi dice cumu fà questu. Sè vo site interessatu à a suluzione finale senza dettagli, basta à leghje l'ultima sezione di l'articulu, "Risolviri u prublema".

Pensate bè prima di utilizà Docker-in-Docker per CI o ambienti di prova

Docker-in-Docker: "Bè"

Più di dui anni fà aghju messu in Docker bandiera - privilegiatu è scrittu prima versione di dind. L'obiettivu era di aiutà à a squadra core à sviluppà Docker più veloce. Prima di Docker-in-Docker, u ciculu di sviluppu tipicu pareva cusì:

  • pirate di pirate;
  • custruì;
  • arrestà un daemon Docker in esecuzione;
  • lanciari un novu daemon Docker;
  • prova;
  • ripetiri u ciclu.

Se vulete fà una bella assemblea riproducibile (vale à dì, in un cuntinuu), allora hè diventatu più intricatu:

  • pirate di pirate;
  • assicuratevi chì una versione di travagliu di Docker hè in esecuzione;
  • custruisce un novu Docker cù u vechju Docker;
  • stop Docker daemon;
  • principià un novu daemon Docker;
  • prova;
  • ferma u novu demone Docker;
  • ripetiri.

Cù l'avventu di Docker-in-Docker, u prucessu hè diventatu più simplice:

  • pirate di pirate;
  • assemblea + lanciamentu in una tappa;
  • ripetiri u ciclu.

Ùn hè micca assai megliu cusì ?

Pensate bè prima di utilizà Docker-in-Docker per CI o ambienti di prova

Docker-in-Docker: "Bad"

Tuttavia, contru à a credenza populari, Docker-in-Docker ùn hè micca 100% stelle, poni è unicorni. Ciò chì vogliu dì hè chì ci sò parechje prublemi chì un sviluppatore deve esse cuscenti.

Unu di elli riguarda LSMs (moduli di sicurezza Linux) cum'è AppArmor è SELinux: quandu eseguite un containeru, u "Docker internu" pò pruvà à applicà profili di sicurità chì cunflittu o cunfonde u "Docker esternu". Questu hè u prublema più difficiuli di risolve quandu pruvate di unisce l'implementazione originale di a bandiera -privileged. I mo cambiamenti anu travagliatu è tutte e teste passanu nantu à a mo macchina Debian è Ubuntu test VMs, ma anu crash and brusing on Michael Crosby's machine (hà avutu Fedora cum'è mi ricordu). Ùn possu micca ricurdà a causa esatta di u prublema, ma pò esse perchè Mike hè un omu sàviu chì travaglia cù SELINUX=enforce (aghju utilizatu AppArmor) è i mo cambiamenti ùn anu micca pigliatu i profili SELinux in contu.

Docker-in-Docker: "Evil"

U sicondu prublema hè cù i driver di almacenamiento Docker. Quandu eseguite Docker-in-Docker, Docker esternu corre nantu à un sistema di fugliale regulare (EXT4, BTRFS, o qualunque cosa avete) è Docker internu corre sopra à un sistema di copia in scrittura (AUFS, BTRFS, Device Mapper). , etc.). , secondu ciò chì hè cunfiguratu per utilizà Docker esternu). Questu crea parechje cumminazzioni chì ùn viaghjanu micca. Per esempiu, ùn puderete micca eseguisce AUFS sopra à AUFS.

Se eseguite BTRFS in cima à BTRFS, duverebbe travaglià in prima, ma una volta chì ci sò subvolumi annidati, sguassà u subvolume parent fallerà. U modulu Device Mapper ùn hà micca spaziu di nomi, cusì se parechje istanze di Docker l'anu in esecuzione nantu à a listessa macchina, tutti puderanu vede (è influenzà) l'imaghjini nantu à l'altri è in i dispositi di salvezza di u containeru. Questu hè male.

Ci sò soluzioni per risolve parechji di sti prublemi. Per esempiu, sè vo vulete usà AUFS in Docker internu, basta à trasfurmà u cartulare /var/lib/docker in un voluminu è sarete bè. Docker hà aghjustatu qualchi spazii di nomi di basa à i nomi di destinazione di Device Mapper in modu chì, se parechje chjamate Docker sò in esecuzione nantu à a stessa macchina, ùn si pisanu micca l'un l'altru.

Tuttavia, tali cunfigurazione ùn hè micca sèmplice, cum'è si pò vede da queste articuli in u repository dind in GitHub.

Docker-in-Docker: peghju

E a cache di creazione? Questu pò ancu esse abbastanza difficiule. A ghjente mi dumanda à spessu "s'è aghju eseguitu Docker-in-Docker, cumu possu utilizà l'imaghjini allughjate nantu à u mo òspite invece di ritruvà tuttu in u mo Docker internu"?

Alcune persone intraprendenti anu pruvatu à ligà /var/lib/docker da l'ospite à un containeru Docker-in-Docker. A volte sparte /var/lib/docker cù parechji cuntenituri.

Pensate bè prima di utilizà Docker-in-Docker per CI o ambienti di prova
Vulete currutti i vostri dati? Perchè questu hè esattamente ciò chì dannu i vostri dati!

U daemon Docker hè statu chjaramente cuncepitu per avè accessu esclusivu à /var/lib/docker. Nisun altru ùn deve "toccare, picchià, o prod" qualsiasi schedari Docker situatu in stu cartulare.

Perchè hè cusì? Perchè questu hè u risultatu di una di e lezioni più difficili amparate durante u sviluppu di dotCloud. U mutore di u containeru dotCloud hà funzionatu cù parechje prucessi chì accede à /var/lib/dotcloud simultaneamente. Trucchi astuti cum'è a rimpiazzamentu di u schedariu atomicu (invece di l'editura in situ), u codice di peppering cù chjusi cunsiglii è obligatorii, è altri esperimenti cù sistemi sicuri cum'è SQLite è BDB ùn anu micca sempre travagliatu. Quandu eramu riprogettatu u nostru mutore di cuntainer, chì eventualmente diventò Docker, una di e grandi decisioni di cuncepimentu era di cunsulidà tutte l'operazioni di cuntainer sottu à un solu daemon per sguassà tutte l'assurdità di cuncurrenza.

Ùn vi sbagliate micca: hè interamente pussibule di fà qualcosa di bonu, affidabile è veloce chì implica parechji prucessi è un cuntrollu parallelu mudernu. Ma pensemu chì hè più simplice è più faciule per scrive è mantene u codice utilizendu Docker cum'è l'unicu attore.

Questu significa chì se sparte u cartulare /var/lib/docker trà parechje istanze di Docker, averete prublemi. Di sicuru, questu pò travaglià, soprattuttu in i primi stadi di teste. "Senti, mamma, possu eseguisce ubuntu cum'è docker!" Ma pruvate qualcosa di più cumplessu, cum'è tirà a stessa maghjina da dui casi diffirenti, è vi vede u mondu brusgià.

Questu significa chì se u vostru sistema CI eseguisce custruzzioni è ricustruisce, ogni volta chì riavviate u vostru containeru Docker-in-Docker, rischiate di abbandunà una nucleare in a so cache. Questu ùn hè micca bellu!

Solución di salvezza

Facemu un passu in daretu. Avete veramente bisognu di Docker-in-Docker o vulete solu esse capace di eseguisce Docker è custruisce è eseguite cuntenituri è imagine da u vostru sistema CI mentre chì u sistema CI stessu hè in un containeru?

Aghju scumessa chì a maiò parte di a ghjente volenu l'ultima opzione, vale à dì chì volenu un sistema CI cum'è Jenkins per pudè eseguisce cuntenituri. È u modu più faciule per fà questu hè di inserisce solu un socket Docker in u vostru containeru CI è associà cù a bandiera -v.

Simply put, when you run your CI container (Jenkins or other), invece di pirate qualcosa cù Docker-in-Docker, cuminciate cù a linea:

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

Stu cuntinuu avarà avà accessu à u socket Docker è dunque puderà eseguisce cuntenituri. Eccettu chì invece di eseguisce cuntenituri "figlioli", lanciarà cuntenituri "fratelli".

Pruvate questu utilizendu l'imaghjini ufficiale di docker (chì cuntene u binariu Docker):

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

Sembra è funziona cum'è Docker-in-Docker, ma ùn hè micca Docker-in-Docker: quandu stu containeru crea cuntenituri supplementari, seranu creati in u Docker di primu livellu. Ùn averete micca l'effetti collaterali di a nidificazione è a cache di l'assemblea serà sparta in parechje chjamate.

Nota: Versioni precedenti di questu articulu cunsiglianu di ligà u binariu Docker da l'ospite à u cuntinuu. Questu hè diventatu inaffidabile postu chì u mutore Docker ùn copre più biblioteche statiche o quasi statiche.

Allora, se vulete usà Docker da Jenkins CI, avete 2 opzioni:
installendu a Docker CLI utilizendu u sistema di imballaggio di l'imaghjini di basa (vale à dì, se a vostra maghjina hè basatu annantu à Debian, utilizate pacchetti .deb), utilizendu l'API Docker.

Certi annunzii 🙂

Grazie per stà cun noi. Ti piace i nostri articuli ? Vulete vede più cuntenutu interessante? Supportaci facendu un ordine o ricumandendu à l'amichi, cloud VPS per sviluppatori da $ 4.99, un analogu unicu di servitori di livellu d'entrata, chì hè statu inventatu da noi per voi: Tutta a verità nantu à VPS (KVM) E5-2697 v3 (6 Cores) 10GB DDR4 480GB SSD 1Gbps da $ 19 o cumu si sparte un servitore? (dispunibule cù RAID1 è RAID10, finu à 24 core è finu à 40GB DDR4).

Dell R730xd 2 volte più prezzu in u centru di dati Equinix Tier IV in Amsterdam? Solu quì 2 x Intel TetraDeca-Core Xeon 2x E5-2697v3 2.6GHz 14C 64GB DDR4 4x960GB SSD 1Gbps 100 TV da $ 199 in l'Olanda! Dell R420 - 2x E5-2430 2.2Ghz 6C 128GB DDR3 2x960GB SSD 1Gbps 100TB - da $ 99! Leghje circa Cumu custruisce una infrastruttura corp. classa cù l'usu di i servitori Dell R730xd E5-2650 v4 valenu 9000 XNUMX euro per un centesimu?

Source: www.habr.com

Add a comment