CI эсвэл туршилтын орчинд Docker-in-Docker ашиглахаасаа өмнө сайтар бодож үзээрэй

CI эсвэл туршилтын орчинд Docker-in-Docker ашиглахаасаа өмнө сайтар бодож үзээрэй

Docker-in-Docker нь контейнерийн дүрсийг бүтээхийн тулд чингэлэг дотор ажилладаг виртуалчлагдсан Docker дэмон орчин юм. Docker-in-Docker-ийг бүтээх гол зорилго нь Docker-ийг өөрөө хөгжүүлэхэд туслах явдал байв. Олон хүмүүс үүнийг Jenkins CI-г ажиллуулахын тулд ашигладаг. Энэ нь эхэндээ хэвийн мэт санагдах боловч дараа нь Jenkins CI контейнерт Docker суулгаснаар зайлсхийх боломжтой асуудлууд гарч ирдэг. Үүнийг хэрхэн хийх талаар энэ нийтлэл танд хэлэх болно. Хэрэв та нарийн ширийн зүйлгүйгээр эцсийн шийдлийг сонирхож байгаа бол "Асуудлыг шийдвэрлэх нь" нийтлэлийн сүүлчийн хэсгийг уншаарай.

CI эсвэл туршилтын орчинд Docker-in-Docker ашиглахаасаа өмнө сайтар бодож үзээрэй

Docker-in-Docker: "Сайн"

Хоёр жил гаруйн өмнө би Docker-д оруулсан туг – давуу эрхтэй бөгөөд бичсэн dind-ийн анхны хувилбар. Гол зорилго нь Docker-ийг илүү хурдан хөгжүүлэхэд нь туслах явдал байв. Docker-in-Docker-ээс өмнө ердийн хөгжлийн мөчлөг дараах байдалтай байсан.

  • хакердах;
  • барих;
  • ажиллаж байгаа Docker демоныг зогсоох;
  • шинэ Docker дэмоныг эхлүүлэх;
  • туршилт хийх;
  • мөчлөгийг давт.

Хэрэв та үзэсгэлэнтэй, хуулбарлах боломжтой угсралт хийхийг хүсч байвал (өөрөөр хэлбэл саванд) энэ нь илүү төвөгтэй болсон.

  • хакердах;
  • Docker-ийн ажиллаж байгаа хувилбар ажиллаж байгаа эсэхийг шалгах;
  • хуучин Docker ашиглан шинэ Docker бүтээх;
  • Docker дэмоныг зогсоох;
  • шинэ Docker демоныг эхлүүлэх;
  • туршилт;
  • шинэ Docker дэмоныг зогсоох;
  • давтана.

Docker-in-Docker гарч ирснээр үйл явц илүү хялбар болсон:

  • хакердах;
  • угсралт + нэг үе шатанд хөөргөх;
  • мөчлөгийг давт.

Энэ нь хамаагүй дээр биш гэж үү?

CI эсвэл туршилтын орчинд Docker-in-Docker ашиглахаасаа өмнө сайтар бодож үзээрэй

Docker-in-Docker: "Муу"

Гэсэн хэдий ч түгээмэл итгэл үнэмшлийн эсрэг Docker-in-Docker бол 100% од, одой морь, ганц эвэрт биш юм. Би юу хэлэх гээд байна вэ гэвэл хөгжүүлэгчийн анхаарах ёстой хэд хэдэн асуудал байдаг.

Тэдгээрийн нэг нь AppArmor болон SELinux зэрэг LSM (Linux аюулгүй байдлын модулиуд)-тай холбоотой: контейнер ажиллуулж байх үед "дотоод Докер" нь "гадаад 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 instances үүнийг нэг машин дээр ажиллуулж байгаа бол тэд бүгд бие биенээсээ болон контейнер нөөцлөх төхөөрөмж дээрх зургуудыг харах (мөн нөлөөлөх) боломжтой болно. Энэ муу байна.

Эдгээр олон асуудлыг шийдвэрлэх арга замууд байдаг. Жишээлбэл, хэрэв та дотоод Docker-д AUFS ашиглахыг хүсвэл /var/lib/docker хавтсыг боть болгон хувиргавал зүгээр. Докер нь Device Mapper зорилтот нэрүүдэд зарим үндсэн нэрийн орон зайг нэмсэн бөгөөд хэрэв олон Docker дуудлага нэг машин дээр ажиллаж байгаа бол тэдгээр нь бие биен дээрээ гишгэхгүй байх болно.

Гэсэн хэдий ч ийм тохиргоо нь тийм ч энгийн зүйл биш бөгөөд үүнийг эдгээрээс харж болно нийтлэл GitHub дээрх dind репозитор дээр.

Docker-in-Docker: Энэ нь улам дорддог

Бүтээлийн кэшийн талаар юу хэлэх вэ? Энэ нь бас нэлээд хэцүү байж болно. Хүмүүс надаас "Хэрэв би Docker-in-Docker ажиллуулж байгаа бол бүх зүйлийг өөрийн дотоод 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-ийг цорын ганц тоглогч болгон ашиглан код бичиж, засварлахад илүү хялбар бөгөөд хялбар гэж бодож байна.

Энэ нь хэрэв та /var/lib/docker санг олон Docker instance хооронд хуваалцвал асуудал гарна гэсэн үг. Мэдээжийн хэрэг, энэ нь ялангуяа туршилтын эхний шатанд ажиллах боломжтой. "Сонсоорой, ээж ээ, би ubuntu-г докероор ажиллуулж чадна!" Гэхдээ нэг зургийг хоёр өөр тохиолдлоос татах гэх мэт илүү төвөгтэй зүйлийг туршиж үзээрэй, тэгвэл та дэлхий шатаж байгааг харах болно.

Энэ нь хэрвээ таны CI систем бүтээж, дахин бүтээж байгаа бол Docker-in-Docker контейнерээ дахин эхлүүлэх бүрд та түүний кэш рүү цөмийн зэвсгийг хаях эрсдэлтэй гэсэн үг юм. Энэ огт дажгүй биш!

Алдааг олж засварлах

Нэг алхам ухрацгаая. Танд үнэхээр Docker-in-Docker хэрэгтэй байна уу эсвэл CI систем өөрөө контейнер дотор байх үед Docker-ийг ажиллуулж, CI системээсээ контейнер, дүрс бүтээж, ажиллуулмаар байна уу?

Ихэнх хүмүүс Женкинс шиг CI системийг чингэлэг ажиллуулах чадвартай болгохыг хүсдэг гэсэн үг. Үүнийг хийх хамгийн хялбар арга бол зүгээр л Docker залгуурыг өөрийн CI контейнерт оруулаад -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-г суулгах.

Зарим зар 🙂

Бидэнтэй хамт байсанд баярлалаа. Манай нийтлэл танд таалагдаж байна уу? Илүү сонирхолтой контент үзэхийг хүсч байна уу? Захиалга өгөх эсвэл найзууддаа санал болгох замаар биднийг дэмжээрэй, 4.99 доллараас эхлэн хөгжүүлэгчдэд зориулсан үүлэн VPS, Бидний танд зориулж бүтээсэн анхны түвшний серверүүдийн өвөрмөц аналоги: VPS (KVM) E5-2697 v3 (6 цөм) 10GB DDR4 480GB SSD 1Gbps-ийн 19 ам.долларын үнэ эсвэл серверийг хэрхэн хуваалцах тухай бүх үнэн үү? (RAID1 болон RAID10, 24 хүртэлх цөм, 40 ГБ хүртэл DDR4-тэй байх боломжтой).

Амстердам дахь Equinix Tier IV дата төвд Dell R730xd 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 сервер ашиглах анги?

Эх сурвалж: www.habr.com

сэтгэгдэл нэмэх