Bagaimana saya menjalankan Docker di dalam Docker dan apa yang terhasil daripadanya

Hai semua! Dalam dia artikel sebelumnya, saya berjanji untuk bercakap tentang menjalankan Docker dalam Docker dan aspek praktikal menggunakan pelajaran ini. Sudah tiba masanya untuk menunaikan janji anda. Seorang devopser yang berpengalaman mungkin akan membantah bahawa mereka yang memerlukan Docker di dalam Docker hanya memajukan soket daemon Docker dari hos ke dalam bekas dan ini akan mencukupi dalam 99% kes. Tetapi jangan tergesa-gesa untuk melemparkan kuki kepada saya, kerana kita akan bercakap tentang sebenarnya menjalankan Docker di dalam Docker. Penyelesaian ini mempunyai banyak kemungkinan aplikasi dan artikel ini adalah mengenai salah satu daripadanya, jadi duduk dan luruskan tangan anda di hadapan anda.

Bagaimana saya menjalankan Docker di dalam Docker dan apa yang terhasil daripadanya

bermula

Semuanya bermula pada petang September yang hujan ketika saya sedang membersihkan mesin yang saya sewa dengan harga $5 di Digital Ocean, yang dibekukan kerana fakta bahawa Docker telah mengisi kesemua 24 gigabait ruang cakera yang tersedia dengan imej dan bekasnya. Ironinya ialah semua imej dan bekas ini bersifat sementara dan hanya diperlukan untuk menguji prestasi aplikasi saya setiap kali versi baharu perpustakaan atau rangka kerja dikeluarkan. Saya cuba menulis skrip shell dan menyediakan jadual cron untuk membersihkan sampah, tetapi ia tidak membantu: setiap kali ia pasti berakhir dengan ruang cakera pelayan saya dimakan dan pelayan tergantung (paling baik). Pada satu ketika, saya menjumpai artikel tentang cara menjalankan Jenkins dalam bekas dan cara ia boleh mencipta dan memadamkan saluran paip binaan melalui soket daemon docker yang dikemukakan ke dalamnya. Saya menyukai idea itu, tetapi saya memutuskan untuk pergi lebih jauh dan cuba bereksperimen dengan menjalankan Docker secara langsung di dalam Docker. Pada masa itu, nampaknya saya penyelesaian yang logik sepenuhnya untuk memuat turun imej Docker dan mencipta bekas untuk semua aplikasi yang saya perlukan untuk menguji di dalam bekas lain (mari kita panggil ia bekas pementasan). Ideanya adalah untuk memulakan bekas pementasan dengan bendera -rm, yang secara automatik memadamkan keseluruhan bekas dan semua kandungannya apabila ia dihentikan. Saya bermain-main dengan imej Docker dari Docker itu sendiri (https://hub.docker.com/_/docker), tetapi ternyata ia terlalu menyusahkan dan saya tidak pernah berjaya membuatnya berfungsi seperti yang saya perlukan dan saya mahu melakukannya sendiri.

berlatih. kon

Saya berusaha untuk menjadikan bekas berfungsi seperti yang saya perlukan dan meneruskan percubaan saya, yang menghasilkan banyak tunas. Hasil penyeksaan diri saya adalah algoritma berikut:

  1. Kami melancarkan bekas Docker dalam mod interaktif.

    docker run --privileged -it docker:18.09.6

    Perhatikan versi bekas, langkah ke kanan atau kiri dan DinD anda bertukar menjadi labu. Malah, perkara-perkara sering rosak apabila versi baharu dikeluarkan.
    Kita mesti segera masuk ke dalam cangkerang.

  2. Kami cuba untuk mengetahui bekas yang sedang dijalankan (Jawapan: tiada), tetapi mari jalankan arahan pula:

    docker ps

    Anda akan sedikit terkejut, tetapi ternyata daemon Docker tidak berjalan:

    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. Mari kita jalankan sendiri:

    dockerd &

    Satu lagi kejutan yang tidak menyenangkan:

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

  4. Pasang pakej iptables dan bash (semuanya lebih menyenangkan untuk digunakan dalam bash daripada dalam sh):

    apk add --no-cache iptables bash

  5. Mari kita lancarkan bash. Akhirnya kami kembali dalam cangkang biasa

  6. Mari cuba mulakan Docker sekali lagi:

    dockerd &

    Kita seharusnya melihat helaian log panjang yang berakhir dengan:

    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. Tekan enter. Kami kembali dalam bash.

Mulai sekarang, kami boleh cuba melancarkan bekas lain di dalam bekas Docker kami, tetapi bagaimana jika kami mahu melancarkan bekas Docker lain di dalam bekas Docker kami atau ada masalah dan kontena ranap? Mulakan sekali lagi.

Bekas DinD sendiri dan percubaan baharu

Bagaimana saya menjalankan Docker di dalam Docker dan apa yang terhasil daripadanya
Untuk mengelakkan mengulangi langkah di atas berulang kali, saya mencipta bekas DinD saya sendiri:

https://github.com/alekslitvinenk/dind

Penyelesaian DinD yang berfungsi memberi saya keupayaan untuk menjalankan Docker di dalam Docker secara rekursif dan melakukan eksperimen yang lebih mencabar.
Saya akan menerangkan satu percubaan (berjaya) sedemikian dengan menjalankan MySQL dan Nodejs sekarang.
Yang paling tidak sabar dapat melihat bagaimana keadaan di sini

Oleh itu, mari kita mulakan:

  1. Kami melancarkan DinD dalam mod interaktif. Dalam versi DinD ini, kita perlu memetakan secara manual semua port yang boleh digunakan oleh bekas anak kita (saya sudah mengusahakannya)

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

    Kami masuk ke dalam bash, dari mana kami boleh mula melancarkan bekas kanak-kanak dengan segera.

  2. Lancarkan MySQL:

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

  3. Kami menyambung ke pangkalan data dengan cara yang sama seperti kami menyambungkannya secara tempatan. Mari pastikan semuanya berfungsi.

  4. Lancarkan bekas kedua:

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

    Sila ambil perhatian bahawa pemetaan pelabuhan adalah tepat 8080:8080, kerana kami telah pun memetakan port 80 daripada hos kepada bekas induk kepada port 8080.

  5. Kami pergi ke localhost dalam penyemak imbas, pastikan pelayan menjawab "Hello World!"

Dalam kes saya, percubaan dengan bekas Docker bersarang ternyata agak positif dan saya akan terus membangunkan projek itu dan menggunakannya untuk pementasan. Nampaknya saya ini adalah penyelesaian yang jauh lebih ringan daripada Kubernetes dan Jenkins X. Tetapi ini adalah pendapat subjektif saya.

Saya rasa itu sahaja untuk artikel hari ini. Dalam artikel seterusnya saya akan menerangkan dengan lebih terperinci eksperimen dengan menjalankan Docker secara rekursif dalam Docker dan memasang direktori jauh ke dalam bekas bersarang.

PS Jika anda mendapati projek ini berguna, sila berikan bintang pada GitHub, buat garpu dan beritahu rakan anda.

Edit1 Ralat diperbetulkan, fokus pada 2 video

Sumber: www.habr.com

Tambah komen