Halo semuanya! Dalam artikel saya sebelumnya , saya berjanji untuk berbicara tentang peluncuran Docker di Docker dan aspek praktis penerapan pelajaran ini. Saatnya menepati janji kita. Seorang devo yang berpengalaman, mungkin, akan berpendapat bahwa mereka yang membutuhkan Docker di dalam Docker hanya membuang soket iblis Docker dari host di dalam wadah dan ini sudah cukup dalam 99% kasus. Tapi jangan buru-buru melemparkan cookie ke saya, karena kita akan berbicara tentang peluncuran Docker yang sebenarnya di dalam Docker. Solusi ini memiliki banyak bidang aplikasi yang mungkin dan artikel ini tentang salah satunya, jadi duduk dan luruskan lengan Anda di depan Anda.
Mulai
Semuanya berawal pada suatu malam di bulan September yang hujan ketika saya sedang membersihkan mobil sewaan Digital Ocean seharga $ 5, yang sangat ketat karena Docker mengisi semua 24 gigabytes ruang disk yang tersedia dengan gambar dan wadahnya. Ironinya adalah bahwa semua gambar dan wadah ini bersifat sementara dan hanya perlu untuk menguji kinerja aplikasi saya setiap kali versi baru perpustakaan atau kerangka kerja keluar. Saya mencoba untuk menulis skrip shell dan mengkonfigurasi jadwal mahkota untuk pembersihan sampah, tetapi ini tidak menghemat: setiap kali, tak terhindarkan, ruang disk server saya ternyata dimakan dan server digantung (paling-paling). Pada titik tertentu, saya menemukan sebuah artikel tentang cara menjalankan Jenkins dalam sebuah wadah dan bagaimana ia dapat membuat dan menghapus pipa rakitan melalui soket daemon buruh pelabuhan yang dilemparkan ke dalamnya. Saya menyukai gagasan itu, tetapi saya memutuskan untuk terus maju dan mencoba bereksperimen dengan peluncuran langsung Docker di dalam Docker. Bagi saya, itu adalah keputusan yang sangat logis untuk memompa gambar buruh pelabuhan dan membuat wadah dari semua aplikasi yang saya butuhkan untuk pengujian di dalam wadah lain (sebut saja wadah pementasan). Idenya adalah untuk menjalankan wadah pementasan dengan bendera -rm, yang secara otomatis menghapus seluruh wadah dengan semua isinya ketika berhenti. Saya mencari-cari gambar buruh pelabuhan dari Docker itu sendiri ( https://hub.docker.com/_/docker ), tetapi ternyata terlalu besar dan saya tidak bisa membuatnya berfungsi seperti yang saya butuhkan dan saya ingin pergi sendiri.
Berlatih. Benjolan
Saya berangkat untuk membuat wadah bekerja sesuai kebutuhan dan melanjutkan percobaan saya, yang menghasilkan segudang kerucut. Hasil dari penyiksaan diri saya adalah algoritma berikut:
Kami meluncurkan wadah Docker dalam mode interaktif.
docker run --privileged -it docker:18.09.6
Perhatikan versi wadah, langkah ke kanan atau ke kiri dan DID Anda berubah menjadi labu. Bahkan, semuanya sering rusak dengan rilis versi baru.
Kita harus segera masuk ke shell.
Mencoba mencari tahu wadah mana yang berjalan (Jawab: tidak ada), tetapi mari kita tetap jalankan perintah:
docker ps
Anda akan sedikit terkejut, tetapi ternyata daemon Docker bahkan 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
Mari kita jalankan sendiri:
dockerd &
Kejutan tidak menyenangkan lainnya:
failed to start daemon: Error initializing network controller: error obtaining controller instance: failed to create NAT chain DOCKER: Iptables not found
Instal iptables dan paket bash (lebih menyenangkan untuk bekerja di bash daripada di sh):
apk add --no-cache iptables bash
Kami mulai bash. Akhirnya kami kembali ke shell yang biasa
coba luncurkan docker lagi:
dockerd &
Kita akan melihat lembar log panjang yang berakhir:
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
Tekan Enter. Kami kembali di pesta.
Mulai sekarang, kita dapat mencoba meluncurkan wadah lain di dalam wadah Docker kita, tetapi bagaimana jika kita ingin menaikkan wadah Docker lain di dalam wadah Docker kita atau ada yang tidak beres dan wadah itu akan βterbang keluarβ? Mulai dari awal lagi.
Wadah DID sendiri dan percobaan baru
Agar tidak mengulangi langkah-langkah di atas lagi dan lagi, saya membuat wadah DinD saya sendiri:
https://github.com/alekslitvinenk/dind
Solusi DinD yang berfungsi memberi saya kesempatan untuk menjalankan Docker di dalam Docker secara rekursif dan melakukan eksperimen yang lebih berani.
Salah satu percobaan (berhasil) tersebut dengan menjalankan MySQL dan Nodejs, saya akan jelaskan sekarang.
Yang paling tidak sabar bisa melihat bagaimana itu ada di sini
Jadi, mari kita mulai:
Luncurkan DID secara interaktif. Dalam versi DinD ini, kita perlu memetakan secara manual semua port yang dapat digunakan wadah anak kita (saya sudah mengerjakan ini)
docker run --privileged -it \ -p 80:8080 \ -p 3306:3306 \ alekslitvinenk/dind
Kami menemukan diri kami dalam sebuah bash, dari mana kami dapat segera mulai meluncurkan kontainer tambahan.
Kami memulai MySQL:
docker run --name mysql -e MYSQL_ROOT_PASSWORD=strongpassword -d -p 3306:3306 mysql
Kami terhubung ke database dengan cara yang sama seperti kami akan terhubung secara lokal. Pastikan semuanya bekerja.
Kami meluncurkan wadah kedua:
docker run -d --rm -p 8080:8080 alekslitvinenk/hello-world-nodejs-server
Harap dicatat bahwa pemetaan port di sini akan tepat 8080: 8080 , karena kami telah memetakan port 80 dari host ke wadah induk di port 8080.
Kami pergi ke localhost di browser, kami yakin bahwa server menjawab "Hello World!".
Dalam kasus saya, percobaan dengan wadah buruh pelabuhan tertutup cukup positif, dan saya akan terus mengembangkan proyek dan menggunakannya untuk pementasan. Menurut saya ini adalah solusi yang jauh lebih ringan daripada Kubernetes dan Jenkins X yang sama. Tapi ini pendapat subjektif saya.
Saya pikir ini semua untuk artikel hari ini. Pada artikel berikutnya, saya akan menjelaskan dalam percobaan yang lebih rinci dengan peluncuran Docker di Docker secara rekursif dan pemasangan direktori jauh ke dalam wadah bersarang.
NB Jika Anda menganggap proyek ini bermanfaat, maka beri asterisk pada GitHub, garpu dan beri tahu teman-teman Anda.
Edit1 Bug yang diperbaiki , fokus pada 2 video