Kiel mi kuris Docker en Docker kaj kio eliris el ĝi

Saluton al ĉiuj! En lia antaŭa artikolo, Mi promesis paroli pri rulado de Docker en Docker kaj la praktikaj aspektoj de uzado de ĉi tiu leciono. Estas tempo plenumi vian promeson. Sperta devopser verŝajne kontraŭos, ke tiuj, kiuj bezonas Docker ene de Docker, simple plusendas la Docker-demon-ingon de la gastiganto en la ujon kaj tio sufiĉos en 99% de kazoj. Sed ne rapidu ĵeti kuketojn al mi, ĉar ni parolos pri efektive ruli Docker ene de Docker. Ĉi tiu solvo havas multajn eblajn aplikojn kaj ĉi tiu artikolo temas pri unu el ili, do sidiĝu kaj rektigu viajn brakojn antaŭ vi.

Kiel mi kuris Docker en Docker kaj kio eliris el ĝi

Начало

Ĉio komenciĝis en pluva septembra vespero, kiam mi purigis la maŝinon, kiun mi luis por $5 sur Digital Ocean, kiu estis frostigita pro la fakto, ke Docker plenigis ĉiujn 24 gigabajtojn da disponebla diskospaco per siaj bildoj kaj ujoj. La ironio estis, ke ĉiuj ĉi tiuj bildoj kaj ujoj estis pasemaj kaj estis bezonataj nur por testi la agadon de mia aplikaĵo ĉiufoje kiam nova versio de biblioteko aŭ kadro estis publikigita. Mi provis skribi ŝelajn skriptojn kaj agordi cron-horaron por purigi rubon, sed ĝi ne helpis: ĉiufoje ĝi neeviteble finiĝis kun la diskospaco de mia servilo manĝita kaj la servilo pendanta (en la plej bona kazo). Iam, mi trovis artikolon pri kiel ruli Jenkins en ujo kaj kiel ĝi povas krei kaj forigi konstruajn duktoj per docker-demono-ingo plusendita en ĝin. Mi ŝatis la ideon, sed mi decidis iri plu kaj provi eksperimenti rekte ruli Docker ene de Docker. Tiutempe ŝajnis al mi tute logika solvo elŝuti Docker-bildojn kaj krei ujojn por ĉiuj aplikaĵoj, kiujn mi bezonis por provi ene de alia ujo (ni nomu ĝin staging-ujo). La ideo estis komenci aranĝan ujon kun la flago -rm, kiu aŭtomate forigas la tutan ujon kaj ĝian tutan enhavon kiam ĝi estas haltigita. Mi tuŝis la bildon de Docker de Docker mem (https://hub.docker.com/_/docker), sed ĝi montriĝis tro maloportuna kaj mi neniam sukcesis igi ĝin funkcii kiel mi bezonis ĝin kaj mi volis iri la tutan vojon mem.

Praktiko. Konusoj

Mi komencis igi la ujon funkcii kiel mi bezonis kaj daŭrigis miajn eksperimentojn, kiuj rezultigis miriadon da burĝonoj. La rezulto de mia mem-torturo estis la sekva algoritmo:

  1. Ni lanĉas la Docker-ujon en interaga reĝimo.

    docker run --privileged -it docker:18.09.6

    Atentu la version de la ujo, paŝu dekstren aŭ maldekstren kaj via DinD fariĝas kukurbo. Fakte, aferoj rompiĝas sufiĉe ofte kiam nova versio estas publikigita.
    Ni devas tuj eniri la ŝelon.

  2. Ni provas eltrovi, kiuj ujoj funkcias (Respondo: neniu), sed ni rulu la komandon ĉiukaze:

    docker ps

    Vi estos iomete surprizita, sed rezultas, ke la Docker-demono eĉ ne funkcias:

    error during connect: Get http://docker:2375/v1.40/containers/json: dial tcp: lookup docker on 
    192.168.65.1:53: no such host

  3. Ni mem ekzercu ĝin:

    dockerd &

    Alia malagrabla surprizo:

    failed to start daemon: Error initializing network controller: error obtaining controller instance: failed 
    to create NAT chain DOCKER: Iptables not found

  4. Instalu la iptables kaj bash-pakaĵojn (ĉio estas pli agrable labori en bash ol en sh):

    apk add --no-cache iptables bash

  5. Ni lanĉu bash. Fine ni estas reen en la kutima ŝelo

  6. Ni provu ruli Docker denove:

    dockerd &

    Ni devus vidi longan folion de protokoloj finiĝantaj per:

    INFO[2019-11-25T19:51:19.448080400Z] Daemon has completed initialization          
    INFO[2019-11-25T19:51:19.474439300Z] API listen on /var/run/docker.sock

  7. Premu Enigu. Ni revenis en la baton.

De nun ni povas provi lanĉi aliajn ujojn ene de nia Docker-ujo, sed kio se ni volas lanĉi alian Docker-ujon ene de nia Docker-ujo aŭ io misfunkcias kaj la ujo kraŝas? Komencu ĉion denove.

Propra DinD-ujo kaj novaj eksperimentoj

Kiel mi kuris Docker en Docker kaj kio eliris el ĝi
Por eviti ripeti la suprajn paŝojn denove kaj denove, mi kreis mian propran DinD-ujon:

https://github.com/alekslitvinenk/dind

La funkcianta solvo DinD donis al mi la kapablon ruli Docker ene de Docker rekursie kaj fari pli aventurajn eksperimentojn.
Mi priskribos tian (sukcesan) eksperimenton pri rulado de MySQL kaj Nodejs nun.
La plej senpaciencaj povas vidi kiel estis ĉi tie

Do ni komencu:

  1. Ni lanĉas DinD en interaga reĝimo. En ĉi tiu versio de DinD, ni devas mane mapi ĉiujn havenojn, kiujn niaj infanaj ujoj povas uzi (mi jam laboras pri tio)

    docker run --privileged -it 
    -p 80:8080 
    -p 3306:3306 
    alekslitvinenk/dind

    Ni eniras la baton, de kie ni povas tuj komenci lanĉi infanajn ujojn.

  2. Lanĉu MySQL:

    docker run --name mysql -e MYSQL_ROOT_PASSWORD=strongpassword -d -p 3306:3306 mysql

  3. Ni konektas al la datumbazo same kiel ni konektus al ĝi loke. Ni certigu, ke ĉio funkcias.

  4. Lanĉu la duan ujon:

    docker run -d --rm -p 8080:8080 alekslitvinenk/hello-world-nodejs-server

    Bonvolu noti, ke la havenomapado estos ĝuste 8080:8080, ĉar ni jam mapis la havenon 80 de la gastiganto al la gepatra ujo al la haveno 8080.

  5. Ni iras al localhost en la retumilo, certigu, ke la servilo respondas "Saluton Mondo!"

En mia kazo, la eksperimento kun nestitaj Docker-ujoj montriĝis sufiĉe pozitiva kaj mi daŭre disvolvos la projekton kaj uzos ĝin por enscenigo. Ŝajnas al mi, ke ĉi tio estas multe pli malpeza solvo ol Kubernetes kaj Jenkins X. Sed ĉi tio estas mia subjektiva opinio.

Mi pensas, ke tio estas ĉio por la hodiaŭa artikolo. En la sekva artikolo mi priskribos pli detale eksperimentojn pri rulado de Docker rekursie en Docker kaj muntado de dosierujoj profunde en nestitajn ujojn.

PS Se vi trovas ĉi tiun projekton utila, bonvolu doni al ĝi stelon en GitHub, forku ĝin kaj diru al viaj amikoj.

Redakti1 Korektitaj eraroj, koncentritaj al 2 filmetoj

fonto: www.habr.com

Aldoni komenton