Mae Docker-in-Docker yn amgylchedd ellyll Docker rhithwir sy'n rhedeg o fewn y cynhwysydd ei hun i adeiladu delweddau cynhwysydd. Prif bwrpas creu Docker-in-Docker oedd helpu i ddatblygu Docker ei hun. Mae llawer o bobl yn ei ddefnyddio i redeg Jenkins CI. Mae hyn yn ymddangos yn normal ar y dechrau, ond yna mae problemau'n codi y gellir eu hosgoi trwy osod Docker mewn cynhwysydd Jenkins CI. Mae'r erthygl hon yn dweud wrthych sut i wneud hyn. Os oes gennych ddiddordeb yn yr ateb terfynol heb fanylion, darllenwch adran olaf yr erthygl, “Datrys y Broblem.”
Dociwr-yn-Docker: "Da"
Mwy na dwy flynedd yn ôl rhoddais i mewn i Docker
- darnia hacio;
- adeiladu;
- atal daemon Dociwr rhedeg;
- lansio daemon Dociwr newydd;
- profi;
- ailadrodd y cylch.
Os oeddech chi eisiau gwneud cynulliad hardd, atgenhedlu (hynny yw, mewn cynhwysydd), yna daeth yn fwy cymhleth:
- darnia hacio;
- gwnewch yn siŵr bod fersiwn weithredol o Docker yn rhedeg;
- adeiladu Dociwr newydd gyda hen Ddociwr;
- ellyll Docker stop;
- cychwyn daemon Dociwr newydd;
- prawf;
- stop ellyll Docker newydd;
- ailadrodd.
Gyda dyfodiad Docker-in-Docker, mae'r broses wedi dod yn symlach:
- darnia hacio;
- cynulliad + lansiad mewn un cam;
- ailadrodd y cylch.
Onid yw llawer gwell fel hyn?
Dociwr-yn-Docker: "Drwg"
Fodd bynnag, yn groes i'r gred boblogaidd, nid yw Docker-in-Docker yn 100% o sêr, merlod ac unicornau. Yr hyn yr wyf yn ei olygu yw bod sawl mater y mae angen i ddatblygwr fod yn ymwybodol ohonynt.
Mae un ohonynt yn ymwneud â LSMs (modiwlau diogelwch Linux) fel AppArmor a SELinux: wrth redeg cynhwysydd, efallai y bydd y "Docker mewnol" yn ceisio cymhwyso proffiliau diogelwch a fydd yn gwrthdaro neu'n drysu'r "Docker allanol". Dyma'r broblem anoddaf i'w datrys wrth geisio uno gweithrediad gwreiddiol y faner breintiedig. Gweithiodd fy newidiadau a byddai pob prawf yn trosglwyddo fy mheiriant Debian a VMs prawf Ubuntu, ond byddent yn damwain ac yn llosgi ar beiriant Michael Crosby (roedd ganddo Fedora fel yr wyf yn cofio). Ni allaf gofio union achos y broblem, ond efallai mai'r rheswm am hyn oedd bod Mike yn foi doeth sy'n gweithio gyda SELINUX=enforce (defnyddiais AppArmor) ac nid oedd fy newidiadau wedi ystyried proffiliau SELinux.
Dociwr-yn-Docker: "Drwg"
Mae'r ail fater yn ymwneud â gyrwyr storio Docker. Pan fyddwch chi'n rhedeg Docker-in-Docker, mae Docker allanol yn rhedeg ar ben system ffeiliau reolaidd (EXT4, BTRFS, neu beth bynnag sydd gennych chi) ac mae Dociwr mewnol yn rhedeg ar ben system copi-ar-ysgrifennu (AUFS, BTRFS, Device Mapper , ac ati). , yn dibynnu ar yr hyn sydd wedi'i ffurfweddu i ddefnyddio Dociwr allanol). Mae hyn yn creu llawer o gyfuniadau na fydd yn gweithio. Er enghraifft, ni fyddwch yn gallu rhedeg AUFS ar ben AUFS.
Os ydych chi'n rhedeg BTRFS ar ben BTRFS, dylai weithio ar y dechrau, ond unwaith y bydd is-gyfrolau nythu, bydd dileu'r is-gyfrol rhiant yn methu. Nid oes gan y modiwl Device Mapper unrhyw ofod enw, felly os yw nifer o achosion Docker yn ei redeg ar yr un peiriant, byddant i gyd yn gallu gweld (a dylanwadu) y delweddau ar ei gilydd ac ar y dyfeisiau wrth gefn cynhwysydd. Mae hyn yn ddrwg.
Mae yna ffyrdd o ddatrys llawer o'r problemau hyn. Er enghraifft, os ydych chi am ddefnyddio AUFS yn Docker mewnol, trowch y ffolder /var/lib/docker yn gyfrol a byddwch yn iawn. Mae Docker wedi ychwanegu rhai gofodau enwau sylfaenol at enwau targed Device Mapper fel, os yw galwadau Docker lluosog yn rhedeg ar yr un peiriant, ni fyddant yn camu ar ei gilydd.
Fodd bynnag, nid yw gosodiad o'r fath yn syml o gwbl, fel y gwelir o'r rhain
Dociwr-yn-Docker: Mae'n gwaethygu
Beth am y storfa adeiladu? Gall hyn fod yn eithaf anodd hefyd. Mae pobl yn aml yn gofyn i mi “os ydw i'n rhedeg Docker-in-Docker, sut alla i ddefnyddio delweddau sy'n cael eu cynnal ar fy gwesteiwr yn lle tynnu popeth yn ôl i'm Dociwr mewnol”?
Mae rhai pobl fentrus wedi ceisio rhwymo /var/lib/docker o'r gwesteiwr i gynhwysydd Docker-in-Docker. Weithiau maen nhw'n rhannu /var/lib/docker gyda chynwysyddion lluosog.
Ydych chi am lygru'ch data? Oherwydd dyma'n union beth fydd yn niweidio'ch data!
Roedd yr ellyll Dociwr yn amlwg wedi'i gynllunio i gael mynediad unigryw i /var/lib/docker. Ni ddylai unrhyw beth arall "gyffwrdd, procio na phrocio" unrhyw ffeiliau Dociwr sydd wedi'u lleoli yn y ffolder hwn.
Pam fod hyn felly? Oherwydd bod hyn yn ganlyniad i un o'r gwersi anoddaf a ddysgwyd wrth ddatblygu dotCloud. Roedd injan cynhwysydd dotCloud yn rhedeg trwy gael prosesau lluosog yn cyrchu /var/lib/dotcloud ar yr un pryd. Nid oedd triciau cyfrwys fel ailosod ffeiliau atomig (yn lle golygu yn ei le), pupuro cod gyda chloeon cynghori a gorfodol, ac arbrofion eraill gyda systemau diogel fel SQLite a BDB bob amser yn gweithio. Pan oeddem yn ailgynllunio ein peiriant cynhwysydd, a ddaeth yn Docker yn y pen draw, un o'r penderfyniadau dylunio mawr oedd cydgrynhoi'r holl weithrediadau cynhwysydd o dan un daemon i gael gwared ar yr holl nonsens arian cyfred.
Peidiwch â fy nghael yn anghywir: mae'n gwbl bosibl gwneud rhywbeth da, dibynadwy a chyflym sy'n cynnwys prosesau lluosog a rheolaeth gyfochrog fodern. Ond rydyn ni'n meddwl ei bod hi'n symlach ac yn haws ysgrifennu a chynnal cod gan ddefnyddio Docker fel yr unig chwaraewr.
Mae hyn yn golygu, os ydych chi'n rhannu'r cyfeiriadur / var / lib / docker rhwng sawl achos Docker, bydd gennych broblemau. Wrth gwrs, gall hyn weithio, yn enwedig yn ystod camau cynnar y profion. “Gwrandewch, Ma, gallaf redeg ubuntu fel dociwr!” Ond rhowch gynnig ar rywbeth mwy cymhleth, fel tynnu'r un ddelwedd o ddau achos gwahanol, a byddwch chi'n gweld y byd yn llosgi.
Mae hyn yn golygu, os yw'ch system CI yn perfformio'n adeiladu ac yn ailadeiladu, bob tro y byddwch chi'n ailgychwyn eich cynhwysydd Docker-in-Docker, rydych chi mewn perygl o ollwng nuke i'w storfa. Nid yw hyn yn cŵl o gwbl!
Yr ateb
Gadewch i ni gymryd cam yn ôl. A oes gwir angen Docker-in-Docker arnoch chi neu a ydych chi eisiau gallu rhedeg Docker ac adeiladu a rhedeg cynwysyddion a delweddau o'ch system CI tra bod y system CI honno ei hun mewn cynhwysydd?
Rwy'n siŵr bod y rhan fwyaf o bobl eisiau'r opsiwn olaf, sy'n golygu eu bod eisiau system CI fel Jenkins i allu rhedeg cynwysyddion. A'r ffordd hawsaf o wneud hyn yw gosod soced Docker yn eich cynhwysydd CI a'i gysylltu â'r faner -v.
Yn syml, pan fyddwch chi'n rhedeg eich cynhwysydd CI (Jenkins neu arall), yn lle hacio rhywbeth ynghyd â Docker-in-Docker, dechreuwch ef gyda'r llinell:
docker run -v /var/run/docker.sock:/var/run/docker.sock ...
Bydd gan y cynhwysydd hwn fynediad at soced y Docker nawr ac felly bydd yn gallu rhedeg cynwysyddion. Ac eithrio yn lle rhedeg cynwysyddion “plentyn”, bydd yn lansio cynwysyddion “siblingiaid”.
Rhowch gynnig ar hyn gan ddefnyddio delwedd swyddogol y docwr (sy'n cynnwys deuaidd y Docker):
docker run -v /var/run/docker.sock:/var/run/docker.sock
-ti docker
Mae'n edrych ac yn gweithio fel Docker-in-Docker, ond nid Docker-in-Docker ydyw: pan fydd y cynhwysydd hwn yn creu cynwysyddion ychwanegol, byddant yn cael eu creu yn y Dociwr lefel uchaf. Ni fyddwch yn profi sgîl-effeithiau nythu a bydd storfa'r cynulliad yn cael ei rannu ar draws galwadau lluosog.
Nodyn: Cynghorodd fersiynau blaenorol o'r erthygl hon gysylltu deuaidd y Docker o'r gwesteiwr i'r cynhwysydd. Mae hyn bellach wedi dod yn annibynadwy gan nad yw injan y Docker bellach yn gorchuddio llyfrgelloedd sefydlog neu bron yn sefydlog.
Felly, os ydych chi am ddefnyddio Docker o Jenkins CI, mae gennych chi 2 opsiwn:
gosod y CLI Docker gan ddefnyddio'r system pecynnu delwedd sylfaenol (h.y. os yw'ch delwedd yn seiliedig ar Debian, defnyddiwch becynnau .deb), gan ddefnyddio'r API Docker.
Rhai hysbysebion 🙂
Diolch am aros gyda ni. Ydych chi'n hoffi ein herthyglau? Eisiau gweld cynnwys mwy diddorol? Cefnogwch ni trwy osod archeb neu argymell i ffrindiau,
Dell R730xd 2 gwaith yn rhatach yng nghanolfan ddata Equinix Haen IV yn Amsterdam? Dim ond yma
Ffynhonnell: hab.com