GNU/Linux >> Belajar Linux >  >> Linux

Mempercepat pembuatan gambar container dengan Buildah

Beberapa bulan yang lalu, saya menulis artikel tentang mempercepat pembuatan container di dalam container. Artikel tersebut berkonsentrasi pada kecepatan menarik gambar container, dan berbagai cara untuk mengisi penyimpanan gambar sebelumnya, menggunakan pemasangan volume dari host dan konsep Buildah tentang "penyimpanan tambahan".

Buildah adalah fitur command-line untuk membuat image yang kompatibel dengan Open Container Initiative (yang berarti kompatibel dengan Docker dan Kubernetes juga) dengan cepat dan mudah. Buildah mudah dimasukkan ke dalam skrip dan pipeline build, dan yang terpenting, buildah tidak memerlukan daemon container yang sedang berjalan untuk membangun image-nya.

Artikel ini akan membahas masalah kedua dengan kecepatan build saat menggunakan dnf /yum perintah di dalam container. Perhatikan bahwa dalam artikel ini saya akan menggunakan nama dnf (yang merupakan nama upstream) dan bukan yang digunakan oleh beberapa downstream (yum ) Komentar ini berlaku untuk dnf dan yum .

Kecepatan unduh

Pernahkah Anda memperhatikan bahwa terkadang saat Anda menjalankan dnf -y update atau dnf -y install untuk pertama kalinya dalam beberapa saat, perintah dijeda untuk waktu yang lama bahkan sebelum mulai menurunkan RPM? Apa yang terjadi?

Hal pertama yang dnf lakukan adalah mengunduh file cache yang sangat besar. File-file ini ditulis dalam XML dan berisi setiap paket dalam repositori jarak jauh, termasuk banyak data tentang paket tersebut. Mereka bahkan berisi setiap jalur dalam paket. Data ini diperlukan agar ketika Anda dapat menjalankan sesuatu seperti dnf -y install /usr/bin/httpd lalu dnf mengetahui paket yang akan diinstal. Banyak paket berisi perintah seperti (requires: /usr/bin/sendmail ) yang memanfaatkan fitur ini, memungkinkan dnf untuk menarik paket yang sesuai untuk memenuhi kebutuhan.

Menarik file-file besar ini—dan yang lebih penting, memproses file-file ini—bisa memakan waktu lebih dari satu menit. Data ini digunakan oleh libsolv , jadi harus dikonversi ke solv format, yang lambat. Kecepatan bukanlah masalah besar jika Anda hanya melakukannya secara berkala di host Anda, tetapi dalam hal membangun container, ini adalah masalah yang jauh lebih besar.

Sintaks Dockerfile

Meskipun Buildah memungkinkan Anda membuat image container langsung di shell, kebanyakan orang menggunakan Dockerfiles dan Containerfiles untuk membuat container dan menentukan resep gambar yang dapat direproduksi. Buildah default untuk mencari Containerfile dan Dockerfile sekarang. Masing-masing memiliki sintaks yang sama, jadi saya akan menggunakan Containerfile untuk sisa dokumen ini.

Hal yang umum dilakukan di Containerfile adalah dengan menggunakan sintaks seperti:

FROM ubi8  
RUN dnf -y update; dnf -y install nginx; dnf -y clean all  
…  
RUN dnf -y install jboss; dnf -y clean all  

Mari kita periksa dnf garis. dnf pertama baris:

(dnf -y update; dnf -y install nginx; dnf -y clean all ):

  1. Memperbarui semua paket dalam penampung.
  2. Menginstal paket yang dipilih nginx .
  3. Membersihkan semua.

Sejak ubi8 gambar mungkin dibuat beberapa waktu lalu dan /var/cache/dnf direktori mungkin tidak ada di dalam gambar kontainer, dnf harus menarik file cache XML dan memprosesnya. Kemudian, dnf menginstal paket yang sebenarnya sebelum dnf -y clean all menghapus semua data berlebih yang ditempatkan oleh perintah sebelumnya ke dalam gambar seperti file log dan cache.

Pengguna disarankan untuk menjalankan clean all untuk menjaga gambar sekecil mungkin. Setiap RUN perintah membuat layer baru, dan bahkan jika Anda menghapus konten di RUN later perintah, lapisan awal akan berisi semua konten. Ini berarti bahwa setiap orang yang pernah menarik gambar Anda pada akhirnya akan menarik file log dan cache. Sekarang, jika Containerfile Anda berisi satu atau lebih dnf perintah, Anda akan membayar harga berulang kali. Tidak hanya itu tetapi setiap kali Anda membangun kembali gambar ini, Anda akan membayar harga itu lagi. Jika Anda berada di server build, setiap image container yang Anda buat akan mendownload file XML ini berulang kali, membuang banyak sumber daya dan waktu.

Bangun dengan dudukan overlay

Kami melihat masalah yang dijelaskan di atas dan berpikir kami dapat menangani ini dengan cara yang lebih baik. Tidak bisakah kita menarik data XML ke host, memprosesnya di host, dan memasang volume ke dalam container? Mungkin kita bisa mengatur tugas cron atau systemd timer yang melakukan dnf makecache sekali untuk setiap versi OS tempat Anda akan membuat gambar penampung? Anda dapat menjalankan tugas ini sekali atau beberapa kali sehari di host, lalu meminta semua volume pembuat penampung memasang cache yang sesuai ke dalam penampung buildah.

Nah, Buildah mendukung direktori pemasangan volume dari host ke dalam wadah. Itu harus menyelesaikan masalah, dan memang begitu. NAMUN, kontainer sering ingin menulis ke direktori ini, jika mereka harus memperbarui cache, maka cache perlu dipasang ke dalam kontainer baca/tulis. Hal ini menyebabkan lubang keamanan yang sangat besar. Bayangkan situasi di mana container build yang tidak bersahabat menulis konten ke cache ini yang dibaca oleh container builder berikutnya. Itu mungkin bisa menipu wadah kedua untuk menginstal perangkat lunak yang diretas. Kami membutuhkan solusi di mana konten dipasang ke dalam wadah, tidak dapat ditulis oleh wadah, namun tetap ditulis dari perspektif wadah. Pada dasarnya inilah titik pemasangan Overlay.

Sistem file overlay memasang lower direktori dan kemudian melampirkan upper direktori ke merged titik pemasangan. Ketika sebuah proses menulis ke file baru ke merged direktori, file baru akan ditulis ke upper direktori. Ketika sebuah proses memodifikasi file yang ada di lower direktori, kernel menyalin file dari lower direktori ke upper direktori dan memungkinkan proses untuk memodifikasi file di upper direktori.

Kami memperkenalkan konsep pemasangan Overlay ke Buildah. Sekarang Anda dapat menjalankan build dengan

buildah bud -v /var/cache/dnf:/var/cache/dnf:O -f /tmp/Containerfile /tmp  

Dnf di dalam wadah masih akan memeriksa untuk melihat apakah ada konten yang lebih baru di repo, dan akan menarik konten ke bawah jika ada. Tapi jika konten di host sudah up to date, maka akan cepat menggunakan cache host. Saya sarankan Anda memperbarui cache host setidaknya sekali sehari.

Satu fitur tambahan yang kami tambahkan untuk pemasangan Buildah Overlay adalah menghancurkan upper direktori pada setiap RUN pengarahan. Ingat dalam contoh kita, kita menggunakan beberapa RUN perintah yang masing-masing menjalankan dnf -y clean all . dnf -y clean all perintah menyebabkan upper direktori untuk menampilkan semua konten dari bawah sebagai dihapus. Jika berikutnya dnf perintah berbagi bagian atas sebelumnya akan melihat cache kosong dan harus menarik penyimpanan data XML dan memprosesnya. Menghapus upper direktori berarti bahwa setiap dnf perintah akan kembali melihat lower direktori dari host, dan terus berbagi cache host.

Perbedaan kecepatan

Saya akan membuat Containerfile sederhana berisi dua dnf menjalankan perintah.

FROM fedora:31  
RUN dnf -y install net-utils; dnf -y clean all  
RUN dnf -y install iputils; dnf -y clean all  

Menjalankan ini secara lokal di kotak Fedora 31 saya

# time -f "Elapsed Time: %E" buildah bud -f Containerfile .  
STEP 1: FROM fedora:31  
STEP 2: RUN dnf -y install procps-ng; dnf -y clean all  
Fedora Modular 31 - x86_64 2.0 MB/s | 5.2 MB 00:02  
Fedora Modular 31 - x86_64 - Updates 1.6 MB/s | 4.0 MB 00:02  
Fedora 31 - x86_64 - Updates 4.2 MB/s | 19 MB 00:04  
Fedora 31 - x86_64 1.8 MB/s | 71 MB 00:39  
Last metadata expiration check: 0:00:01 ago on Wed Feb 5 13:55:54 2020.  
Dependencies resolved.  
================================================================================  
Package Architecture Version Repository Size  
================================================================================  
Installing:  
procps-ng x86_64 3.3.15-6.fc31 fedora 326 k

Transaction Summary  
================================================================================  
Install 1 Package

Total download size: 326 k  
Installed size: 966 k  
Downloading Packages:  
procps-ng-3.3.15-6.fc31.x86_64.rpm 375 kB/s | 326 kB 00:00  
--------------------------------------------------------------------------------  
Total 218 kB/s | 326 kB 00:01  
Running transaction check  
Transaction check succeeded.  
Running transaction test  
Transaction test succeeded.  
Running transaction  
Preparing : 1/1  
Installing : procps-ng-3.3.15-6.fc31.x86_64 1/1  
Running scriptlet: procps-ng-3.3.15-6.fc31.x86_64 1/1  
Verifying : procps-ng-3.3.15-6.fc31.x86_64 1/1

Installed:  
procps-ng-3.3.15-6.fc31.x86_64

Complete!  
33 files removed  
STEP 3: RUN dnf -y install iputils; dnf -y clean all  
Fedora Modular 31 - x86_64 741 kB/s | 5.2 MB 00:07  
Fedora Modular 31 - x86_64 - Updates 928 kB/s | 4.0 MB 00:04  
Fedora 31 - x86_64 - Updates 3.8 MB/s | 19 MB 00:05  
Fedora 31 - x86_64 7.9 MB/s | 71 MB 00:08  
Last metadata expiration check: 0:00:01 ago on Wed Feb 5 13:57:13 2020.  
Dependencies resolved.  
================================================================================  
Package Architecture Version Repository Size  
================================================================================  
Installing:  
iputils x86_64 20190515-3.fc31 fedora 141 k

Transaction Summary  
================================================================================  
Install 1 Package

Total download size: 141 k  
Installed size: 387 k  
Downloading Packages:  
iputils-20190515-3.fc31.x86_64.rpm 252 kB/s | 141 kB 00:00  
--------------------------------------------------------------------------------  
Total 141 kB/s | 141 kB 00:01  
Running transaction check  
Transaction check succeeded.  
Running transaction test  
Transaction test succeeded.  
Running transaction  
Preparing : 1/1  
Installing : iputils-20190515-3.fc31.x86_64 1/1  
Running scriptlet: iputils-20190515-3.fc31.x86_64 1/1  
Verifying : iputils-20190515-3.fc31.x86_64 1/1

Installed:  
iputils-20190515-3.fc31.x86_64

Complete!  
33 files removed  
STEP 4: COMMIT  
Getting image source signatures  
Copying blob ac0b803c5612 skipped: already exists  
Copying blob 922380d685bc done  
Copying config 566e2afbb4 done  
Writing manifest to image destination  
Storing signatures  
566e2afbb417f0119109578a87950250b566a3b4908868627975a4c7428accfb  
566e2afbb417f0119109578a87950250b566a3b4908868627975a4c7428accfb

Elapsed Time: 2:15.00  

Proses ini membutuhkan waktu 2 menit 15 detik untuk membuat image container baru dengan dua paket baru.

Sekarang mari kita coba ini dengan mount Overlay dari host.

# dnf -y makecache  
# time -f "Elapsed Time: %E" buildah bud -v /var/cache/dnf:/var/cache/dnf:O -f Containerfile .  
STEP 1: FROM fedora:31  
STEP 2: RUN dnf -y install procps-ng; dnf -y clean all  
Last metadata expiration check: 0:02:34 ago on Wed Feb 5 13:51:54 2020.  
Dependencies resolved.  
================================================================================  
Package Architecture Version Repository Size  
================================================================================  
Installing:  
procps-ng x86_64 3.3.15-6.fc31 fedora 326 k

Transaction Summary  
================================================================================  
Install 1 Package

Total download size: 326 k  
Installed size: 966 k  
Downloading Packages:  
procps-ng-3.3.15-6.fc31.x86_64.rpm 496 kB/s | 326 kB 00:00  
--------------------------------------------------------------------------------  
Total 245 kB/s | 326 kB 00:01  
Running transaction check  
Transaction check succeeded.  
Running transaction test  
Transaction test succeeded.  
Running transaction  
Preparing : 1/1  
Installing : procps-ng-3.3.15-6.fc31.x86_64 1/1  
Running scriptlet: procps-ng-3.3.15-6.fc31.x86_64 1/1  
Verifying : procps-ng-3.3.15-6.fc31.x86_64 1/1

Installed:  
procps-ng-3.3.15-6.fc31.x86_64

Complete!  
285 files removed  
STEP 3: RUN dnf -y install iputils; dnf -y clean all  
Last metadata expiration check: 0:02:41 ago on Wed Feb 5 13:51:54 2020.  
Dependencies resolved.  
================================================================================  
Package Architecture Version Repository Size  
================================================================================  
Installing:  
iputils x86_64 20190515-3.fc31 fedora 141 k

Transaction Summary  
================================================================================  
Install 1 Package

Total download size: 141 k  
Installed size: 387 k  
Downloading Packages:  
iputils-20190515-3.fc31.x86_64.rpm 556 kB/s | 141 kB 00:00  
--------------------------------------------------------------------------------  
Total 222 kB/s | 141 kB 00:00  
Running transaction check  
Transaction check succeeded.  
Running transaction test  
Transaction test succeeded.  
Running transaction  
Preparing : 1/1  
Installing : iputils-20190515-3.fc31.x86_64 1/1  
Running scriptlet: iputils-20190515-3.fc31.x86_64 1/1  
Verifying : iputils-20190515-3.fc31.x86_64 1/1

Installed:  
iputils-20190515-3.fc31.x86_64

Complete!  
285 files removed  
STEP 4: COMMIT  
Getting image source signatures  
Copying blob ac0b803c5612 skipped: already exists  
Copying blob 524bb3b83d61 done  
Copying config 0f82aa6064 done  
Writing manifest to image destination  
Storing signatures  
0f82aa6064814ff3dcb603c34c75e516e00817811681b83b8632f3e9b694e518  
0f82aa6064814ff3dcb603c34c75e516e00817811681b83b8632f3e9b694e518  
Elapsed Time: 0.17.44  

Dengan pemasangan Overlay, kami dapat membuat gambar baru dengan dua paket tambahan dalam 17 detik, bukan 2 menit dan 15 detik. Itu hampir 8 kali lebih cepat untuk membuat image container yang sama.

Sekarang ini menunjukkan bahwa jika Anda membuat gambar pada sistem operasi host yang memiliki dnf metadata pra-cache Anda dapat mempercepat kecepatan instal dengan jumlah yang BESAR. Tetapi bagaimana jika sistem build Anda membuat image untuk versi OS lainnya? Katakanlah Anda ingin membuat gambar untuk Fedora 30 serta Fedora 31. Catatan:ini juga akan bekerja pada sistem RHEL8, di mana Anda mungkin ingin membuat gambar RHEL7 dan bahkan mungkin RHEL6.
Dnf menyertakan fitur keren di mana Anda dapat menentukan rilis berbeda saat menarik konten, menggunakan --releasever pilihan. Dnf juga memungkinkan Anda untuk menentukan direktori alternatif untuk menempatkan cachedir, --setopt=cachedir .

Dalam contoh berikut, saya akan menurunkan dua cache pada host dan kemudian menggunakan Buildah dalam mode baris perintah.

# dnf -y makecache --releasever=31 --setopt=cachedir=/var/cache/dnf/31  
# dnf -y makecache --releasever=30 --setopt=cachedir=/var/cache/dnf/30  
# ctr31=$(buildah from fedora:31)  
# time -f 'Elapsed Time: %E' buildah run -v /var/cache/dnf/31:/var/cache/dnf:O ${ctr31} dnf -y install iputils  
Last metadata expiration check: 0:00:15 ago on Wed Feb 5 14:17:41 2020.  
Dependencies resolved.  
================================================================================  
Package Architecture Version Repository Size  
================================================================================  
Installing:  
iputils x86_64 20190515-3.fc31 fedora 141 k

Transaction Summary  
================================================================================  
Install 1 Package

Total download size: 141 k  
Installed size: 387 k  
Downloading Packages:  
iputils-20190515-3.fc31.x86_64.rpm 192 kB/s | 141 kB 00:00  
--------------------------------------------------------------------------------  
Total 107 kB/s | 141 kB 00:01  
Running transaction check  
Transaction check succeeded.  
Running transaction test  
Transaction test succeeded.  
Running transaction  
Preparing : 1/1  
Installing : iputils-20190515-3.fc31.x86_64 1/1  
Running scriptlet: iputils-20190515-3.fc31.x86_64 1/1  
Verifying : iputils-20190515-3.fc31.x86_64 1/1

Installed:  
iputils-20190515-3.fc31.x86_64

Complete!  
Elapsed Time: 0:06.85

# ctr30=$(buildah from fedora:30)  
# time -f 'Elapsed Time: %E' buildah run -v /var/cache/dnf/30:/var/cache/dnf:O ${ctr30} dnf -y install iputils  
Last metadata expiration check: 0:00:15 ago on Wed Feb 5 14:17:47 2020.  
Dependencies resolved.  
================================================================================  
Package Architecture Version Repository Size  
================================================================================  
Installing:  
iputils x86_64 20180629-4.fc30 fedora 123 k

Transaction Summary  
================================================================================  
Install 1 Package

Total download size: 123 k  
Installed size: 351 k  
Downloading Packages:  
iputils-20180629-4.fc30.x86_64.rpm 370 kB/s | 123 kB 00:00  
--------------------------------------------------------------------------------  
Total 138 kB/s | 123 kB 00:00  
Running transaction check  
Transaction check succeeded.  
Running transaction test  
Transaction test succeeded.  
Running transaction  
Preparing : 1/1  
Installing : iputils-20180629-4.fc30.x86_64 1/1  
Running scriptlet: iputils-20180629-4.fc30.x86_64 1/1  
Verifying : iputils-20180629-4.fc30.x86_64 1/1

Installed:  
iputils-20180629-4.fc30.x86_64

Complete!  
Elapsed Time: 0:08.88  

Seperti yang Anda lihat, kami dapat menjalankan container Buildah menggunakan dnf cache dari dua rilis Fedora berbeda dari host build yang sama dan container untuk Fedora 31 membutuhkan waktu 6+ detik dan build Fedora 30 membutuhkan waktu 8+ detik.

Catatan:Saya memilih subdirektori /var/cache/dnf untuk file cache, untuk memastikan label SELinux sudah benar. Hanya menjalankan dnf clean all tidak akan membersihkan /var/cache/dnf/31 . Anda perlu menjalankan dnf clean all --setopt=cachedir=/var/cache/dnf/31 untuk membersihkan file cache repo dengan benar, tetapi beberapa artefak akan tetap ada (kunci gpg, direktori kosong).

Sekarang hanya untuk melihat berapa lama waktu yang dibutuhkan untuk menjalankan build di Fedora 31 tanpa mount Overlay.

# ctr31=$(buildah from fedora:31)  
# time -f 'Elapsed Time: %E' buildah run ${ctr31} dnf -y install iputils  
Fedora Modular 31 - x86_64 1.2 MB/s | 5.2 MB 00:04  
Fedora Modular 31 - x86_64 - Updates 875 kB/s | 4.0 MB 00:04  
Fedora 31 - x86_64 - Updates 2.4 MB/s | 19 MB 00:07  
Fedora 31 - x86_64 1.7 MB/s | 71 MB 00:41  
Dependencies resolved.  
================================================================================  
Package Architecture Version Repository Size  
================================================================================  
Installing:  
iputils x86_64 20190515-3.fc31 fedora 141 k

Transaction Summary  
================================================================================  
Install 1 Package

Total download size: 141 k  
Installed size: 387 k  
Downloading Packages:  
iputils-20190515-3.fc31.x86_64.rpm 279 kB/s | 141 kB 00:00  
--------------------------------------------------------------------------------  
Total 129 kB/s | 141 kB 00:01  
Running transaction check  
Transaction check succeeded.  
Running transaction test  
Transaction test succeeded.  
Running transaction  
Preparing : 1/1  
Installing : iputils-20190515-3.fc31.x86_64 1/1  
Running scriptlet: iputils-20190515-3.fc31.x86_64 1/1  
Verifying : iputils-20190515-3.fc31.x86_64 1/1

Installed:  
iputils-20190515-3.fc31.x86_64

Complete!  
Elapsed Time: 1:29.85  

Dalam hal ini, butuh hampir 1,5 menit untuk menjalankan wadah yang sama. Buildah dengan mount Overlay berjalan 14 kali lebih cepat.

Wadah Tanpa Root

Semua contoh saya sampai sekarang telah menjalankan build menggunakan Containerfiles sebagai akar. Tetapi Anda juga dapat melakukan ini dengan wadah tanpa akar. Dalam beberapa contoh berikutnya, saya akan meminta Buildah menjalankan container menggunakan buildah run sintaks untuk mendemonstrasikan menggunakan cache.

Menjalankan

$ buildah run -v /var/cache/dnf/30:/var/cache/dnf:O ${ctr30} dnf -y install iputils  

berfungsi dengan baik. Selama pengguna dapat membaca /var/cache/dnf/30 direktori, lower direktori dapat dibaca. Tetapi Anda harus mengandalkan sesuatu pada host untuk memperbarui cache secara berkala.

Jika pengguna mau, mereka bahkan dapat menggunakan dnf untuk membuat cache di direktori home mereka.

$ dnf -y makecache --releasever=30 --setopt=cachedir=$HOME/dnfcache  
$ chcon --reference /var/cache/dnf -R $HOME/dnfcache  
$ ctr30=$(buildah from fedora:30)  
$ buildah run -v $HOME/dnfcache:/var/cache/dnf:O ${ctr30} dnf -y install iputils  

Perhatikan saya harus mengubah label SELinux dari $HOME/dnfcache direktori sehingga SELinux akan memungkinkan wadah untuk membaca lower direktori untuk pemasangan Overlay.

Kesimpulan

Mempercepat pembuatan container memerlukan pemahaman tentang apa yang terjadi saat Anda menginstal paket. Pra-cache dnf data di host dan menggunakan pemasangan Overlay untuk memasang cache ke dalam wadah dengan Buildah dapat sangat meningkatkan kecepatan pembangunan dan mengurangi jumlah sumber daya yang diperlukan untuk mendukung kumpulan bangunan.

Buildah sama dengan kesederhanaan tetapi juga memiliki beberapa fitur hebat seperti Overlay mounts dan additional stores yang dapat membantu Anda mempercepat pembuatan gambar container.

[ Baru mengenal container? Unduh Containers Primer dan pelajari dasar-dasar container Linux. ]


Linux
  1. Cara membuat gambar khusus dari wadah Docker

  2. Perbaiki citra sistem dengan DISM

  3. Gunakan status tugas dengan pencitraan server

  1. Optimalisasi gambar dengan webp

  2. Buat daftar semua file gambar grafik dengan find?

  3. Apa yang ada di dalam gambar/wadah Docker?

  1. Bangun wadah Anda sendiri di Linux

  2. Komit data dalam wadah mysql

  3. Cara menyalin gambar ISO ke USB dengan dd