Paano ko pinatakbo ang Docker sa loob ng Docker at kung ano ang lumabas dito

Kamusta kayong lahat! Sa kanyang nakaraang artikulo, nangako akong pag-usapan ang tungkol sa pagpapatakbo ng Docker sa Docker at ang mga praktikal na aspeto ng paggamit ng araling ito. Oras na para tuparin ang iyong pangako. Ang isang may karanasan na devopser ay malamang na tututol na ang mga nangangailangan ng Docker sa loob ng Docker ay ipasa lamang ang Docker daemon socket mula sa host papunta sa lalagyan at ito ay magiging sapat sa 99% ng mga kaso. Ngunit huwag magmadali upang ihagis sa akin ang mga cookies, dahil pag-uusapan natin ang tungkol sa aktwal na pagpapatakbo ng Docker sa loob ng Docker. Ang solusyon na ito ay maraming posibleng aplikasyon at ang artikulong ito ay tungkol sa isa sa mga ito, kaya umupo at ituwid ang iyong mga braso sa harap mo.

Paano ko pinatakbo ang Docker sa loob ng Docker at kung ano ang lumabas dito

simula

Nagsimula ang lahat sa maulan na gabi ng Setyembre nang nililinis ko ang makina na nirentahan ko sa halagang $5 sa Digital Ocean, na na-freeze dahil sa katotohanang napuno ng Docker ang lahat ng 24 gigabytes ng available na disk space sa mga larawan at lalagyan nito. Ang kabalintunaan ay ang lahat ng mga larawan at lalagyan na ito ay lumilipas at kinakailangan lamang upang subukan ang pagganap ng aking aplikasyon sa tuwing may ilalabas na bagong bersyon ng isang library o framework. Sinubukan kong magsulat ng mga script ng shell at mag-set up ng iskedyul ng cron upang linisin ang basura, ngunit hindi ito nakatulong: sa bawat oras na ito ay hindi maiiwasang magtatapos sa espasyo ng disk ng aking server na kinakain at ang server ay nakabitin (sa pinakamahusay). Sa ilang mga punto, nakatagpo ako ng isang artikulo tungkol sa kung paano patakbuhin ang Jenkins sa isang lalagyan at kung paano ito makakagawa at makakapagtanggal ng mga build pipeline sa pamamagitan ng isang docker daemon socket na ipinapasa dito. Nagustuhan ko ang ideya, ngunit nagpasya akong pumunta pa at subukang mag-eksperimento sa direktang pagpapatakbo ng Docker sa loob ng Docker. Sa oras na iyon, tila sa akin ay isang ganap na lohikal na solusyon upang mag-download ng mga imahe ng Docker at lumikha ng mga lalagyan para sa lahat ng mga application na kailangan ko para sa pagsubok sa loob ng isa pang lalagyan (tawagin natin itong isang lalagyan ng pagtatanghal ng dula). Ang ideya ay upang simulan ang isang pagtatanghal na lalagyan na may -rm flag, na awtomatikong nagde-delete sa buong lalagyan at lahat ng nilalaman nito kapag ito ay tumigil. Pinag-usapan ko ang imahe ng Docker mula sa Docker mismo (https://hub.docker.com/_/docker), ngunit ito ay naging napakahirap at hindi ko kailanman nagawang gawin ito sa paraang kailangan ko at gusto kong pumunta sa lahat ng paraan.

Magsanay. Mga kono

Nagtakda akong gawin ang lalagyan sa paraang kailangan ko at ipinagpatuloy ko ang aking mga eksperimento, na nagresulta sa napakaraming buds. Ang resulta ng aking pagpapahirap sa sarili ay ang sumusunod na algorithm:

  1. Inilunsad namin ang container ng Docker sa interactive na mode.

    docker run --privileged -it docker:18.09.6

    Bigyang-pansin ang bersyon ng lalagyan, hakbang pakanan o pakaliwa at ang iyong DinD ay magiging kalabasa. Sa katunayan, ang mga bagay ay madalas na masira kapag ang isang bagong bersyon ay inilabas.
    Dapat tayong makapasok kaagad sa shell.

  2. Sinusubukan naming malaman kung aling mga lalagyan ang tumatakbo (Sagot: wala), ngunit patakbuhin pa rin natin ang command:

    docker ps

    Medyo magugulat ka, ngunit lumalabas na ang Docker daemon ay hindi pa tumatakbo:

    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. Patakbuhin natin ito sa ating sarili:

    dockerd &

    Isa pang hindi kasiya-siyang sorpresa:

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

  4. I-install ang mga iptable at bash na pakete (lahat ay mas kaaya-aya na magtrabaho sa bash kaysa sa sh):

    apk add --no-cache iptables bash

  5. Ilunsad natin ang bash. Sa wakas ay bumalik na kami sa karaniwang shell

  6. Subukan nating ilunsad muli ang Docker:

    dockerd &

    Dapat nating makita ang isang mahabang sheet ng mga log na nagtatapos sa:

    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. Pindutin ang enter. Balik tayo sa bash.

Mula ngayon, maaari naming subukang maglunsad ng iba pang mga container sa loob ng aming Docker container, ngunit paano kung gusto naming maglunsad ng isa pang Docker container sa loob ng aming Docker container o may magkamali at mag-crash ang container? Magsimula muli.

Sariling lalagyan ng DinD at mga bagong eksperimento

Paano ko pinatakbo ang Docker sa loob ng Docker at kung ano ang lumabas dito
Upang maiwasang maulit ang mga hakbang sa itaas nang paulit-ulit, gumawa ako ng sarili kong lalagyan ng DinD:

https://github.com/alekslitvinenk/dind

Ang gumaganang solusyon sa DinD ay nagbigay sa akin ng kakayahang patakbuhin ang Docker sa loob ng Docker nang recursively at gumawa ng higit pang mga adventurous na eksperimento.
Ilalarawan ko ang isang tulad (matagumpay) na eksperimento sa pagpapatakbo ng MySQL at Nodejs ngayon.
Ang pinaka naiinip ay makikita kung paano ito nangyari dito

Kaya, simulan natin:

  1. Inilunsad namin ang DinD sa interactive na mode. Sa bersyong ito ng DinD, kailangan nating manu-manong imapa ang lahat ng port na magagamit ng ating mga child container (ginagawa ko na ito)

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

    Pumasok kami sa bash, kung saan maaari kaming agad na magsimulang maglunsad ng mga lalagyan ng bata.

  2. Ilunsad ang MySQL:

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

  3. Kumokonekta kami sa database sa parehong paraan tulad ng pagkonekta namin dito nang lokal. Siguraduhin nating gumagana ang lahat.

  4. Ilunsad ang pangalawang lalagyan:

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

    Pakitandaan na ang port mapping ay magiging eksakto 8080:8080, dahil na-map na namin ang port 80 mula sa host patungo sa parent container sa port 8080.

  5. Pumunta kami sa localhost sa browser, siguraduhin na ang server ay tumugon ng "Hello World!"

Sa aking kaso, ang eksperimento sa mga nested Docker container ay naging medyo positibo at ipagpapatuloy ko ang pagbuo ng proyekto at gagamitin ito para sa pagtatanghal. Para sa akin, ito ay isang mas magaan na solusyon kaysa sa Kubernetes at Jenkins X. Ngunit ito ang aking pansariling opinyon.

Sa tingin ko iyon lang ang para sa artikulo ngayong araw. Sa susunod na artikulo ay ilalarawan ko nang mas detalyado ang mga eksperimento sa pagpapatakbo ng Docker nang pabalik-balik sa Docker at pag-mount ng mga direktoryo nang malalim sa mga nested na lalagyan.

PS Kung nakita mong kapaki-pakinabang ang proyektong ito, mangyaring bigyan ito ng bituin sa GitHub, i-fork ito at sabihin sa iyong mga kaibigan.

Edit1 Nawastong mga error, nakatutok sa 2 video

Pinagmulan: www.habr.com

Magdagdag ng komento