Docker'ı Docker'ın içinde nasıl çalıştırdım ve bundan ne çıktı?

Herkese selam! onun içinde önceki haberBu derste Docker'ı Docker'da çalıştırma ve kullanmanın pratik yönlerinden bahsedeceğime söz verdim. Artık sözünü tutmanın zamanı geldi. Deneyimli bir devopser muhtemelen Docker içinde Docker'a ihtiyaç duyanların Docker arka plan programı soketini ana bilgisayardan konteynere iletmesine itiraz edecektir ve bu durum vakaların %99'unda yeterli olacaktır. Ama bana kurabiye fırlatmak için acele etmeyin çünkü Docker'ı Docker'ın içinde gerçekten çalıştırmaktan bahsedeceğiz. Bu çözümün birçok olası uygulaması vardır ve bu makale bunlardan biri hakkındadır, o yüzden arkanıza yaslanın ve kollarınızı önünüzde düzleştirin.

Docker'ı Docker'ın içinde nasıl çalıştırdım ve bundan ne çıktı?

başlangıç

Her şey yağmurlu bir eylül akşamı, Digital Ocean'da 5 dolara kiraladığım, Docker'ın 24 gigabaytlık kullanılabilir disk alanının tamamını görselleri ve konteynerleriyle doldurması nedeniyle donan makineyi temizlerken başladı. Buradaki ironi, tüm bu görüntülerin ve kapsayıcıların geçici olması ve yalnızca bir kitaplığın veya çerçevenin yeni bir sürümü yayınlandığında uygulamamın performansını test etmek için gerekli olmasıydı. Çöpleri temizlemek için kabuk komut dosyaları yazmayı ve bir cron programı ayarlamayı denedim, ancak işe yaramadı: her seferinde kaçınılmaz olarak sunucumun disk alanının tükenmesi ve sunucunun (en iyi ihtimalle) askıda kalmasıyla sonuçlandı. Bir noktada Jenkins'in bir konteynerde nasıl çalıştırılacağı ve kendisine iletilen bir docker arka plan programı soketi aracılığıyla derleme hatlarını nasıl oluşturup silebileceği hakkında bir makaleyle karşılaştım. Bu fikir hoşuma gitti ama daha da ileri gitmeye ve Docker'ı doğrudan Docker'ın içinde çalıştırmayı denemeye karar verdim. O zamanlar Docker görsellerini indirmek ve test etmek için ihtiyaç duyduğum tüm uygulamalar için başka bir konteyner (buna hazırlama konteyneri diyelim) oluşturmak için konteynerler oluşturmak bana tamamen mantıklı bir çözüm gibi göründü. Buradaki fikir, -rm bayrağıyla bir hazırlama kabı başlatmaktı; bu, durdurulduğunda kabın tamamını ve tüm içeriğini otomatik olarak siler. Docker'ın kendisinden Docker görüntüsünü düzelttim (https://hub.docker.com/_/docker), ama çok hantal olduğu ortaya çıktı ve hiçbir zaman ihtiyacım olan şekilde çalıştırmayı başaramadım ve sonuna kadar kendim gitmek istedim.

Pratik. Koniler

Kabın ihtiyacım olan şekilde çalışmasını sağlamak için yola çıktım ve deneylerime devam ettim, bunun sonucunda sayısız tomurcuk ortaya çıktı. Kendi kendime yaptığım işkencenin sonucu şu algoritmaydı:

  1. Docker konteynerini etkileşimli modda başlatıyoruz.

    docker run --privileged -it docker:18.09.6

    Kabın versiyonuna dikkat edin, sağa veya sola adım atın ve DinD'niz balkabağına dönüşsün. Aslında yeni bir sürüm yayınlandığında işler sıklıkla bozulur.
    Derhal kabuğa girmeliyiz.

  2. Hangi kapsayıcıların çalıştığını bulmaya çalışıyoruz (Cevap: yok), ancak yine de komutu çalıştıralım:

    docker ps

    Biraz şaşıracaksınız ama Docker arka plan programının çalışmadığı ortaya çıktı:

    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. Kendimiz çalıştıralım:

    dockerd &

    Hoş olmayan bir sürpriz daha:

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

  4. İptables ve bash paketlerini yükleyin (her şeyi bash'ta çalışmak sh'den daha keyiflidir):

    apk add --no-cache iptables bash

  5. Bash'ı başlatalım. Sonunda her zamanki kabuğa geri döndük

  6. Docker'ı tekrar başlatmayı deneyelim:

    dockerd &

    Şununla biten uzun bir günlük sayfası görmeliyiz:

    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 tuşuna basın. Partiye geri döndük.

Artık Docker konteynerimizin içinde başka konteynerler başlatmayı deneyebiliriz ancak Docker konteynerimizin içinde başka bir Docker konteyneri başlatmak istersek veya bir şeyler ters giderse ve konteyner çökerse ne olur? En baştan yeniden başla.

Kendi DinD kapsayıcısına ve yeni deneylere sahip olun

Docker'ı Docker'ın içinde nasıl çalıştırdım ve bundan ne çıktı?
Yukarıdaki adımların tekrar tekrar tekrarlanmasını önlemek için kendi DinD kapsayıcımı oluşturdum:

https://github.com/alekslitvinenk/dind

Çalışan DinD çözümü bana Docker'ı Docker'ın içinde yinelemeli olarak çalıştırma ve daha macera dolu deneyler yapma olanağı verdi.
Şimdi MySQL ve Nodejs'i çalıştırmayla ilgili böyle (başarılı) bir deneyi anlatacağım.
En sabırsız olanlar burada nasıl olduğunu görebilir

Yani, başlayalım:

  1. DinD'yi etkileşimli modda başlatıyoruz. DinD'nin bu sürümünde, alt konteynerlerimizin kullanabileceği tüm bağlantı noktalarını manuel olarak eşlememiz gerekiyor (zaten bunun üzerinde çalışıyorum)

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

    Alt konteynerleri hemen başlatmaya başlayabileceğimiz bash'a giriyoruz.

  2. MySQL'i başlatın:

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

  3. Veritabanına yerel olarak bağlandığımız şekilde bağlanıyoruz. Her şeyin çalıştığından emin olalım.

  4. İkinci kapsayıcıyı başlatın:

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

    Lütfen bağlantı noktası eşlemesinin tam olarak olacağını unutmayın. 8080:808080 numaralı bağlantı noktasını ana bilgisayardan ana kapsayıcıya ve 8080 numaralı bağlantı noktasına zaten eşlediğimiz için.

  5. Tarayıcıda localhost'a gidiyoruz, sunucunun "Merhaba Dünya!"

Benim durumumda, iç içe geçmiş Docker konteynerleriyle yapılan deney oldukça olumlu sonuçlandı ve projeyi geliştirmeye ve sahneleme için kullanmaya devam edeceğim. Bana öyle geliyor ki bu, Kubernetes ve Jenkins X'ten çok daha hafif bir çözüm. Ancak bu benim öznel görüşüm.

Sanırım bugünkü yazımız bu kadar. Bir sonraki makalede Docker'ı Docker'da özyinelemeli olarak çalıştırma ve dizinleri iç içe konteynerlerin derinliklerine yerleştirme deneylerini daha ayrıntılı olarak anlatacağım.

PS Bu projeyi faydalı bulursanız lütfen GitHub'da ona bir yıldız verin, çatallayın ve arkadaşlarınıza söyleyin.

Edit1 Hatalar düzeltildi, 2 videoya odaklanıldı

Kaynak: habr.com

Yorum ekle