Gambar buruh pelabuhan sebenarnya adalah daftar yang terhubung dari lapisan sistem file. Setiap instruksi dalam Dockerfile membuat lapisan filesystem yang menjelaskan perbedaan dalam filesystem sebelum dan sesudah eksekusi instruksi yang sesuai. docker inspect
Sub - perintah ini dapat digunakan pada gambar buruh pelabuhan untuk mengungkapkan sifatnya sebagai daftar tautan dari lapisan sistem file.
Jumlah lapisan yang digunakan dalam suatu gambar adalah penting
- saat mendorong atau menarik gambar, karena hal itu mempengaruhi jumlah unggahan atau unduhan yang terjadi secara bersamaan.
- ketika memulai sebuah wadah, karena lapisan-lapisannya digabungkan bersama untuk menghasilkan sistem file yang digunakan dalam wadah tersebut; semakin banyak layer yang terlibat, semakin buruk kinerjanya, tetapi backend filesystem yang berbeda dipengaruhi secara berbeda oleh ini.
Ini memiliki beberapa konsekuensi untuk bagaimana gambar harus dibangun. Saran pertama dan paling penting yang bisa saya berikan adalah:
Saran # 1 Pastikan langkah-langkah pembuatan di mana kode sumber Anda terlibat datang selambat mungkin di Dockerfile dan tidak terikat dengan perintah sebelumnya menggunakan a &&
atau a ;
.
Alasan untuk ini, adalah bahwa semua langkah sebelumnya akan di-cache dan lapisan yang sesuai tidak perlu diunduh berulang kali. Ini berarti versi yang lebih cepat dan rilis yang lebih cepat, yang mungkin Anda inginkan. Cukup menarik, ternyata sulit untuk memanfaatkan cache buruh pelabuhan secara optimal.
Saran kedua saya kurang penting tetapi saya merasa sangat berguna dari sudut pandang pemeliharaan:
Nasihat # 2 Jangan menulis perintah kompleks di Dockerfile tetapi gunakan skrip yang akan disalin dan dieksekusi.
Sebuah Dockerfile mengikuti saran ini akan terlihat seperti
COPY apt_setup.sh /root/
RUN sh -x /root/apt_setup.sh
COPY install_pacakges.sh /root/
RUN sh -x /root/install_packages.sh
dan seterusnya. Saran mengikat beberapa perintah dengan &&
hanya memiliki ruang lingkup terbatas. Jauh lebih mudah untuk menulis dengan skrip, di mana Anda dapat menggunakan fungsi, dll untuk menghindari redundansi atau untuk keperluan dokumentasi.
Orang-orang tertarik dengan pra-prosesor dan bersedia menghindari overhead kecil yang disebabkan oleh COPY
langkah - langkah dan benar-benar menghasilkan Dockerfile di mana
COPY apt_setup.sh /root/
RUN sh -x /root/apt_setup.sh
urutan digantikan oleh
RUN base64 --decode … | sh -x
di mana …
adalah versi base64-encoded dari apt_setup.sh
.
Saran ketiga saya adalah untuk orang-orang yang ingin membatasi ukuran dan jumlah lapisan dengan biaya pembuatan yang lebih lama.
Saran # 3 Gunakan with
-idiom untuk menghindari file yang ada di lapisan perantara tetapi tidak di sistem file yang dihasilkan.
File yang ditambahkan oleh beberapa instruksi buruh pelabuhan dan dihapus oleh beberapa instruksi kemudian tidak ada dalam sistem berkas yang dihasilkan tetapi disebutkan dua kali dalam lapisan buruh pelabuhan yang merupakan gambar buruh pelabuhan dalam konstruksi. Sekali, dengan nama dan konten lengkap di lapisan yang dihasilkan dari instruksi menambahkannya, dan sekali sebagai pemberitahuan penghapusan di lapisan yang dihasilkan dari instruksi menghapusnya.
Sebagai contoh, anggap kita untuk sementara membutuhkan kompiler C dan beberapa gambar dan pertimbangkan
# !!! THIS DISPLAYS SOME PROBLEM --- DO NOT USE !!!
RUN apt-get install -y gcc
RUN gcc --version
RUN apt-get --purge autoremove -y gcc
(Contoh yang lebih realistis akan membangun beberapa perangkat lunak dengan kompiler alih-alih hanya menyatakan kehadirannya dengan --version
bendera.)
Cuplikan Dockerfile membuat tiga lapisan, yang pertama berisi suite gcc lengkap sehingga meskipun tidak ada dalam sistem file akhir, data yang sesuai masih merupakan bagian dari gambar dengan cara yang sama dan perlu diunduh, diunggah dan dibongkar setiap kali gambar akhir adalah.
The with
-idiom adalah bentuk umum dalam pemrograman fungsional dengan kepemilikan sumber daya isolat dan sumber daya melepaskan dari logika menggunakannya. Sangat mudah untuk memindahkan idiom ini menjadi shell-scripting, dan kita dapat menguraikan kembali perintah sebelumnya sebagai skrip berikut, untuk digunakan dengan COPY & RUN
seperti pada Saran # 2.
# with_c_compiler SIMPLE-COMMAND
# Execute SIMPLE-COMMAND in a sub-shell with gcc being available.
with_c_compiler()
(
set -e
apt-get install -y gcc
"$@"
trap 'apt-get --purge autoremove -y gcc' EXIT
)
with_c_compiler\
gcc --version
Perintah kompleks dapat diubah menjadi fungsi sehingga dapat diumpankan ke with_c_compiler
. Dimungkinkan juga untuk melakukan panggilan ke beberapa with_whatever
fungsi, tetapi mungkin tidak terlalu diinginkan. (Menggunakan lebih banyak fitur esoteris dari shell, tentu saja memungkinkan untuk membuat with_c_compiler
perintah kompleks, tetapi dalam semua aspek lebih baik untuk membungkus perintah kompleks ini ke dalam fungsi.)
Jika kita ingin mengabaikan Saran # 2, cuplikan Dockerfile yang dihasilkan akan menjadi
RUN apt-get install -y gcc\
&& gcc --version\
&& apt-get --purge autoremove -y gcc
yang tidak begitu mudah dibaca dan dipelihara karena kebingungan. Lihat bagaimana varian skrip shell gcc --version
mengeluarkan penekanan pada bagian penting sementara &&
varian berantai mengubur bagian itu di tengah kebisingan.