Pensu zorge antaŭ ol uzi Docker-in-Docker por CI aŭ testa medio

Pensu zorge antaŭ ol uzi Docker-in-Docker por CI aŭ testa medio

Docker-in-Docker estas virtualigita Docker-demona medio funkcianta ene de la ujo mem por konstrui ujbildojn. La ĉefa celo de kreado de Docker-in-Docker estis helpi evoluigi Docker mem. Multaj homoj uzas ĝin por ruli Jenkins CI. Ĉi tio ŝajnas normala komence, sed poste aperas problemoj, kiuj povas esti evititaj instalante Docker en Jenkins CI-ujo. Ĉi tiu artikolo diras al vi kiel fari tion. Se vi interesiĝas pri la fina solvo sen detaloj, simple legu la lastan sekcion de la artikolo, "Solvanta la Problemon."

Pensu zorge antaŭ ol uzi Docker-in-Docker por CI aŭ testa medio

Docker-in-Docker: "Bona"

Antaŭ pli ol du jaroj mi metis en Docker flago – privilegiis kaj skribis unua versio de dind. La celo estis helpi la kernteamon evoluigi Docker pli rapide. Antaŭ Docker-in-Docker, la tipa disvolva ciklo aspektis jene:

  • hackity hako;
  • konstrui;
  • haltigi kurantan Docker-demonon;
  • lanĉante novan Docker-demonon;
  • testado;
  • ripetu la ciklon.

Se vi volis fari belan, reprodukteblan asembleon (tio estas, en ujo), tiam ĝi fariĝis pli komplika:

  • hackity hako;
  • certigu, ke funkcianta versio de Docker funkcias;
  • konstrui novan Docker kun malnova Docker;
  • haltigu Docker-demonon;
  • komenci novan Docker-demonon;
  • testo;
  • haltigi novan Docker-demonon;
  • ripeti.

Kun la apero de Docker-in-Docker, la procezo fariĝis pli simpla:

  • hackity hako;
  • muntado + lanĉo en unu etapo;
  • ripetu la ciklon.

Ĉu ne estas multe pli bone ĉi tiel?

Pensu zorge antaŭ ol uzi Docker-in-Docker por CI aŭ testa medio

Docker-in-Docker: "Malbona"

Tamen, kontraŭe al populara kredo, Docker-in-Docker ne estas 100% steloj, poneoj kaj unikornoj. Kion mi volas diri estas, ke estas pluraj aferoj, pri kiuj programisto devas esti konscia.

Unu el ili koncernas LSM-ojn (Linukso-sekurecaj moduloj) kiel AppArmor kaj SELinux: dum funkciado de ujo, la "interna Docker" eble provos apliki sekurecajn profilojn, kiuj konfliktos aŭ konfuzos la "eksteran Docker". Ĉi tio estas la plej malfacila problemo solvi kiam oni provas kunfandi la originan efektivigon de la flago –privilegia. Miaj ŝanĝoj funkciis kaj ĉiuj testoj transdonus mian Debianan maŝinon kaj Ubuntu-testajn VM-ojn, sed ili kraŝus kaj brulus sur la maŝino de Michael Crosby (li havis Fedora kiel mi memoras). Mi ne povas memori la precizan kaŭzon de la problemo, sed eble estis ĉar Mike estas saĝa ulo, kiu laboras kun SELINUX=enforce (mi uzis AppArmor) kaj miaj ŝanĝoj ne enkalkulis SELinux-profilojn.

Docker-in-Docker: "Malico"

La dua afero estas kun Docker-stokaj ŝoforoj. Kiam vi rulas Docker-in-Docker, ekstera Docker funkcias aldone al regula dosiersistemo (EXT4, BTRFS, aŭ kion ajn vi havas) kaj interna Docker funkcias aldone al kopi-sur-skriba sistemo (AUFS, BTRFS, Device Mapper). , ktp.). , depende de tio, kio estas agordita por uzi eksteran Docker). Ĉi tio kreas multajn kombinaĵojn, kiuj ne funkcios. Ekzemple, vi ne povos ruli AUFS super AUFS.

Se vi rulas BTRFS sur BTRFS, ĝi devus funkcii komence, sed post kiam estas nestitaj subvolumoj, forigo de la gepatra subvolumo malsukcesos. La Device Mapper-modulo havas neniun nomspacon, do se pluraj Docker-instancoj rulas ĝin sur la sama maŝino, ili ĉiuj povos vidi (kaj influi) la bildojn unu sur la alia kaj sur la uj-rezervaj aparatoj. Ĉi tio estas malbona.

Estas solvoj por solvi multajn el ĉi tiuj problemoj. Ekzemple, se vi volas uzi AUFS en interna Docker, simple turnu la dosierujon /var/lib/docker en volumon kaj vi estos bone. Docker aldonis kelkajn bazajn nomspacojn al Device Mapper celnomoj tiel ke se pluraj Docker-vokoj funkcias sur la sama maŝino, ili ne paŝas unu sur la alian.

Tamen tia aranĝo tute ne estas simpla, kiel oni povas vidi el ĉi tiuj artikoloj en la dind-deponejo sur GitHub.

Docker-in-Docker: Ĝi plimalboniĝas

Kio pri la konstrukaŝmemoro? Ĉi tio ankaŭ povas esti sufiĉe malfacila. Homoj ofte demandas min "se mi rulas Docker-in-Docker, kiel mi povas uzi bildojn gastigitajn ĉe mia gastiganto anstataŭ tiri ĉion reen en mian internan Docker"?

Iuj entreprenemaj homoj provis ligi /var/lib/docker de la gastiganto al Docker-in-Docker-ujo. Kelkfoje ili kunhavas /var/lib/docker kun pluraj ujoj.

Pensu zorge antaŭ ol uzi Docker-in-Docker por CI aŭ testa medio
Ĉu vi volas korupti viajn datumojn? Ĉar ĝuste ĉi tio damaĝos viajn datumojn!

La Docker-demono estis klare dizajnita por havi ekskluzivan aliron al /var/lib/docker. Nenio alia devus "tuŝi, piki aŭ piki" iujn ajn Docker-dosierojn situantajn en ĉi tiu dosierujo.

Kial ĉi tio estas tiel? Ĉar ĉi tio estas la rezulto de unu el la plej malfacilaj lecionoj lernitaj dum disvolvado de dotCloud. La dotCloud-ujo-motoro funkciis havante plurajn procezojn alirantajn /var/lib/dotcloud samtempe. Ruzaj lertaĵoj kiel ekzemple atomdosieranstataŭaĵo (anstataŭ surloka redaktado), piprikodo kun konsilaj kaj devigaj seruroj, kaj aliaj eksperimentoj kun sekuraj sistemoj kiel ekzemple SQLite kaj BDB ne ĉiam funkciis. Kiam ni restrukturis nian ujran motoron, kiu poste iĝis Docker, unu el la grandaj dezajnaj decidoj estis plifirmigi ĉiujn ujajn operaciojn sub ununura demono por forigi ĉiujn samtempajn sensencaĵojn.

Ne miskomprenu min: estas tute eble fari ion bonan, fidindan kaj rapidan, kiu implikas plurajn procezojn kaj modernan paralelan kontrolon. Sed ni opinias, ke estas pli simpla kaj pli facile skribi kaj konservi kodon uzante Docker kiel la solan ludilon.

Ĉi tio signifas, ke se vi dividas la dosierujon /var/lib/docker inter pluraj Docker-okazoj, vi havos problemojn. Kompreneble, ĉi tio povas funkcii, precipe en la fruaj stadioj de testado. "Aŭskultu, panjo, mi povas funkciigi ubuntu kiel doker!" Sed provu ion pli kompleksan, kiel tiri la saman bildon el du malsamaj okazoj, kaj vi vidos la mondon bruli.

Ĉi tio signifas, ke se via CI-sistemo faras konstruojn kaj rekonstruojn, ĉiufoje kiam vi rekomencas vian Docker-in-Docker-ujon, vi riskas faligi atombombon en ĝian kaŝmemoron. Ĉi tio tute ne estas mojosa!

Problemo

Ni faru paŝon malantaŭen. Ĉu vi vere bezonas Docker-in-Docker aŭ ĉu vi nur volas povi ruli Docker kaj konstrui kaj ruli ujojn kaj bildojn de via CI-sistemo dum tiu CI-sistemo mem estas en ujo?

Mi vetas, ke plej multaj homoj volas ĉi-lastan opcion, tio signifas, ke ili volas CI-sistemon kiel Jenkins povi ruli ujojn. Kaj la plej facila maniero fari tion estas simple enigi Docker-ingon en vian CI-ujon kaj asocii ĝin kun la -v flago.

Simple dirite, kiam vi rulas vian CI-ujon (Jenkins aŭ alia), anstataŭ haki ion kune kun Docker-in-Docker, komencu ĝin per la linio:

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

Ĉi tiu ujo nun havos aliron al la ingo Docker kaj do povos ruli ujojn. Krom ke anstataŭ ruli "infanajn" ujojn, ĝi lanĉos "fratajn" ujojn.

Provu ĉi tion uzante la oficialan docker-bildon (kiu enhavas la Docker-binaron):

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

Ĝi aspektas kaj funkcias kiel Docker-in-Docker, sed ĝi ne estas Docker-in-Docker: kiam ĉi tiu ujo kreas pliajn ujojn, ili estos kreitaj en la plej alta nivelo Docker. Vi ne spertos la kromefikojn de nestado kaj la asembleokaŝmemoro estos dividita tra pluraj alvokoj.

Noto: Antaŭaj versioj de ĉi tiu artikolo konsilis ligi la binaron Docker de la gastiganto al la ujo. Ĉi tio nun fariĝis nefidinda ĉar la Docker-motoro ne plu kovras senmovajn aŭ preskaŭ senmovajn bibliotekojn.

Do, se vi volas uzi Docker de Jenkins CI, vi havas 2 eblojn:
instalante la Docker CLI uzante la bazan bildan paksistemon (t.e. se via bildo estas bazita sur Debian, uzu .deb-pakaĵojn), uzante la Docker API.

Kelkaj reklamoj 🙂

Dankon pro restado ĉe ni. Ĉu vi ŝatas niajn artikolojn? Ĉu vi volas vidi pli interesan enhavon? Subtenu nin farante mendon aŭ rekomendante al amikoj, nuba VPS por programistoj de $4.99, unika analogo de enirnivelaj serviloj, kiu estis inventita de ni por vi: La tuta vero pri VPS (KVM) E5-2697 v3 (6 Kernoj) 10GB DDR4 480GB SSD 1Gbps de $ 19 aŭ kiel dividi servilon? (havebla kun RAID1 kaj RAID10, ĝis 24 kernoj kaj ĝis 40GB DDR4).

Dell R730xd 2 fojojn pli malmultekosta en Equinix Tier IV datumcentro en Amsterdamo? Nur ĉi tie 2 x Intel TetraDeca-Core Xeon 2x E5-2697v3 2.6GHz 14C 64GB DDR4 4x960GB SSD 1Gbps 100 televidilo ekde 199 USD en Nederlando! Dell R420 - 2x E5-2430 2.2Ghz 6C 128GB DDR3 2x960GB SSD 1Gbps 100TB - ekde $99! Legu pri Kiel konstrui infrastrukturan korpon. klaso kun la uzo de serviloj Dell R730xd E5-2650 v4 valorantaj 9000 eŭrojn por centono?

fonto: www.habr.com

Aldoni komenton