Teknik Pengurangan Gambar Docker

Pernahkah Anda bertanya-tanya mengapa ukuran wadah Docker yang hanya berisi satu aplikasi bisa sekitar 400 MB? Atau mungkin Anda khawatir tentang ukuran gambar Docker yang agak besar berisi biner tunggal dengan ukuran beberapa puluh MB?



Penulis artikel, terjemahan yang kami terbitkan hari ini, ingin menganalisis faktor utama yang mempengaruhi ukuran wadah Docker. Dia, di samping itu, akan berbagi rekomendasi untuk mengurangi ukuran kontainer.

Lapisan Gambar Docker


Gambar wadah Docker pada dasarnya adalah kumpulan file yang ditumpuk satu sama lain dalam beberapa lapisan. Wadah yang berfungsi dirakit dari file-file ini. Docker menggunakan sistem file UnionFS , di mana file dikelompokkan dalam lapisan. Lapisan dapat berisi satu file atau beberapa file, lapisan saling tumpang tindih. Selama pelaksanaan wadah, konten lapisan digabungkan, sebagai akibatnya, pengguna akhir wadah menganggap materi “ditata” berlapis-lapis sebagai sistem file tunggal.


Tampilan UnionFS yang Sederhana

Sistem file yang dihasilkan disajikan kepada pengguna akhir menggunakan beberapa implementasi UnionFS (Docker mendukung banyak implementasi serupa melalui driver penyimpanan plug-in). Ukuran total file yang diterima oleh pengguna akhir sama dengan jumlah ukuran file dalam lapisan. Ketika Docker membuat wadah berdasarkan gambar, ia menggunakan semua lapisan read-only dari gambar, menambahkan satu lapisan tipis di atas lapisan ini yang mendukung membaca dan menulis. Lapisan inilah yang memungkinkan Anda untuk memodifikasi file dalam wadah yang sedang berjalan.


Wadah yang sedang berjalan berisi lapisan baca-tulis yang terletak di atas lapisan baca-saja

Apa yang terjadi jika suatu file dihapus pada Layer 4 wadah yang disajikan secara skematis di atas? Meskipun file ini tidak akan tersedia dalam sistem file yang dilihat pengguna, pada kenyataannya, ukuran file ini akan tetap menjadi salah satu komponen dari ukuran kontainer, karena file ini akan tetap berada di salah satu lapisan read-only.

Sangat mudah untuk mulai membangun gambar dengan file yang dapat dieksekusi aplikasi kecil dan sampai ke gambar yang sangat besar. Di bawah ini kita akan melihat berbagai metode untuk membuat wadah sekecil mungkin.

Perhatikan jalur ke folder, berdasarkan pada materi yang dikumpulkan gambar


Apa cara paling umum untuk merakit gambar Docker? Rupanya - seperti ini:

 docker build . 

Poin dalam perintah ini memberi tahu Docker bahwa kami menganggap direktori kerja saat ini sebagai root dari sistem file yang digunakan dalam proses perakitan gambar.

Untuk lebih memahami apa yang terjadi setelah perintah di atas dijalankan, perlu diingat bahwa membangun gambar Docker adalah proses client-server. Antarmuka baris perintah Docker (klien), yang kami berikan docker build , menggunakan mesin Docker (server) untuk membuat gambar wadah. Untuk membatasi akses ke sistem file dasar klien, sistem perakitan gambar perlu tahu di mana root dari sistem file virtual berada. Di sanalah instruksi dari file Dockerfile mencari sumber daya file yang akhirnya mungkin berakhir pada gambar yang sedang dirakit.

Bayangkan tempat dimana Dockerfile biasanya ditempatkan. Ini mungkin direktori root proyek? Jika ada Dockerfile di root proyek, yang digunakan oleh docker build untuk membangun gambar, maka ternyata semua file proyek dapat masuk ke dalam gambar. Ini dapat mengarah pada fakta bahwa ribuan file sampah yang ukurannya megabita banyak dapat masuk ke dalam konteks perakitan gambar. Jika Anda dengan ringan menggunakan perintah ADD dan COPY di Dockerfile , maka semua file proyek mungkin menjadi bagian dari gambar yang sudah jadi. Paling sering, mereka yang mengumpulkan gambar tidak memerlukan ini, karena gambar akhir biasanya hanya menyertakan beberapa file yang dipilih.

Selalu pastikan bahwa perintah docker build jalur yang benar, dan bahwa tidak ada perintah di Dockerfile yang menambahkan file yang tidak perlu ke gambar. Jika karena alasan tertentu Anda perlu membuat root proyek konteks pembangunan, Anda dapat secara selektif memasukkan file di dalamnya dan mengecualikannya dari itu menggunakan .dockerignore .

Optimalkan lapisan gambar


Jumlah lapisan maksimum yang dapat dimiliki gambar adalah 127 (diberikan dukungan untuk sejumlah lapisan yang digunakan oleh driver data warehouse). Keterbatasan ini, jika benar-benar diperlukan, dapat dilonggarkan, tetapi dengan pendekatan ini rentang sistem yang dapat mengumpulkan gambar-gambar tersebut dipersempit. Intinya adalah bahwa mesin Docker harus berjalan pada sistem yang kernelnya dimodifikasi sesuai.

Seperti disebutkan di bagian sebelumnya, karena fakta bahwa UnionFS digunakan ketika merakit gambar, file yang jatuh ke dalam lapisan tertentu tetap ada bahkan jika mereka dihapus dari lapisan atasnya. Mari kita cari tahu menggunakan Dockerfile eksperimental:

 FROM alpine RUN wget http://xcal1.vodafone.co.uk/10MB.zip -P /tmp RUN rm /tmp/10MB.zip 

Mari kita kumpulkan gambar:


Perakitan gambar eksperimental di mana ada ruang yang digunakan secara tidak rasional

Jelajahi gambar menggunakan menyelam :


Indikator kinerja gambar adalah 34%

Indikator efisiensi gambar 34% menunjukkan bahwa sejumlah besar ruang gambar digunakan secara tidak rasional. Hal ini menyebabkan peningkatan waktu boot gambar, pemborosan sumber daya jaringan yang tidak perlu, ke waktu mulai yang lebih lambat dari wadah.

Bagaimana cara mengatasi masalah ini? Mari kita pertimbangkan beberapa opsi.

▍ Menggabungkan hasil kerja tim


Pernahkah Anda melihat Dockerfile berisi arahan RUN sangat panjang di mana banyak perintah shell digabungkan menggunakan && ? Ini adalah penggabungan dari hasil tim.

Dengan menggunakan metode ini, kami membuat, berdasarkan hasil dari tim panjang tunggal, hanya satu lapisan. Karena tidak akan ada lapisan dalam gambar yang berisi file yang dihapus di lapisan berikut, gambar akhir tidak akan menyertakan "file hantu" tersebut. Pertimbangkan ini sebagai contoh, membawa Dockerfile atas ke status ini:

 FROM alpine RUN wget http://xcal1.vodafone.co.uk/10MB.zip -P /tmp && rm /tmp/10MB.zip 

Setelah itu, kami menganalisis gambar:


Penggabungan tim memungkinkan Anda membuat gambar yang 100% dioptimalkan

Aplikasi teknik ini untuk mengoptimalkan ukuran gambar dalam praktek adalah bahwa setelah Anda selesai bekerja pada file Dockerfile , Anda perlu menganalisisnya dan mencari tahu apakah penggabungan perintah dapat digunakan untuk mengurangi jumlah ruang yang terbuang.

▍Menerapkan opsi --sashash


Dalam kasus di mana Anda menggunakan Dockerfile orang lain yang tidak Anda inginkan atau tidak dapat diubah, alternatif untuk menggabungkan perintah dapat merakit gambar menggunakan opsi --squash .

Versi modern Docker (dimulai dengan 1.13) memungkinkan Anda untuk membawa semua lapisan menjadi satu lapisan, dengan demikian menyingkirkan "sumber daya hantu". Dalam hal ini, Anda dapat menggunakan Dockerfile asli yang tidak dimodifikasi, yang berisi banyak perintah terpisah. Tetapi Anda perlu membangun gambar menggunakan opsi --squash :

 docker build --squash . 

Gambar yang dihasilkan juga ternyata dioptimalkan 100%:


Menggunakan opsi --sashash selama perakitan diperbolehkan membuat gambar yang 100% dioptimalkan

Di sini Anda dapat memperhatikan satu detail menarik. Yaitu, di Dockerfile lapisan dibuat untuk menambahkan file dan lapisan lain untuk menghapus file ini. Opsi --squash cukup cerdas untuk memahami bahwa dalam skenario ini Anda tidak perlu membuat layer tambahan sama sekali (pada gambar akhir hanya ada 9ccd9… layer 9ccd9… dari gambar dasar yang kami gunakan). Secara umum, untuk ini kita dapat menaruh --squash plus tambahan. Benar, menggunakan --squash , Anda perlu mempertimbangkan bahwa ini dapat mengganggu penggunaan lapisan cache.

Akibatnya, disarankan untuk mempertimbangkan fakta bahwa ketika bekerja dengan Dockerfile orang lain yang tidak ingin Anda ubah, Anda dapat meminimalkan jumlah ruang gambar yang digunakan secara tidak rasional dengan mengumpulkan gambar menggunakan opsi --squash . Untuk menganalisis gambar yang sudah jadi, Anda bisa menggunakan alat selam .

Hapus cache dan file sementara


Saat menyimpan aplikasi, situasi sering muncul ketika Anda perlu menempatkan alat, pustaka, utilitas tambahan di dalam gambar. Ini dilakukan dengan menggunakan manajer paket seperti apk , yum , apt .

Manajer paket berusaha untuk menghemat waktu pengguna dan tidak memuat koneksi jaringannya sekali lagi ketika menginstal paket. Karena itu, mereka menyimpan data yang diunduh. Agar ukuran gambar Docker akhir menjadi sekecil mungkin, kita tidak perlu menyimpan cache pengelola paket di gambar ini. Lagi pula, jika kita membutuhkan gambar lain, kita selalu dapat membangunnya kembali menggunakan Dockerfile diperbarui.

Untuk menghapus cache yang dibuat oleh tiga manajer paket populer yang disebutkan di atas, di akhir perintah gabungan (yaitu, yang menjalankan untuk membuat satu lapisan), Anda bisa menambahkan yang berikut ini:

 APK: ... && rm -rf /etc/apk/cache YUM: ... && rm -rf /var/cache/yum APT: ... && rm -rf /var/cache/apt 

Akibatnya, disarankan agar sebelum menyelesaikan pekerjaan di Dockerfile tambahkan Dockerfile untuk itu yang menghapus cache dari manajer paket yang digunakan untuk membangun gambar. Hal yang sama berlaku untuk semua file sementara yang tidak memengaruhi pengoperasian wadah dengan benar.

Pilih gambar dasar Anda dengan hati-hati


Setiap Dockerfile dimulai dengan arahan FROM . Di sinilah kita menetapkan gambar dasar atas dasar mana gambar kita akan dibuat.

Berikut adalah apa yang dikatakan dokumentasi Docker tentangnya: “Instruksi FROM menginisialisasi fase build baru dan mengatur gambar dasar untuk instruksi yang mengikuti. Akibatnya, Dockerfile disusun dengan benar harus dimulai dengan pernyataan FROM . Sebuah gambar bisa berupa gambar apa pun yang bisa diterapkan. Paling mudah untuk mulai merakit gambar Anda sendiri, dengan mengambil gambar dari repositori publik sebagai dasar. "

Jelas, ada banyak gambar dasar, yang masing-masing memiliki fitur dan kemampuan sendiri. Pemilihan gambar dasar yang benar yang berisi persis apa yang dibutuhkan aplikasi, tidak lebih dan tidak kurang, memiliki dampak besar pada ukuran gambar akhir.

Seperti yang Anda duga, ukuran gambar dasar populer sangat bervariasi:


Ukuran gambar buruh pelabuhan dasar populer

Jadi, kontainerisasi aplikasi menggunakan gambar dasar Ubuntu 19.10 akan mengarah pada fakta bahwa ukuran gambar, di samping ukuran aplikasi, akan ditambahkan lagi 73 MB. Jika kami mengumpulkan gambar yang sama berdasarkan gambar Alpine 3.10.3 , maka kami akan mendapatkan "aditif" hanya dalam jumlah 6 MB. Sejak Docker melakukan cache lapisan gambar, sumber daya jaringan dihabiskan untuk memuat gambar hanya ketika wadah diluncurkan untuk pertama kalinya dengan cara yang sesuai (dengan kata lain, ketika gambar pertama kali dimuat). Namun ukuran gambarnya sendiri tidak semakin kecil dari ini.

Di sini Anda bisa sampai pada kesimpulan (sepenuhnya logis) berikut: "Jadi - Saya akan selalu menggunakan Alpine!". Namun, sayangnya, di dunia pengembangan perangkat lunak, tidak semuanya begitu sederhana.

Mungkin pengembang Alpine Linux menemukan beberapa bahan rahasia yang masih belum ditemukan Ubuntu atau Debian? Tidak. Faktanya adalah bahwa untuk membuat gambar Docker, yang ukurannya adalah urutan besarnya lebih kecil dari ukuran gambar Debian yang sama, pengembang Alpine harus membuat beberapa keputusan tentang apa yang perlu dimasukkan dalam gambar dan apa yang tidak diperlukan. Sebelum memanggil Alpine gambar dasar yang akan selalu Anda gunakan, Anda harus bertanya apakah Alpine memiliki semua yang Anda butuhkan. Selain itu, meskipun Alpine memiliki manajer paket, mungkin paket spesifik yang digunakan di lingkungan kerja Anda, misalnya, di Ubuntu, tidak tersedia di Alpine. Atau - bukan paket, tetapi versi paket yang diinginkan. Ini adalah kompromi yang harus Anda ketahui sebelum memilih dan menguji gambar dasar yang paling cocok untuk proyek Anda.

Dan akhirnya, jika Anda benar-benar membutuhkan salah satu gambar dasar terbesar, Anda dapat menggunakan alat ini untuk memperkecil ukuran gambar. Misalnya - alat open source DockerSlim gratis . Ini akan mengurangi ukuran gambar jadi.

Pada akhirnya, kita dapat mengatakan bahwa penggunaan gambar dasar yang dipilih dengan cermat sangat penting dalam menciptakan gambar ringkas Anda sendiri. Nilai kebutuhan proyek Anda dan pilih gambar yang berisi apa yang Anda butuhkan, dan pada saat yang sama memiliki dimensi yang dapat Anda terima.

Pertimbangkan untuk membuat gambar yang tidak memiliki gambar dasar.


Jika aplikasi Anda dapat berjalan tanpa lingkungan tambahan yang disediakan dengan cara dasar, Anda dapat memutuskan untuk tidak menggunakan gambar dasar. Tentu saja, karena instruksi FROM harus ada di Dockerfile , Anda tidak dapat melakukannya tanpa itu. Selain itu, ia harus menunjuk pada semacam citra. Gambar apa yang digunakan dalam situasi seperti itu?

Tampilan awal mungkin berguna di sini. Dari deskripsinya, Anda dapat mengetahui bahwa itu dibuat khusus kosong dan dirancang untuk membuat gambar, jika Anda berbicara bahasa Dockerfile , FROM scratch , yaitu dari awal. Gambar ini sangat berguna saat membuat gambar dasar (seperti gambar debian dan busybox) atau gambar yang sangat minimal (yang berisi file biner tunggal dan apa yang diperlukan untuk operasinya, katakan sesuatu seperti hello-world). Menggunakan gambar ini sebagai dasar gambar yang dijelaskan oleh Dockerfile mirip dengan menggunakan "operasi kosong" di beberapa program. Menerapkan gambar scratch tidak akan membuat lapisan tambahan pada gambar selesai.

Akibatnya, jika aplikasi Anda adalah executable mandiri yang dapat bekerja sendiri, memilih gambar scratch dasar akan memungkinkan Anda untuk meminimalkan ukuran wadah.

Gunakan bangunan multi-tahap


Pembangunan multi-tahap telah menjadi fokus perhatian sejak Docker 05/17. Itu adalah kesempatan yang telah dinanti sejak lama. Ini memungkinkan pembuat gambar untuk meninggalkan skrip mereka sendiri untuk membuat gambar dan mengimplementasikan semua yang mereka butuhkan menggunakan format Dockerfile terkenal.

Secara umum, majelis multi-tahap dapat dianggap sebagai menggabungkan beberapa Dockerfile , atau sebagai Dockerfile , yang memiliki beberapa instruksi FROM .

Sebelum munculnya majelis multi-tahap, jika Anda harus membuat perakitan proyek Anda dan mendistribusikannya dalam wadah menggunakan Dockerfile , maka Anda mungkin perlu melakukan proses perakitan, yang akan mengarah pada penampilan wadah, seperti yang ditunjukkan di bawah ini:


Bangun dan distribusikan aplikasi tanpa menggunakan teknologi multi-stage build

Meskipun, dari sudut pandang teknis, semuanya dilakukan dengan benar, gambar akhir dan wadah yang dihasilkan diisi dengan lapisan yang dibuat dalam proses mempersiapkan bahan proyek. Dan lapisan-lapisan ini tidak diperlukan untuk membentuk lingkungan runtime proyek.

Majelis multistage memungkinkan Anda untuk memisahkan fase pembuatan dan persiapan bahan proyek dari lingkungan di mana kode proyek dijalankan.


Perakitan multi-tahap, pemisahan proses pembuatan dan persiapan bahan proyek dari lingkungan eksekusi

Pada saat yang sama, satu Dockerfile cukup untuk menggambarkan proses lengkap membangun proyek. Tetapi sekarang Anda dapat menyalin materi dari satu tahap ke tahap lainnya dan menyingkirkan data yang tidak perlu.

Majelis multistage memungkinkan Anda membuat majelis lintas-platform yang dapat digunakan berulang kali tanpa menggunakan skrip perakitan sendiri yang ditulis untuk sistem operasi tertentu. Ukuran akhir gambar dapat diminimalkan karena kemungkinan inklusi selektif dari bahan yang dihasilkan pada tahap sebelumnya dari proses perakitan gambar.

Ringkasan


Membuat gambar wadah Docker adalah proses yang sering harus dihadapi oleh programmer modern. Ada banyak sumber daya untuk membuat Dockerfile , dan Anda dapat menemukan banyak contoh file seperti itu di Internet. Tapi apa pun yang Anda gunakan, saat membuat Dockerfile Anda sendiri Dockerfile selalu layak untuk mempertimbangkan ukuran gambar yang dihasilkan.

Di sini kami melihat beberapa teknik untuk meminimalkan ukuran gambar Docker. Perhatian pada isi Dockerfile , termasuk hanya apa yang benar-benar Anda butuhkan, memilih gambar dasar yang tepat, menggunakan teknologi multi-stage build - semua ini dapat membantu secara serius mengurangi ukuran gambar Docker yang Anda buat.

PS Kami meluncurkan pasar di situs web RUVDS. Di pasar, gambar Docker dipasang dalam satu klik, Anda dapat memeriksa bagaimana wadah bekerja pada VPS , 3 hari untuk pengujian disediakan gratis untuk semua pelanggan baru.

Pembaca yang budiman! Bagaimana Anda mengoptimalkan ukuran gambar Docker Anda?

Source: https://habr.com/ru/post/id485650/


All Articles