Gambar Docker kecil yang percaya pada dirinya sendiri*

[referensi ke dongeng anak-anak Amerika "Mesin Kecil yang Bisa" - kira-kira. jalur]*

Gambar Docker kecil yang percaya pada dirinya sendiri*

Cara membuat image Docker kecil secara otomatis untuk kebutuhan Anda

Obsesi yang Tidak Biasa

Selama beberapa bulan terakhir, saya terobsesi dengan seberapa kecil image Docker dan aplikasinya masih berjalan?

Saya mengerti, idenya aneh.

Sebelum saya membahas detail dan teknisnya, saya ingin menjelaskan mengapa masalah ini sangat mengganggu saya, dan bagaimana hal ini mengkhawatirkan Anda.

Mengapa ukuran penting

Dengan mengurangi konten image Docker, kami mengurangi daftar kerentanan. Selain itu, kami membuat gambar lebih bersih karena hanya berisi apa yang diperlukan untuk menjalankan aplikasi.

Ada satu lagi keuntungan kecil - gambar diunduh sedikit lebih cepat, tetapi menurut saya, ini tidak begitu penting.

Harap diperhatikan: Jika Anda mengkhawatirkan ukurannya, Alpine terlihat kecil dan kemungkinan besar cocok untuk Anda.

Gambar tanpa distro

Proyek Distroless menawarkan pilihan gambar dasar "distroless", mereka tidak mengandung manajer paket, shell, dan utilitas lain yang biasa Anda lihat di baris perintah. Akibatnya, gunakan manajer paket seperti pip ΠΈ apt tidak akan berfungsi:

FROM gcr.io/distroless/python3
RUN  pip3 install numpy

Dockerfile menggunakan gambar distroless Python 3

Sending build context to Docker daemon  2.048kB
Step 1/2 : FROM gcr.io/distroless/python3
 ---> 556d570d5c53
Step 2/2 : RUN  pip3 install numpy
 ---> Running in dbfe5623f125
/bin/sh: 1: pip3: not found

Pip tidak ada dalam gambar

Biasanya masalah ini diselesaikan dengan build multi-tahap:

FROM python:3 as builder
RUN  pip3 install numpy

FROM gcr.io/distroless/python3
COPY --from=builder /usr/local/lib/python3.7/site-packages /usr/local/lib/python3.5/

Perakitan multi-tahap

Hasilnya adalah gambar berukuran 130MB. Lumayan! Sebagai perbandingan: gambar Python default berbobot 929 MB, dan gambar "lebih tipis" (3,7-slim) - 179MB, gambar pegunungan (3,7-alpine) adalah 98,6MB, sedangkan gambar distroless dasar yang digunakan dalam contoh adalah 50,9MB.

Cukup adil untuk menunjukkan bahwa dalam contoh sebelumnya kita menyalin seluruh direktori /usr/local/lib/python3.7/site-packages, yang mungkin berisi dependensi yang tidak kita perlukan. Meskipun jelas bahwa perbedaan ukuran dari semua gambar dasar Python yang ada berbeda-beda.

Pada saat penulisan, distroless Google tidak mendukung banyak image: Java dan Python masih dalam tahap percobaan, dan Python hanya ada untuk 2,7 dan 3,5.

Gambar kecil

Kembali ke obsesi saya membuat gambar kecil.

Secara umum, saya ingin melihat bagaimana gambar distroless dibuat. Proyek distroless menggunakan alat pembangunan Google bazel. Namun, menginstal Bazel dan menulis gambar Anda sendiri membutuhkan banyak usaha (dan sejujurnya, menciptakan kembali roda itu menyenangkan dan mendidik). Saya ingin menyederhanakan pembuatan gambar yang lebih kecil: tindakan membuat gambar harus sangat sederhana, dangkal. Agar tidak ada file konfigurasi untuk Anda, cukup satu baris di konsol: просто ΡΠΎΠ±Ρ€Π°Ρ‚ΡŒ ΠΎΠ±Ρ€Π°Π· для <ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅>.

Jadi, jika Anda ingin membuat gambar Anda sendiri, ketahuilah: ada gambar buruh pelabuhan yang unik, scratch. Scratch adalah gambar "kosong", tidak ada file di dalamnya, meskipun beratnya secara default - wow! - 77 byte.

FROM scratch

Gambar awal

Ide dari gambar awal adalah Anda dapat menyalin dependensi apa pun dari mesin host ke dalamnya dan menggunakannya di dalam Dockerfile (ini seperti menyalinnya ke apt dan menginstal dari awal), atau nanti ketika image Docker terwujud. Ini memungkinkan Anda untuk sepenuhnya mengontrol konten container Docker, dan dengan demikian sepenuhnya mengontrol ukuran gambar.

Sekarang kita perlu mengumpulkan dependensi ini. Alat yang ada seperti apt memungkinkan Anda mengunduh paket, tetapi paket tersebut terikat dengan mesin saat ini dan, bagaimanapun juga, tidak mendukung Windows atau MacOS.

Jadi saya mulai membuat alat saya sendiri yang secara otomatis akan membuat gambar dasar dengan ukuran sekecil mungkin dan juga menjalankan aplikasi apa pun. Saya menggunakan paket Ubuntu/Debian, membuat pilihan (mendapatkan paket langsung dari repositori) dan secara rekursif menemukan ketergantungannya. Program ini seharusnya secara otomatis mengunduh paket versi stabil terbaru, meminimalkan risiko keamanan sebanyak mungkin.

Saya memberi nama alat itu fetchy, karena dia... menemukan dan membawa... apa yang dibutuhkan [dari bahasa Inggris "ambil", "bawa" - kira-kira. jalur]. Alat ini bekerja melalui antarmuka baris perintah, tetapi pada saat yang sama menawarkan API.

Untuk merakit gambar menggunakan fetchy (mari kita ambil gambar Python kali ini), Anda hanya perlu menggunakan CLI seperti ini: fetchy dockerize python. Anda mungkin ditanyai sistem operasi target dan nama kode karena fetchy saat ini hanya menggunakan paket berbasis Debian dan Ubuntu.

Sekarang Anda dapat memilih dependensi mana yang tidak diperlukan sama sekali (dalam konteks kita) dan mengecualikannya. Misalnya, Python bergantung pada Perl, meskipun ia berfungsi dengan baik tanpa menginstal Perl.

Temuan

Gambar python dibuat menggunakan perintah fetchy dockerize python3.5 beratnya hanya 35MB (saya yakin di masa depan bisa dibuat lebih ringan lagi). Ternyata kami berhasil mengurangi 15 WW lagi dari gambar distroless.

Anda dapat melihat semua gambar yang dikumpulkan sejauh ini di sini.

Proyek - di sini.

Jika Anda kehilangan fitur, cukup buat permintaan - saya akan dengan senang hati membantu :) Terlebih lagi, saat ini saya sedang berupaya mengintegrasikan pengelola paket lain ke dalam pengambilan, sehingga tidak diperlukan pembangunan multi-tahap.

Sumber: www.habr.com

Tambah komentar