Ինչպես ես գործարկեցի Docker-ը Docker-ի ներսում և ինչ ստացվեց դրանից

Բարեւ բոլորին! Իր նախորդ հոդվածըԵս խոստացա խոսել Docker-ում Docker-ում գործարկելու և այս դասի օգտագործման գործնական կողմերի մասին: Ժամանակն է պահելու ձեր խոստումը: Փորձառու մշակողը հավանաբար կառարկի, որ նրանք, ովքեր Docker-ի կարիք ունեն Docker-ի ներսում, պարզապես Docker daemon socket-ը հոսթից տեղափոխում են կոնտեյներ, և դա բավարար կլինի 99% դեպքերում: Բայց մի շտապեք ինձ վրա թխուկներ նետել, քանի որ մենք կխոսենք Docker-ի իրական գործարկման մասին Docker-ի ներսում: Այս լուծումը շատ հնարավոր կիրառություններ ունի, և այս հոդվածը դրանցից մեկի մասին է, այնպես որ նստեք և ուղղեք ձեր ձեռքերը ձեր առջև:

Ինչպես ես գործարկեցի Docker-ը Docker-ի ներսում և ինչ ստացվեց դրանից

Начало

Ամեն ինչ սկսվեց սեպտեմբերի մի անձրևոտ երեկոյան, երբ ես մաքրում էի Digital Ocean-ում 5 դոլարով վարձակալածս մեքենան, որը սառեցվել էր այն պատճառով, որ Docker-ը լցրել էր սկավառակի բոլոր 24 գիգաբայթ տարածությունը իր պատկերներով և տարաներով: Զավեշտն այն էր, որ այս բոլոր պատկերներն ու բեռնարկղերը անցողիկ էին և անհրաժեշտ էին միայն իմ հավելվածի աշխատանքը ստուգելու համար ամեն անգամ, երբ թողարկվում էր գրադարանի կամ շրջանակի նոր տարբերակը: Ես փորձեցի գրել shell-ի սկրիպտներ և ստեղծել cron-ի ժամանակացույց՝ աղբը մաքրելու համար, բայց դա չօգնեց. ամեն անգամ դա անխուսափելիորեն ավարտվում էր իմ սերվերի սկավառակի տարածքը խժռելով և սերվերը կախված էր (լավագույն դեպքում): Ինչ-որ պահի ես հանդիպեցի մի հոդվածի այն մասին, թե ինչպես աշխատեցնել Jenkins-ը կոնտեյներով և ինչպես կարող է այն ստեղծել և ջնջել կառուցված խողովակաշարերը դրան փոխանցված docker daemon վարդակի միջոցով: Ինձ դուր եկավ գաղափարը, բայց ես որոշեցի գնալ ավելի հեռու և փորձել փորձարկել Docker-ի ուղղակի գործարկումը Docker-ի ներսում: Այն ժամանակ ինձ միանգամայն տրամաբանական լուծում էր թվում Docker պատկերները ներբեռնելը և այն բոլոր հավելվածների համար կոնտեյներներ ստեղծելը, որոնք ինձ անհրաժեշտ էին մեկ այլ կոնտեյների ներսում փորձարկելու համար (եկեք դա անվանենք բեմականացման կոնտեյներ): Գաղափարն այն էր, որ սկսվի բեմադրող կոնտեյներ -rm դրոշակով, որն ավտոմատ կերպով ջնջում է ամբողջ կոնտեյները և դրա ամբողջ բովանդակությունը, երբ այն դադարեցվում է: Ես շփոթեցի Docker պատկերը հենց Docker-ից (https://hub.docker.com/_/docker), բայց պարզվեց, որ դա չափազանց ծանր էր, և ես երբեք չեմ կարողացել այնպես անել, որ այն աշխատի այնպես, ինչպես պետք է, և ես ինքս ուզում էի մինչև վերջ գնալ:

Պրակտիկա. Կոններ

Ես ձեռնամուխ եղա, որպեսզի բեռնարկղը աշխատի այնպես, ինչպես պետք է, և շարունակեցի իմ փորձերը, որոնց արդյունքում ստացվեցին անհամար բողբոջներ: Իմ ինքնախոշտանգումների արդյունքը հետևյալ ալգորիթմն էր.

  1. Մենք գործարկում ենք Docker կոնտեյները ինտերակտիվ ռեժիմով:

    docker run --privileged -it docker:18.09.6

    Ուշադրություն դարձրեք տարայի տարբերակին, քայլեք աջ կամ ձախ, և ձեր DinD-ը վերածվում է դդմի: Իրականում ամեն ինչ բավականին հաճախ է կոտրվում, երբ թողարկվում է նոր տարբերակը:
    Մենք պետք է անմիջապես մտնենք պատյանի մեջ:

  2. Մենք փորձում ենք պարզել, թե որ կոնտեյներներն են աշխատում (Պատասխան՝ ոչ մեկը), բայց այնուամենայնիվ եկեք գործարկենք հրամանը.

    docker ps

    Դուք մի փոքր կզարմանաք, բայց պարզվում է, որ Docker daemon-ը նույնիսկ չի աշխատում.

    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. Եկեք ինքներս գործարկենք.

    dockerd &

    Մեկ այլ տհաճ անակնկալ.

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

  4. Տեղադրեք iptables և bash փաթեթները (ամեն ինչ ավելի հաճելի է աշխատել bash-ում, քան sh-ում).

    apk add --no-cache iptables bash

  5. Եկեք գործարկենք bash. Վերջապես մենք վերադարձանք սովորական պատյան

  6. Փորձենք նորից սկսել Docker-ը.

    dockerd &

    Մենք պետք է տեսնենք տեղեկամատյանների երկար թերթ, որն ավարտվում է հետևյալով.

    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. Սեղմեք Enter: Մենք վերադարձել ենք բաշի մեջ:

Այսուհետ մենք կարող ենք փորձել գործարկել այլ կոնտեյներներ մեր Docker կոնտեյների ներսում, բայց ի՞նչ, եթե մենք ցանկանում ենք գործարկել մեկ այլ Docker կոնտեյներ մեր Docker կոնտեյների ներսում, կամ ինչ-որ բան սխալ է, և բեռնարկղը խափանում է: Սկսեք ամեն ինչ նորից:

Սեփական DinD կոնտեյներ և նոր փորձեր

Ինչպես ես գործարկեցի Docker-ը Docker-ի ներսում և ինչ ստացվեց դրանից
Վերոհիշյալ քայլերը նորից ու նորից կրկնելուց խուսափելու համար ես ստեղծեցի իմ սեփական DinD կոնտեյները.

https://github.com/alekslitvinenk/dind

Աշխատանքային DinD լուծումն ինձ հնարավորություն տվեց Docker-ը գործարկել Docker-ի ներսում ռեկուրսիվորեն և ավելի արկածային փորձեր անել:
Ես պատրաստվում եմ նկարագրել մի այդպիսի (հաջող) փորձ՝ MySQL-ն ու Nodejs-ը հիմա գործարկելով:
Ամենաանհամբերը տեսնում է, թե ինչպես է այստեղ

Ուստի եկեք սկսենք.

  1. Մենք գործարկում ենք DinD-ը ինտերակտիվ ռեժիմով: DinD-ի այս տարբերակում մենք պետք է ձեռքով քարտեզագրենք բոլոր այն նավահանգիստները, որոնք կարող են օգտագործել մեր մանկական կոնտեյներները (ես արդեն աշխատում եմ դրա վրա)

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

    Մենք մտնում ենք բաշը, որտեղից կարող ենք անմիջապես սկսել մանկական տարաների գործարկումը։

  2. Գործարկել MySQL:

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

  3. Մենք միանում ենք տվյալների շտեմարանին այնպես, ինչպես տեղայնորեն միանում ենք դրան: Եկեք համոզվենք, որ ամեն ինչ աշխատում է:

  4. Գործարկեք երկրորդ կոնտեյները.

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

    Խնդրում ենք նկատի ունենալ, որ նավահանգստի քարտեզագրումը կլինի ճշգրիտ 8080:8080, քանի որ մենք արդեն քարտեզագրել ենք 80 նավահանգիստը հյուրընկալողից մինչև մայր կոնտեյներ 8080 նավահանգստում:

  5. Մենք բրաուզերում գնում ենք localhost, համոզվեք, որ սերվերը պատասխանում է «Բարև աշխարհ»:

Իմ դեպքում, Nested Docker կոնտեյներների հետ փորձը բավականին դրական է ստացվել, և ես կշարունակեմ մշակել նախագիծը և օգտագործել այն բեմադրության համար։ Ինձ թվում է, որ սա շատ ավելի թեթև լուծում է, քան Kubernetes-ը և Jenkins X-ը։ Բայց սա իմ սուբյեկտիվ կարծիքն է։

Կարծում եմ՝ այսքանը այսօրվա հոդվածի համար է: Հաջորդ հոդվածում ես ավելի մանրամասն կնկարագրեմ Docker-ի ռեկուրսիվ կերպով Docker-ում գործարկելու փորձերը և դիրեկտորիաների տեղադրումը խորը տեղադրված բեռնարկղերի մեջ:

PS Եթե ​​կարծում եք, որ այս նախագիծը օգտակար է, խնդրում ենք աստղ տալ GitHub-ում, պատառաքաղել այն և պատմել ձեր ընկերներին:

Edit1- ը Ուղղվել են սխալները՝ կենտրոնացած 2 տեսանյութի վրա

Source: www.habr.com

Добавить комментарий