Saya membuat gambar sederhana melalui Dockerfile dari Fedora (awalnya 320 MB).
Menambahkan Nano (editor kecil ini berukuran 1MB), dan ukuran gambar telah meningkat hingga 530 MB. Saya telah menambahkan Git di atas itu (30-ish MB), dan kemudian ukuran gambar saya-roket ke 830 MB.
Bukankah itu gila?
Saya sudah mencoba mengekspor dan mengimpor wadah untuk menghapus histori / gambar antara. Upaya ini menghemat hingga 25 MB, sekarang ukuran gambar saya adalah 804 MB. Saya juga telah mencoba menjalankan banyak perintah pada satu RUN
, tetapi saya masih mendapatkan 830MB awal yang sama.
Saya ragu apakah layak menggunakan Docker sama sekali. Maksudku, aku hampir tidak menginstal apa pun dan aku memukul lebih dari 1GB. Jika saya harus menambahkan beberapa hal serius seperti database dan sebagainya saya mungkin kehabisan ruang disk.
Adakah yang menderita ukuran gambar yang konyol? Bagaimana Anda menghadapinya?
Kecuali Dockerfile saya salah besar?
FROM fedora:latest
MAINTAINER Me NotYou <[email protected]>
RUN yum -y install nano
RUN yum -y install git
tapi sulit membayangkan apa yang salah di sini.
yum clean all
ada efek pada ukuran?docker images
yang pada kolom terakhir menyatakan besar 830MB. Saya mungkin tidak menyadari apa sebenarnya ukuran gambar saya karena perintah gambar buruh pelabuhan menyatakan bahwa 830MB ini adalah ukuran virtual. Tapi sekali lagi, berapa ukuran gambar yang sebenarnya?Jawaban:
Seperti yang dikatakan @rexposadas, gambar menyertakan semua layer dan setiap layer menyertakan semua dependensi untuk apa yang Anda instal. Penting juga untuk dicatat bahwa gambar dasar (seperti
fedora:latest
cenderung sangat sederhana). Anda mungkin akan terkejut dengan banyaknya dependensi yang dimiliki oleh perangkat lunak yang Anda instal.Saya dapat membuat instalasi Anda secara signifikan lebih kecil dengan menambahkan
yum -y clean all
ke setiap baris:Adalah penting untuk melakukan itu untuk setiap RUN, sebelum layer dikomit, atau yang lainnya tidak benar-benar menghapus data. Yaitu, dalam sistem file union / copy-on-write, pembersihan pada akhirnya tidak benar-benar mengurangi penggunaan sistem file karena data nyata sudah berkomitmen untuk lapisan bawah. Untuk menyiasatinya, Anda harus membersihkan setiap lapisan.
sumber
docker images
). Apakah mungkin untuk menghapus / menghapus / menghancurkan layer-layer lama itu? Untuk lebih spesifik: saya ingin benar-benar menghapus (berdasarkan contoh Anda) gambar: 172743bd5d60, 3f2fed40e4b0, fd241224e9cf, 511136ea3c5a dari sejarah, sehingga ukuran gambar virtual saya kurang lebih sama dengan ukuran gambar akhir, di sini ~ 260MB .docker export
dan sekalidocker import
lagi. Itu akan meratakan lapisan. Saya tidak berpikir itu akan mengurangi ukuran, tetapi saya bisa saja salah.docker ps -s
menunjukkan ukuran nyata pada HDD yang dalam kasus saya adalah-1B
. Kedengarannya masuk akal, minus 1 Byte . Saya mendapatkan ruang pada HDD ... tampaknya sah.Gambar Docker tidak besar, Anda hanya membangun gambar besar.
The
scratch
gambar 0B dan Anda dapat menggunakannya untuk paket sampai kode Anda jika Anda dapat mengkompilasi kode Anda menjadi biner statis. Misalnya, Anda dapat mengkompilasi program Go dan paket itu di atasscratch
untuk membuat gambar yang sepenuhnya dapat digunakan kurang dari 5MB.Kuncinya adalah untuk tidak menggunakan gambar Docker resmi, mereka terlalu besar. Scratch juga tidak terlalu praktis, jadi saya sarankan menggunakan Alpine Linux sebagai gambar dasar Anda. Ini ~ 5MB, maka hanya tambahkan apa yang diperlukan untuk aplikasi Anda. Posting ini tentang Microcontainers menunjukkan kepada Anda bagaimana membangun basis gambar yang sangat kecil di Alpine.
UPDATE: gambar Docker resmi didasarkan pada alpine sekarang sehingga baik untuk digunakan sekarang.
sumber
Berikut beberapa hal yang dapat Anda lakukan :
RUN
perintah di mana Anda bisa. Masukkan sebanyak mungkin possbile ke dalam satuRUN
perintah (menggunakan&&
)Dengan ini DAN rekomendasi dari @Andy dan @michau saya dapat mengubah ukuran gambar nodejs saya dari 1,062 GB menjadi 542 MB.
Sunting: Satu hal lagi yang penting: "Butuh beberapa saat untuk benar-benar memahami bahwa setiap perintah Dockerfile membuat wadah baru dengan delta. [...] Tidak masalah jika Anda rm -rf file dalam perintah kemudian; mereka terus ada di beberapa wadah lapisan menengah. " Jadi sekarang saya berhasil menempatkan
apt-get install
,wget
,npm install
(dengan dependensi git) danapt-get remove
menjadi satuRUN
perintah, jadi sekarang gambar saya hanya memiliki 438 MB.Edit 29/06/17
Dengan Docker v17.06 hadir fitur baru untuk Dockerfiles: Anda dapat memiliki beberapa
FROM
pernyataan di dalam satu Dockerfile dan hanya hal-hal dari yang terakhir yangFROM
akan ada dalam gambar Docker terakhir Anda. Ini berguna untuk mengurangi ukuran gambar, misalnya:Akan menghasilkan gambar yang hanya memiliki gambar dasar nodejs ditambah konten dari / var / my-project dari langkah pertama - tetapi tanpa ruby, python, git, openssh dan gcc!
sumber
Ya, ukuran itu konyol, dan saya benar-benar tidak tahu mengapa begitu sedikit orang yang memperhatikan hal itu.
Saya membuat gambar Ubuntu yang sebenarnya minimal (tidak seperti gambar "minimal" lainnya). Disebut
textlab/ubuntu-essential
dan memiliki 60 MB.Gambar di atas adalah 82 MB setelah menginstal nano.
Git memiliki lebih banyak prasyarat, sehingga gambarnya menjadi lebih besar, sekitar 192 MB. Itu masih kurang dari ukuran awal sebagian besar gambar.
Anda juga dapat melihat skrip yang saya tulis untuk membuat gambar Ubuntu minimal untuk Docker . Anda mungkin dapat mengadaptasinya ke Fedora, tetapi saya tidak yakin seberapa banyak Anda dapat menghapus.
sumber
Berikut ini banyak membantu saya:
Setelah menghapus paket yang tidak digunakan (mis. Redis 1200 mb dibebaskan) di dalam wadah saya, saya telah melakukan hal berikut:
Lapisan menjadi rata. Ukuran gambar baru akan lebih kecil karena saya telah menghapus paket dari wadah seperti yang disebutkan di atas.
Ini membutuhkan banyak waktu untuk memahami hal ini dan itulah sebabnya saya menambahkan komentar saya.
sumber
docker export <CONTAINER ID> | docker import - some-image-name:latest
Untuk praktik terbaik, Anda harus menjalankan perintah RUN tunggal, karena setiap instruksi RUN di Dockerfile menulis lapisan baru pada gambar dan setiap lapisan membutuhkan ruang ekstra pada disk. Untuk menjaga agar jumlah layer minimum, manipulasi file seperti menginstal, memindahkan, mengekstraksi, menghapus, dll, idealnya harus dibuat di bawah instruksi RUN tunggal
sumber
Docker Squash adalah solusi yang sangat bagus untuk ini. kamu bisa
$packagemanager clean
pada langkah terakhir alih-alih di setiap baris dan kemudian jalankan squash buruh pelabuhan untuk menyingkirkan semua layer.https://github.com/jwilder/docker-squash
sumber
Ya sistem lapisannya cukup mengejutkan. Jika Anda memiliki gambar dasar dan Anda menambahkannya dengan melakukan hal berikut:
Gambar memiliki ukuran yang persis sama. Itu pada dasarnya berarti, Anda harus mengatur untuk menjalankan langkah-langkah RUN Anda banyak mengekstrak, menginstal dan membersihkan sihir untuk membuat gambar sekecil perangkat lunak yang diinstal.
Ini membuat hidup jauh lebih sulit ...
DockerBuild tidak memiliki langkah RUN tanpa komit.
sumber