Docker-in-Docker for CI немесе сынақ ортасын қолданбас бұрын мұқият ойластырыңыз

Docker-in-Docker for CI немесе сынақ ортасын қолданбас бұрын мұқият ойластырыңыз

Docker-in-Docker — контейнер кескіндерін құру үшін контейнердің өзінде жұмыс істейтін виртуалдандырылған Docker демон ортасы. Docker-in-Docker құрудың негізгі мақсаты Докердің өзін дамытуға көмектесу болды. Көптеген адамдар оны Jenkins CI іске қосу үшін пайдаланады. Бұл бастапқыда қалыпты болып көрінеді, бірақ содан кейін Jenkins CI контейнеріне Docker орнату арқылы болдырмауға болатын мәселелер туындайды. Бұл мақалада мұны қалай істеу керектігі айтылады. Егер сізді егжей-тегжейсіз түпкілікті шешім қызықтырса, мақаланың «Мәселені шешу» соңғы бөлімін оқыңыз.

Docker-in-Docker for CI немесе сынақ ортасын қолданбас бұрын мұқият ойластырыңыз

Docker-in-Docker: «Жақсы»

Екі жылдан астам уақыт бұрын мен Docker-ге енгіздім жалауша – артықшылықты және жазған dind бірінші нұсқасы. Мақсаты негізгі командаға Docker-ді тезірек дамытуға көмектесу болды. Docker-in-Docker-ге дейін әдеттегі әзірлеу циклі келесідей болды:

  • бұзу бұзу;
  • салу;
  • жұмыс істеп тұрған Docker демонын тоқтату;
  • жаңа Docker демонын іске қосу;
  • тестілеу;
  • циклды қайталаңыз.

Егер сіз әдемі, қайталанатын жинақ жасағыңыз келсе (яғни контейнерде), онда ол күрделірек болды:

  • бұзу бұзу;
  • Docker жұмыс нұсқасының жұмыс істеп тұрғанына көз жеткізіңіз;
  • ескі Docker көмегімен жаңа Docker құрастыру;
  • Docker демонын тоқтату;
  • жаңа Docker демонын іске қосыңыз;
  • сынақ;
  • жаңа Docker демонын тоқтату;
  • қайталаңыз.

Docker-in-Docker пайда болуымен процесс оңайырақ болды:

  • бұзу бұзу;
  • құрастыру + бір кезеңде іске қосу;
  • циклды қайталаңыз.

Бұл әлдеқайда жақсы емес пе?

Docker-in-Docker for CI немесе сынақ ортасын қолданбас бұрын мұқият ойластырыңыз

Docker-in-Docker: «Нашар»

Дегенмен, танымал нанымға қарамастан, Docker-in-Docker 100% жұлдыздар, понилар және бір мүйізділер емес. Менің айтқым келгені, әзірлеуші ​​білуі керек бірнеше мәселелер бар.

Олардың бірі AppArmor және SELinux сияқты LSM-ге (Linux қауіпсіздік модульдері) қатысты: контейнерді іске қосқан кезде «ішкі Docker» «сыртқы Docker-ке» қайшы келетін немесе шатастыратын қауіпсіздік профильдерін қолдануға тырысуы мүмкін. Бұл – артықшылықты жалаушаның бастапқы іске асырылуын біріктіруге тырысқанда шешуге болатын ең қиын мәселе. Менің өзгертулерім жұмыс істеді және барлық сынақтар менің Debian машинам мен Ubuntu сынақ VM-де өтеді, бірақ олар Майкл Кросбидің машинасында бұзылып, күйіп кетеді (есімде оның Fedora болған). Мен мәселенің нақты себебін есіме түсіре алмаймын, бірақ Майктың SELINUX=enforce (мен AppArmor қолдандым) жұмыс істейтін дана жігіт болғандықтан болуы мүмкін және менің өзгертулерім SELinux профильдерін есепке алмаған.

Docker-in-Docker: «Зұлымдық»

Екінші мәселе Docker сақтау драйверлеріне қатысты. Docker-in-Docker іске қосылғанда, сыртқы Docker кәдімгі файлдық жүйенің (EXT4, BTRFS немесе сізде бар нәрсе) үстінде жұмыс істейді және ішкі Docker жазуға көшіру жүйесінің (AUFS, BTRFS, Device Mapper) үстінде жұмыс істейді. және т.б.). , сыртқы Docker пайдалану үшін конфигурацияланған нәрсеге байланысты). Бұл жұмыс істемейтін көптеген комбинацияларды жасайды. Мысалы, AUFS үстінен AUFS іске қоса алмайсыз.

BTRFS-ті BTRFS үстіне іске қоссаңыз, ол алдымен жұмыс істеуі керек, бірақ кірістірілген ішкі томдар болған кезде, негізгі ішкі томды жою сәтсіз болады. Device Mapper модулінде аттар кеңістігі жоқ, сондықтан бірнеше Docker даналары оны бір құрылғыда іске қосса, олардың барлығы бір-бірінен және контейнерлік сақтық көшірме құрылғыларындағы кескіндерді көре (және әсер ете алады). Бұл жаман.

Осы мәселелердің көпшілігін шешу үшін уақытша шешімдер бар. Мысалы, ішкі Docker-де AUFS пайдаланғыңыз келсе, жай ғана /var/lib/docker қалтасын томға айналдырыңыз, сонда бәрі жақсы болады. Docker бірнеше негізгі аттар кеңістігін Device Mapper мақсатты атауларына қосты, осылайша бірнеше Docker қоңыраулары бір құрылғыда жұмыс істеп тұрса, олар бір-біріне баспайды.

Дегенмен, мұндай орнату оңай емес, мұны мыналардан көруге болады мақалалар GitHub сайтындағы dind репозиторийінде.

Docker-in-Docker: Ол нашарлайды

Құрастыру кэші туралы не деуге болады? Бұл да өте қиын болуы мүмкін. Адамдар маған жиі сұрайды: «Егер мен Docker-in-Docker-ді іске қоссам, барлығын ішкі Docker-ке қайтарудың орнына хостымда орналастырылған кескіндерді қалай пайдалануға болады?»

Кейбір іскер адамдар /var/lib/docker файлын хосттан Docker-in-Docker контейнеріне байланыстыруға тырысты. Кейде олар /var/lib/docker файлын бірнеше контейнермен бөліседі.

Docker-in-Docker for CI немесе сынақ ортасын қолданбас бұрын мұқият ойластырыңыз
Деректеріңізді бүлдіргіңіз келе ме? Өйткені бұл сіздің деректеріңізге зиян келтіретін нәрсе!

Docker демоны /var/lib/docker қолданбасына эксклюзивті қол жеткізу үшін нақты жасалған. Осы қалтада орналасқан кез келген Docker файлдарын басқа ешнәрсе «түртуге, соғуға немесе шығаруға» болмайды.

Неліктен бұлай? Өйткені бұл dotCloud әзірлеу кезінде алынған ең қиын сабақтардың бірінің нәтижесі. DotCloud контейнерлік қозғалтқышы /var/lib/dotcloud бір уақытта қатынасатын бірнеше процестер арқылы жұмыс істеді. Атомдық файлдарды ауыстыру (орнында өңдеудің орнына), кеңес беретін және міндетті құлыптары бар бұрыштық код және SQLite және BDB сияқты қауіпсіз жүйелермен басқа эксперименттер сияқты айла-амалдар әрқашан нәтиже бермеді. Біз контейнерлік қозғалтқышты қайта жобалаған кезде, ол ақырында Docker болды, үлкен дизайн шешімдерінің бірі барлық параллельдік сандырақтарды жою үшін барлық контейнерлік операцияларды бір демон астында біріктіру болды.

Мені қате түсінбеңіз: көптеген процестерді және заманауи параллель басқаруды қамтитын жақсы, сенімді және жылдам нәрсені жасауға әбден болады. Бірақ Docker-ті жалғыз ойыншы ретінде пайдалану арқылы кодты жазу және қолдау оңайырақ және оңай деп ойлаймыз.

Бұл бірнеше Docker даналары арасында /var/lib/docker каталогын ортақ пайдалансаңыз, сізде қиындықтар туындайтынын білдіреді. Әрине, бұл жұмыс істей алады, әсіресе тестілеудің бастапқы кезеңдерінде. «Тыңдашы, ана, мен ubuntu-ны докер ретінде басқара аламын!» Бірақ бір суретті екі түрлі жағдайдан алу сияқты күрделірек нәрсені қолданып көріңіз, сонда сіз әлемнің жанып жатқанын көресіз.

Бұл сіздің CI жүйеңіз құрастырулар мен қайта құруларды орындаса, Docker-in-Docker контейнерін қайта іске қосқан сайын оның кэшіне ядролық қаруды тастау қаупі бар дегенді білдіреді. Бұл мүлдем тамаша емес!

сөйлеген сөзінде

Бір қадам артқа шегінейік. Сізге шынымен Docker-in-Docker керек пе, әлде жай ғана Docker бағдарламасын іске қосып, CI жүйесінің өзі контейнерде болған кезде CI жүйесінен контейнерлер мен кескіндерді құрастырып, іске қосқыңыз келе ме?

Көптеген адамдар соңғы опцияны қалайтынына сенімдімін, яғни олар Дженкинс сияқты CI жүйесінің контейнерлерді іске қосу мүмкіндігін қалайды. Мұны істеудің ең оңай жолы - CI контейнеріне Docker ұяшығын енгізу және оны -v жалаушасымен байланыстыру.

Қарапайым тілмен айтқанда, CI контейнерін (Джэнкинс немесе басқа) іске қосқанда, Docker-in-Docker-пен бірге бірдеңені бұзудың орнына, оны келесі жолдан бастаңыз:

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

Бұл контейнер енді Docker ұясына қол жеткізе алады, сондықтан контейнерлерді іске қоса алады. «Бала» контейнерлерін іске қосудың орнына «аға» контейнерлерін іске қосады.

Мұны ресми докер кескінін пайдаланып көріңіз (онда Docker екілік файлы бар):

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

Ол Docker-in-Docker сияқты көрінеді және жұмыс істейді, бірақ ол Docker-in-Docker емес: бұл контейнер қосымша контейнерлерді жасағанда, олар жоғары деңгейлі Docker бағдарламасында жасалады. Ұя салудың жанама әсерлерін көрмейсіз және жинақ кэші бірнеше қоңыраулар арқылы ортақ болады.

Ескерту: Осы мақаланың алдыңғы нұсқаларында Docker екілік файлын хосттан контейнерге байланыстыру ұсынылады. Бұл енді сенімсіз болды, өйткені Docker қозғалтқышы енді статикалық немесе статикалыққа жақын кітапханаларды қамтымайды.

Сонымен, егер сіз Jenkins CI ұсынған Docker қолданбасын пайдаланғыңыз келсе, сізде 2 опция бар:
Docker API арқылы негізгі кескінді орау жүйесін (яғни, сіздің суретіңіз Debian негізінде болса, .deb бумаларын пайдаланыңыз) арқылы Docker CLI орнату.

Кейбір жарнамалар 🙂

Бізбен бірге болғандарыңызға рахмет. Сізге біздің мақалалар ұнайды ма? Қызықты мазмұнды көргіңіз келе ме? Тапсырыс беру немесе достарыңызға ұсыну арқылы бізге қолдау көрсетіңіз, әзірлеушілерге арналған бұлтты VPS $4.99, Сіз үшін біз ойлап тапқан бастапқы деңгейдегі серверлердің бірегей аналогы: VPS (KVM) E5-2697 v3 (6 ядросы) 10 ГБ DDR4 480 ГБ SSD 1 Гбит/с 19 доллардан немесе серверді қалай бөлісуге болатыны туралы барлық шындық? (RAID1 және RAID10, 24 ядроға дейін және 40 ГБ DDR4 дейін қол жетімді).

Dell R730xd Амстердамдағы Equinix Tier IV деректер орталығында 2 есе арзан ба? Тек осында 2 x Intel TetraDeca-Core Xeon 2x E5-2697v3 2.6 ГГц 14C 64 ГБ DDR4 4x960 ГБ SSD 1 Гбит/с 100 теледидар 199 доллардан бастап Нидерландыда! Dell R420 - 2x E5-2430 2.2 ГГц 6C 128 ГБ DDR3 2x960 ГБ SSD 1 Гбит/с 100 ТБ - 99 доллардан бастап! туралы оқыңыз Инфрақұрылымдық корпорацияны қалай құруға болады. бір тиынға 730 еуро тұратын Dell R5xd E2650-4 v9000 серверлерін қолданатын класс?

Ақпарат көзі: www.habr.com

пікір қалдыру