
Docker-in-Docker, konteyner şəkillərini yaratmaq üçün konteynerin özündə işləyən virtuallaşdırılmış Docker demon mühitidir. Docker-in-Docker-in yaradılmasının əsas məqsədi Docker-in özünü inkişaf etdirməyə kömək etmək idi. Bir çox insan ondan Jenkins CI-ni idarə etmək üçün istifadə edir. Bu, ilk baxışdan normal görünür, lakin sonra Jenkins CI konteynerində Docker-i quraşdırmaqla qarşısını almaq mümkün olan problemlər yaranır. Bu məqalə sizə bunu necə edəcəyinizi izah edir. Əgər təfərrüatsız yekun həll yolu ilə maraqlanırsınızsa, məqalənin son bölməsini oxuyun, “Problemin həlli”.

Docker-in-Docker: "Yaxşı"
İki ildən çox əvvəl Docker-ə daxil etdim – imtiyazlı və yazdı . Məqsəd əsas komandaya Docker-i daha sürətli inkişaf etdirməyə kömək etmək idi. Docker-in-Docker-dən əvvəl tipik inkişaf dövrü belə görünürdü:
- hackity hack;
- qurmaq;
- işləyən Docker demonunun dayandırılması;
- yeni Docker demonunun işə salınması;
- sınaq;
- dövrü təkrarlayın.
Gözəl, təkrarlana bilən bir montaj (yəni konteynerdə) etmək istəyirsinizsə, o, daha mürəkkəb oldu:
- hackity hack;
- Docker-in işləyən versiyasının işlədiyinə əmin olun;
- köhnə Docker ilə yeni Docker qurmaq;
- Docker demonunu dayandırın;
- yeni Docker demonunu işə salın;
- test;
- yeni Docker demonunu dayandırın;
- təkrarlamaq.
Docker-in-Docker-in yaranması ilə proses daha sadə oldu:
- hackity hack;
- montaj + bir mərhələdə işə salmaq;
- dövrü təkrarlayın.
Bu şəkildə daha yaxşı deyilmi?

Docker-in-Docker: "Pis"
Bununla belə, məşhur inancın əksinə olaraq, Docker-in-Docker 100% ulduz, poni və təkbuynuzlu deyil. Demək istədiyim odur ki, tərtibatçının bilməli olduğu bir neçə məsələ var.
Onlardan biri AppArmor və SELinux kimi LSM-lərə (Linux təhlükəsizlik modullarına) aiddir: konteyner işlədərkən “daxili Docker” “xarici Docker” ilə ziddiyyət təşkil edən və ya çaşdıran təhlükəsizlik profillərini tətbiq etməyə cəhd edə bilər. Bu, imtiyazlı bayrağın orijinal tətbiqini birləşdirməyə çalışarkən həll edilməsi ən çətin problemdir. Dəyişikliklərim işə yaradı və bütün testlər mənim Debian maşınımda və Ubuntu sınaq VM-lərində keçəcəkdi, lakin onlar Maykl Krosbinin maşınında çökəcək və yanacaqdılar (xatırladığım kimi o Fedora idi). Problemin dəqiq səbəbini xatırlaya bilmirəm, lakin bu ola bilər ki, Mayk SELINUX=enforce (mən AppArmor istifadə etdim) ilə işləyən müdrik adamdır və mənim dəyişikliklərim SELinux profillərini nəzərə almamışdı.
Docker-in-Docker: "Şər"
İkinci problem Docker saxlama sürücüləri ilə bağlıdır. Docker-in-Docker-i işə saldığınız zaman, xarici Docker adi fayl sisteminin (EXT4, BTRFS və ya sizdə olan hər hansı bir) üstündə, daxili Docker isə yazma üzərində kopyalama sisteminin (AUFS, BTRFS, Device Mapper) üzərində işləyir. və s.). , xarici Docker-dən istifadə etmək üçün konfiqurasiya ediləndən asılı olaraq). Bu işləməyəcək bir çox kombinasiya yaradır. Məsələn, AUFS-i AUFS-in üstündə işlədə bilməyəcəksiniz.
BTRFS-ni BTRFS-in üstündə işlədirsinizsə, o, əvvəlcə işləməlidir, lakin iç-içə alt cildlər olduqda, əsas alt cildin silinməsi uğursuz olacaq. Device Mapper modulunun ad sahəsi yoxdur, ona görə də birdən çox Docker instansiyası onu eyni maşında işlədirsə, onların hamısı bir-birlərində və konteyner ehtiyat nüsxə cihazlarında şəkilləri görə (və təsir göstərə) biləcəklər. Bu pisdir.
Bu problemlərin bir çoxunu həll etmək üçün həll yolları var. Məsələn, daxili Docker-də AUFS-dən istifadə etmək istəyirsinizsə, sadəcə /var/lib/docker qovluğunu həcmə çevirin və yaxşı olacaqsınız. Docker bəzi əsas ad boşluqlarını Cihaz Xəritəçəkməçisinin hədəf adlarına əlavə etdi ki, birdən çox Docker zəngləri eyni maşında işləyirsə, onlar bir-birinin üzərinə getməsin.
Ancaq bunlardan göründüyü kimi, belə quraşdırma heç də sadə deyil GitHub-da dind deposunda.
Docker-in-Docker: Daha da pisləşir
Quraşdırma önbelleği haqqında nə demək olar? Bu da olduqca çətin ola bilər. İnsanlar tez-tez məndən soruşurlar: “Əgər mən Docker-in-Docker işlədirəmsə, hər şeyi daxili Docker-ə çəkmək əvəzinə hostumda yerləşdirilən şəkillərdən necə istifadə edə bilərəm”?
Bəzi təşəbbüskar insanlar /var/lib/docker-i hostdan Docker-in-Docker konteynerinə bağlamağa çalışdılar. Bəzən onlar /var/lib/docker-i çoxlu konteynerlərlə paylaşırlar.

Məlumatlarınızı korlamaq istəyirsiniz? Çünki məlumatlarınıza zərər verən məhz budur!
Docker demonu açıq şəkildə /var/lib/docker-ə eksklüziv giriş əldə etmək üçün hazırlanmışdır. Başqa heç bir şey bu qovluqda yerləşən hər hansı Docker faylına "toxunmamalı, soxmamalı və ya ötürməməlidir".
Bu niyə belədir? Çünki bu, dotCloud-u inkişaf etdirərkən öyrənilən ən çətin dərslərdən birinin nəticəsidir. DotCloud konteyner mühərriki eyni vaxtda /var/lib/dotcloud-a daxil olan birdən çox prosesə malik olmaqla işləyirdi. Atom faylının dəyişdirilməsi (yerində redaktə əvəzinə), məsləhət və məcburi kilidlərlə bibərləmə kodu və SQLite və BDB kimi təhlükəsiz sistemlərlə digər təcrübələr kimi hiyləgər fəndlər həmişə işləmirdi. Nəhayət Dockerə çevrilən konteyner mühərrikimizi yenidən dizayn edərkən, böyük dizayn qərarlarından biri, bütün paralel cəfəngiyatları aradan qaldırmaq üçün bütün konteyner əməliyyatlarını bir demon altında birləşdirmək idi.
Məni səhv başa düşməyin: çoxlu prosesləri və müasir paralel idarəetməni əhatə edən yaxşı, etibarlı və sürətli bir şey etmək tamamilə mümkündür. Lakin biz hesab edirik ki, yeganə oyunçu kimi Docker-dən istifadə edərək kodu yazmaq və saxlamaq daha sadə və asan olur.
Bu o deməkdir ki, əgər siz /var/lib/docker qovluğunu çoxsaylı Docker nümunələri arasında paylaşsanız, probleminiz olacaq. Əlbəttə ki, bu, xüsusilə testin ilkin mərhələlərində işləyə bilər. "Qulaq as, ana, mən ubuntu-nu doker kimi işlədə bilərəm!" Ancaq daha mürəkkəb bir şey sınayın, məsələn, eyni təsviri iki fərqli instansiyadan çəkmək və dünyanın yandığını görəcəksiniz.
Bu o deməkdir ki, əgər CI sisteminiz qurma və yenidən qurma işləri həyata keçirirsə, hər dəfə Docker-in-Docker konteynerinizi yenidən işə saldığınız zaman nüvəni onun keşinə atmaq riskiniz var. Bu heç də sərin deyil!
Həlli
Gəlin bir addım geri alaq. Həqiqətən Docker-in-Docker-ə ehtiyacınız varmı və ya sadəcə Docker-i işə salmaq və CI sisteminin özü konteynerdə olarkən CI sisteminizdən konteynerlər və şəkillər qurmaq və işlətmək istəyirsiniz?
Əminəm ki, insanların çoxu sonuncu variantı istəyir, yəni Jenkins kimi CI sisteminin konteynerləri işlədə bilməsini istəyirlər. Bunu etmək üçün ən asan yol, sadəcə olaraq CI konteynerinizə Docker yuvasını daxil etmək və onu -v bayrağı ilə əlaqələndirməkdir.
Sadəcə olaraq, CI konteynerinizi (Jenkins və ya digər) işə saldığınız zaman Docker-in-Docker ilə birlikdə nəyisə sındırmaq əvəzinə onu xəttlə başlayın:
docker run -v /var/run/docker.sock:/var/run/docker.sock ...Bu konteynerin indi Docker yuvasına çıxışı olacaq və buna görə də konteynerləri işlədə biləcək. Bundan başqa, "uşaq" konteynerlərini işə salmaq əvəzinə, "qardaş" konteynerlərini işə salacaq.
Rəsmi docker təsvirindən istifadə edərək bunu sınayın (burada Docker binar faylı var):
docker run -v /var/run/docker.sock:/var/run/docker.sock
-ti dockerO, Docker-in-Docker kimi görünür və işləyir, lakin Docker-in-Docker deyil: bu konteyner əlavə konteynerlər yaratdıqda, onlar ən yüksək səviyyəli Docker-də yaradılacaq. Siz yuvalamanın yan təsirləri ilə qarşılaşmayacaqsınız və montaj keşi çoxsaylı zənglər arasında paylaşılacaq.
Qeyd: Bu məqalənin əvvəlki versiyalarında Docker binarını hostdan konteynerə bağlamaq məsləhət görülür. Docker mühərriki artıq statik və ya yaxın statik kitabxanaları əhatə etmədiyi üçün bu, indi etibarsız oldu.
Beləliklə, Jenkins CI-dən Docker-dən istifadə etmək istəyirsinizsə, 2 seçiminiz var:
Docker API-dən istifadə edərək əsas şəkil qablaşdırma sistemindən istifadə edərək Docker CLI-nin quraşdırılması (məsələn, şəkliniz Debian-a əsaslanırsa, .deb paketlərindən istifadə edin).
Bəzi reklamlar 🙂
Bizimlə qaldığınız üçün təşəkkür edirik. Məqalələrimiz xoşunuza gəlirmi? Daha maraqlı məzmun görmək istəyirsiniz? Sifariş verməklə və ya dostlarınıza tövsiyə etməklə bizə dəstək olun, , Sizin üçün bizim tərəfimizdən icad edilmiş giriş səviyyəli serverlərin unikal analoqu: (RAID1 və RAID10, 24 nüvəyə qədər və 40 GB DDR4 ilə mövcuddur).
Dell R730xd Amsterdamdakı Equinix Tier IV məlumat mərkəzində 2 dəfə ucuzdur? Yalnız burada Hollandiyada! Dell R420 - 2x E5-2430 2.2Ghz 6C 128GB DDR3 2x960GB SSD 1Gbps 100TB - 99 dollardan! haqqında oxuyun
Mənbə: www.habr.com
