CI үчүн Docker-in-Docker же сыноо чөйрөсүн колдонуудан мурун жакшылап ойлонуңуз

CI үчүн Docker-in-Docker же сыноо чөйрөсүн колдонуудан мурун жакшылап ойлонуңуз

Docker-in-Docker - бул контейнер сүрөттөрүн түзүү үчүн контейнердин ичинде иштеген виртуалдаштырылган Docker демон чөйрөсү. Docker-in-Docker түзүүнүн негизги максаты Докердин өзүн өнүктүрүүгө жардам берүү болгон. Көптөр аны Jenkins CI иштетүү үчүн колдонушат. Бул адегенде кадимкидей сезилет, бирок кийин Dockerди Jenkins CI контейнерине орнотуу менен болтурбоо мүмкүн болгон көйгөйлөр пайда болот. Бул макалада муну кантип жасоо керектиги айтылат. Эгер сизди чоо-жайы жок акыркы чечим кызыктырса, жөн гана макаланын акыркы бөлүмүн окуп чыгыңыз, "Маселени чечүү."

CI үчүн Docker-in-Docker же сыноо чөйрөсүн колдонуудан мурун жакшылап ойлонуңуз

Docker-in-Docker: "Жакшы"

Эки жылдан ашык убакыт мурун мен Докерге киргиздим желек – артыкчылыктуу жана жазган диндин биринчи версиясы. Максаты негизги командага Докерди тезирээк өнүктүрүүгө жардам берүү болгон. Docker-in-Dockerге чейин типтүү иштеп чыгуу цикли төмөнкүдөй болгон:

  • hackity hack;
  • куруу;
  • иштеп жаткан Docker демонун токтотуу;
  • жаңы Docker демонун ишке киргизүү;
  • тестирлөө;
  • циклди кайталаъыз.

Эгер сиз кооз, кайталануучу жыйынды (б.а. контейнерде) жасагыңыз келсе, анда ал татаалыраак болуп калды:

  • hackity hack;
  • Dockerдин жумушчу версиясы иштеп жатканын текшериңиз;
  • эски Докер менен жаңы Докерди куруу;
  • Docker демонун токтотуу;
  • жаңы Docker демонун баштоо;
  • сыноо;
  • жаңы Docker демонун токтотуу;
  • кайталоо.

Docker-in-Dockerдин пайда болушу менен процесс жөнөкөйлөштү:

  • hackity hack;
  • чогултуу + бир этапта ишке киргизүү;
  • циклди кайталаъыз.

Бул жакшыраак эмеспи?

CI үчүн Docker-in-Docker же сыноо чөйрөсүн колдонуудан мурун жакшылап ойлонуңуз

Docker-in-Docker: "Жаман"

Бирок, популярдуу ишенимге карама-каршы, Docker-in-Docker 100% жылдыздар, пони жана бир мүйүздүү эмес. Дегеним, иштеп чыгуучу билиши керек болгон бир нече маселелер бар.

Алардын бири AppArmor жана SELinux сыяктуу LSMдерге (Linux коопсуздук модулдарына) тиешелүү: контейнерди иштетип жатканда, "ички Докер" "тышкы Докерди" чаташтыра турган же чаташтыра турган коопсуздук профилдерин колдонууга аракет кылышы мүмкүн. Бул – артыкчылыктуу желектин баштапкы аткарылышын бириктирүүгө аракет кылганда чечүү үчүн эң кыйын маселе. Менин өзгөртүүлөрүм иштеди жана бардык тесттер менин Debian машинамда жана Ubuntu тесттик VM'леримде өтмөк, бирок алар Майкл Кросбинин машинасында бузулуп, күйүп кетчү (мен эсимде ал Fedora болгон). Мен көйгөйдүн так себебин эстей албайм, бирок Майк SELINUX=enforce менен иштеген акылдуу жигит болгондуктан (мен AppArmor колдондум) жана менин өзгөртүүлөрүм SELinux профилдерин эске албагандыктан болушу мүмкүн.

Докер-ин-Докер: "Жаман"

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

Эгер сиз BTRFSти BTRFS үстүнө иштетсеңиз, анда ал алгач иштеши керек, бирок уя салынган подтомдор болгондон кийин, ата-энелик подтомду жок кылуу ишке ашпай калат. Түзмөк картасынын модулунун ат мейкиндиги жок, андыктан бир нече Docker инстанциялары аны бир эле машинада иштетип жатса, алардын баары бири-бирине жана контейнердин резервдик көчүрмөлөрүндөгү сүрөттөрдү көрө алышат (жана таасир этет). Бул жаман.

Бул көйгөйлөрдүн көбүн чечүү үчүн жолдор бар. Мисалы, эгер сиз AUFSди ички Dockerде колдонгуңуз келсе, жөн гана /var/lib/docker папкасын томго айландырсаңыз, анда баары жакшы болот. Docker бир нече Docker чалуулары бир эле машинада иштесе, алар бири-бирин басып калбашы үчүн, Түзмөк Картачынын максаттуу аталыштарына кээ бир негизги аттар мейкиндиктерин кошту.

Бирок, булардан көрүнүп тургандай, мындай орнотуу жөнөкөй эмес макалалар GitHubдагы dind репозиторийинде.

Docker-in-Docker: Бул начарлап баратат

Куруу кэш жөнүндө эмне айтууга болот? Бул да абдан кыйын болушу мүмкүн. Адамдар менден көп сурашат: "Эгер мен Docker-in-Dockerди иштетип жатсам, бардыгын ички Докерге кайра тартпай, хостумда жайгаштырылган сүрөттөрдү кантип колдоно алам"?

Кээ бир демилгелүү адамдар /var/lib/dockerди хосттон Docker-in-Docker контейнерине байлаганга аракет кылышкан. Кээде алар /var/lib/docker бир нече контейнерлер менен бөлүшүшөт.

CI үчүн Docker-in-Docker же сыноо чөйрөсүн колдонуудан мурун жакшылап ойлонуңуз
Дайындарыңызды бузуп салгыңыз келеби? Анткени бул сиздин маалыматтарыңызга зыян келтирет!

Docker демону /var/lib/dockerге эксклюзивдүү жетүү үчүн иштелип чыккан. Бул папкада жайгашкан Docker файлдарын башка эч нерсе "тийбеши, тиштеп же түртпөшү" керек.

Эмне үчүн мындай? Анткени бул dotCloud иштеп чыгууда алынган эң оор сабактардын биринин натыйжасы. DotCloud контейнер кыймылдаткычы бир эле убакта /var/lib/dotcloud кирүүчү бир нече процесстерге ээ болуу менен иштеген. Атомдук файлдарды алмаштыруу (ордуна оңдоонун ордуна), кеңеш берүүчү жана милдеттүү кулпулары бар калемпир коддору жана SQLite жана BDB сыяктуу коопсуз системалар менен болгон башка эксперименттер сыяктуу куу трюктар дайыма эле натыйжа берген эмес. Контейнердик кыймылдаткычыбызды кайра конструкциялап жатканыбызда, ал акырында Докер болуп калды, чоң дизайн чечимдеринин бири бардык конкуренциялык тантырактарды жок кылуу үчүн бардык контейнер операцияларын бир демонго бириктирүү болду.

Мени жаңылыштырбаңыз: бир нече процессти жана заманбап параллелдүү башкарууну камтыган жакшы, ишенимдүү жана тез нерсени жасоо толук мүмкүн. Бирок биз 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 кыймылдаткычы мындан ары статикалык же жакын статикалык китепканаларды камтыбайт.

Ошентип, эгер сиз Jenkins CIден Docker колдонгуңуз келсе, сизде 2 вариант бар:
негизги сүрөттөрдү таңгактоо тутумун колдонуу менен Docker CLI орнотуу (б.а. сүрөтүңүз Debianга негизделген болсо, .deb пакеттерин колдонуңуз), Docker API аркылуу.

Кээ бир жарнамалар 🙂

Биз менен болгонуңуз үчүн рахмат. Биздин макалалар сизге жагабы? Көбүрөөк кызыктуу мазмунду көргүңүз келеби? Буйрутма берүү же досторуңузга сунуштоо менен бизди колдоңуз, иштеп чыгуучулар үчүн булут 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.6GHz 14C 64GB DDR4 4x960GB SSD 1Gbps 100 ТВ 199 доллардан баштап Нидерландыда! Dell R420 - 2x E5-2430 2.2Ghz 6C 128GB DDR3 2x960GB SSD 1Gbps 100TB - 99 доллардан! Жөнүндө окуу Инфраструктураны кантип куруу керек. бир тыйынга 730 евро турган Dell R5xd E2650-4 v9000 серверлерин колдонуу менен класс?

Source: www.habr.com

Комментарий кошуу