Apakah boleh menjalankan docker dari dalam docker?

185

Saya menjalankan Jenkins di dalam wadah Docker. Saya bertanya-tanya apakah tidak masalah bagi wadah Jenkins untuk menjadi tuan rumah Docker? Apa yang saya pikirkan adalah untuk memulai wadah buruh pelabuhan baru untuk setiap build uji integrasi dari dalam Jenkins (untuk memulai database, pialang pesan, dll.). Kontainer dengan demikian harus dimatikan setelah tes integrasi selesai. Apakah ada alasan untuk menghindari menjalankan wadah buruh pelabuhan dari dalam wadah buruh pelabuhan lain dengan cara ini?

Johan
sumber
11
Kemungkinan lain adalah memasang dock docker dari host sebagai volume dalam wadah. Itu memungkinkan Anda membuat wadah "saudara" dan memiliki keuntungan bisa menggunakan kembali cache.
Adrian Mouat
4
Saya telah menemukan bahwa ketika menggunakan socket docker dari host yang dalam kasus di mana saya ingin me-mount volume eksternal perlu untuk mengatur jalur volume relatif ke host karena di situlah docker daemon berjalan. Menyetelnya relatif terhadap wadah yang memulai wadah tidak akan berfungsi kecuali jalur bertepatan.
Jakob Runge

Jawaban:

224

Menjalankan Docker di dalam Docker (alias dind ), sedapat mungkin, harus dihindari, jika memungkinkan. (Sumber disediakan di bawah ini.) Sebaliknya, Anda ingin mengatur cara agar wadah utama Anda memproduksi dan berkomunikasi dengan wadah saudara .

Jérôme Petazzoni - penulis fitur yang memungkinkan Docker berjalan di dalam wadah Docker - sebenarnya menulis posting blog yang mengatakan tidak melakukannya . Kasus penggunaan yang dia gambarkan cocok dengan kasus penggunaan OP yang tepat dari wadah CI Docker yang perlu menjalankan pekerjaan di dalam wadah Docker lainnya.

Petazzoni mencantumkan dua alasan mengapa dind merepotkan:

  1. Itu tidak bekerja dengan baik dengan Modul Keamanan Linux (LSM).
  2. Ini menciptakan ketidakcocokan dalam sistem file yang menciptakan masalah untuk wadah yang dibuat di dalam wadah induk.

Dari posting blog itu, ia menjelaskan alternatif berikut,

[Cara] paling sederhana adalah dengan hanya mengekspos soket Docker ke wadah CI Anda, dengan mengikat-mount dengan -vbendera.

Sederhananya, ketika Anda memulai wadah CI Anda (Jenkins atau lainnya), alih-alih meretas sesuatu bersama dengan Docker-in-Docker, mulailah dengan:

docker run -v /var/run/docker.sock:/var/run/docker.sock ...

Sekarang wadah ini akan memiliki akses ke soket Docker, dan karena itu akan dapat memulai wadah. Kecuali bahwa alih-alih memulai wadah "anak", itu akan memulai wadah "saudara".

predmijat
sumber
1
Bagaimana menjalankan perintah buruh pelabuhan tanpa sudoketika melakukan seperti ini? Terima kasih
c4k
3
Anda perlu menambahkan pengguna ke dockergrup: sudo usermod -aG docker $USER. Anda harus melakukan relog ulang setelah itu.
predmijat
2
Bagaimana cara relog dari dalam cointainer?
thiagowfx
1
@AlexanderMills Ini sama karena socket docker Anda juga terletak pada /var/run/docker.socksaat Anda menjalankan docker untuk mac pada mesin macos Anda.
Bruce Sun
1
bagaimana dengan windows? saya tidak punya/var/run/docker.sock
Abdelhafid
54

Saya menjawab pertanyaan serupa sebelumnya tentang cara menjalankan wadah Docker di dalam Docker .

Untuk menjalankan buruh pelabuhan di dalam buruh pelabuhan adalah mungkin. Yang utama adalah Anda runmemiliki wadah luar dengan hak istimewa ekstra (dimulai dengan --privileged=true) dan kemudian memasang buruh pelabuhan di wadah itu.

Lihat posting blog ini untuk info lebih lanjut: Docker-in-Docker .

Satu kasus penggunaan potensial untuk ini dijelaskan dalam entri ini . Blog menjelaskan cara membuat wadah buruh pelabuhan di dalam wadah buruh pelabuhan Jenkins.

Namun, Docker di dalam Docker bukanlah pendekatan yang disarankan untuk menyelesaikan masalah jenis ini. Sebagai gantinya, pendekatan yang disarankan adalah membuat wadah "saudara" seperti yang dijelaskan dalam posting ini

Jadi, menjalankan Docker di dalam Docker oleh banyak orang dianggap sebagai jenis solusi yang baik untuk jenis masalah ini. Sekarang, trennya adalah menggunakan wadah "saudara". Lihat jawabannya oleh @predmijat di halaman ini untuk info lebih lanjut.

wassgren
sumber
Lihat komentar di bawah tentang menghindari buruh pelabuhan di buruh pelabuhan.
Dan Poltawski
6

Tidak apa-apa untuk menjalankan Docker-in-Docker (DinD) dan pada kenyataannya Docker (perusahaan) memiliki gambar DinD resmi untuk ini.

Namun peringatannya adalah bahwa itu membutuhkan wadah istimewa, yang tergantung pada kebutuhan keamanan Anda mungkin bukan alternatif yang layak.

Solusi alternatif menjalankan Docker menggunakan wadah saudara (alias Docker-out-of-Docker atau DooD) tidak memerlukan wadah istimewa, tetapi memiliki beberapa kelemahan yang berasal dari kenyataan bahwa Anda meluncurkan wadah dari dalam konteks yang berbeda dari yang sedang dijalankan (yaitu, Anda meluncurkan wadah dari dalam wadah, namun berjalan di tingkat tuan rumah, bukan di dalam wadah).

Saya menulis sebuah blog yang menggambarkan pro / kontra dari DinD vs DooD di sini .

Karena itu, Nestybox (startup yang baru saya dirikan) sedang mengerjakan solusi yang menjalankan Docker-in-Docker dengan aman (tanpa menggunakan wadah istimewa). Anda dapat memeriksanya di www.nestybox.com .

ctalledo
sumber
0

Ya, kita dapat menjalankan buruh pelabuhan di buruh pelabuhan, kita harus melampirkan sockeet unix "/var/run/docker.sock" di mana daemon buruh pelabuhan mendengarkan secara default sebagai volume ke buruh pelabuhan induk menggunakan "-v / var / run /docker.sock:/var/run/docker.sock ". Terkadang, masalah izin mungkin muncul untuk soket daemon docker yang dapat Anda tulis "sudo chmod 757 /var/run/docker.sock".

Dan juga perlu menjalankan docker dalam mode istimewa, jadi perintahnya adalah:

sudo chmod 757 /var/run/docker.sock

run buruh pelabuhan --privileged = true -v /var/run/docker.sock:/var/run/docker.sock -itu ...

Renu Saini
sumber