Mereka paling masuk akal bagi saya dengan contoh ...
Memeriksa lapisan bangunan Anda sendiri dengan docker diff
Mari kita ambil contoh buatan Dockerfile:
FROM busybox
RUN mkdir /data
# imagine this is downloading source code
RUN dd if=/dev/zero bs=1024 count=1024 of=/data/one
RUN chmod -R 0777 /data
# imagine this is compiling the app
RUN dd if=/dev/zero bs=1024 count=1024 of=/data/two
RUN chmod -R 0777 /data
# and now this cleans up that downloaded source code
RUN rm /data/one
CMD ls -alh /data
Masing-masing ddperintah menghasilkan file 1M ke disk. Mari kita membangun gambar dengan bendera tambahan untuk menyimpan wadah sementara:
docker image build --rm=false .
Dalam output, Anda akan melihat masing-masing perintah yang berjalan terjadi dalam wadah sementara yang sekarang kami simpan alih-alih dihapus secara otomatis:
...
Step 2/7 : RUN mkdir /data
---> Running in 04c5fa1360b0
---> 9b4368667b8c
Step 3/7 : RUN dd if=/dev/zero bs=1024 count=1024 of=/data/one
---> Running in f1b72db3bfaa
1024+0 records in
1024+0 records out
1048576 bytes (1.0MB) copied, 0.006002 seconds, 166.6MB/s
---> ea2506fc6e11
Jika Anda menjalankan docker diffmasing-masing id wadah itu, Anda akan melihat file apa yang dibuat dalam wadah itu:
$ docker diff 04c5fa1360b0 # mkdir /data
A /data
$ docker diff f1b72db3bfaa # dd if=/dev/zero bs=1024 count=1024 of=/data/one
C /data
A /data/one
$ docker diff 81c607555a7d # chmod -R 0777 /data
C /data
C /data/one
$ docker diff 1bd249e1a47b # dd if=/dev/zero bs=1024 count=1024 of=/data/two
C /data
A /data/two
$ docker diff 038bd2bc5aea # chmod -R 0777 /data
C /data/one
C /data/two
$ docker diff 504c6e9b6637 # rm /data/one
C /data
D /data/one
Setiap baris diawali dengan Amenambahkan file, Cmenunjukkan perubahan ke file yang ada, dan Dmenunjukkan penghapusan.
Inilah bagian TL; DR
Masing-masing dari sistem berkas wadah di atas masuk ke dalam satu "lapisan" yang akan dirakit ketika Anda menjalankan gambar sebagai wadah. Seluruh file ada di setiap lapisan saat ada penambahan atau perubahan, sehingga setiap chmodperintah itu, meskipun hanya mengubah sedikit izin, menghasilkan seluruh file yang disalin ke lapisan berikutnya. File yang dihapus / data / satu masih di lapisan sebelumnya, sebenarnya 3 kali, dan akan disalin melalui jaringan dan disimpan dalam disk ketika Anda menarik gambar.
Meneliti gambar yang ada
Anda dapat melihat perintah yang digunakan untuk membuat lapisan gambar yang ada dengan docker historyperintah. Anda juga dapat menjalankan a docker image inspectpada gambar dan melihat daftar lapisan di bawah bagian RootFS.
Inilah sejarah untuk gambar di atas:
IMAGE CREATED CREATED BY SIZE COMMENT
a81cfb93008c 4 seconds ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "ls -… 0B
f36265598aef 5 seconds ago /bin/sh -c rm /data/one 0B
c79aff033b1c 7 seconds ago /bin/sh -c chmod -R 0777 /data 2.1MB
b821dfe9ea38 10 seconds ago /bin/sh -c dd if=/dev/zero bs=1024 count=102… 1.05MB
a5602b8e8c69 13 seconds ago /bin/sh -c chmod -R 0777 /data 1.05MB
08ec3c707b11 15 seconds ago /bin/sh -c dd if=/dev/zero bs=1024 count=102… 1.05MB
ed27832cb6c7 18 seconds ago /bin/sh -c mkdir /data 0B
22c2dd5ee85d 2 weeks ago /bin/sh -c #(nop) CMD ["sh"] 0B
<missing> 2 weeks ago /bin/sh -c #(nop) ADD file:2a4c44bdcb743a52f… 1.16MB
Lapisan terbaru tercantum di atas. Yang perlu diperhatikan, ada dua lapisan di bagian bawah yang cukup tua. Mereka berasal dari gambar busybox itu sendiri. Saat Anda membangun satu gambar, Anda mewarisi semua lapisan gambar yang Anda tentukan di FROMbaris. Ada juga lapisan yang ditambahkan untuk perubahan pada meta-data gambar, seperti CMDgaris. Mereka hampir tidak mengambil ruang apa pun dan lebih untuk menyimpan pengaturan apa yang berlaku untuk gambar yang Anda jalankan.
Mengapa lapisan?
Lapisan memiliki beberapa keunggulan. Pertama, mereka tidak berubah. Setelah dibuat, lapisan yang diidentifikasi oleh hasa sha256 tidak akan pernah berubah. Kekekalan itu memungkinkan gambar saling membangun dan memotong dengan aman. Jika dua dockerfiles memiliki himpunan garis awal yang sama, dan dibangun pada server yang sama, mereka akan berbagi himpunan lapisan awal yang sama, menghemat ruang disk. Itu juga berarti jika Anda membangun kembali gambar, dengan hanya beberapa baris terakhir Dockerfile mengalami perubahan, hanya lapisan-lapisan yang perlu dibangun kembali dan sisanya dapat digunakan kembali dari cache lapisan. Ini dapat membuat pembangunan kembali gambar buruh pelabuhan sangat cepat.
Di dalam sebuah wadah, Anda melihat sistem file gambar, tetapi sistem file itu tidak disalin. Di atas semua layer gambar itu, container me-mount sendiri layer sistem file read-write. Setiap pembacaan file turun melalui lapisan sampai menyentuh lapisan yang telah menandai file untuk dihapus, memiliki salinan file di lapisan itu, atau membaca kehabisan lapisan untuk mencari. Setiap tulisan membuat modifikasi dalam lapisan baca-tulis khusus wadah.
Mengurangi lapisan kembung
Salah satu kelemahan lapisan adalah membangun gambar yang menduplikasi file atau mengirim file yang dihapus di lapisan selanjutnya. Solusinya adalah sering menggabungkan beberapa perintah menjadi satu RUNperintah. Khususnya ketika Anda memodifikasi file yang sudah ada atau menghapus file, Anda ingin langkah-langkah tersebut berjalan di perintah yang sama di mana mereka pertama kali dibuat. Menulis ulang Dockerfile di atas akan terlihat seperti:
FROM busybox
RUN mkdir /data \
&& dd if=/dev/zero bs=1024 count=1024 of=/data/one \
&& chmod -R 0777 /data \
&& dd if=/dev/zero bs=1024 count=1024 of=/data/two \
&& chmod -R 0777 /data \
&& rm /data/one
CMD ls -alh /data
Dan jika Anda membandingkan gambar yang dihasilkan:
- busybox: ~ 1MB
- gambar pertama: ~ 6MB
- gambar kedua: ~ 2MB
Hanya dengan menggabungkan beberapa baris dalam contoh yang dibuat, kami mendapatkan konten yang dihasilkan sama di gambar kami, dan menyusut gambar kami dari 5MB menjadi hanya 1MB file yang Anda lihat di gambar akhir.