[referință la povestea americană pentru copii „Micuțul locomotiva care a crezut în sine” („The Little Engine That Could”) — n.tr.]

Cum să creezi automat mici imagini Docker pentru nevoile tale
Obsesie neobișnuită
În ultimele câteva luni am fost obsedat de o idee constantă: cât de mult poate fi redusă o imagine Docker, încât aplicația să funcționeze?
Înțeleg, ideea este ciudată.
Înainte de a aprofunda detaliile și aspectele tehnice, aș dori să explic de ce această problemă m-a captivat atât de mult și cum te afectează pe tine.
De ce dimensiunea contează
Prin reducerea conținutului imaginii Docker, de fapt reducem lista de vulnerabilități. În plus, facem imaginile mai curate, deoarece conțin doar ce este necesar pentru a rula aplicațiile.
Există un alt mic avantaj — imaginile se descarcă puțin mai repede, dar, din punctul meu de vedere, asta nu este atât de important.
Rețineți: Dacă dimensiunea vă preocupă, imaginile Alpine sunt mici în sine și cu siguranță v-ar putea satisface.
Imagini Distroless
oferă o colecție de imagini de bază „distroless”, care nu conțin gestionare de pachete, shell-uri și alte utilitare pe care ești obișnuit să le vezi în linia de comandă. Ca urmare, utilizarea managerilor de pachete precum pip și apt nu va fi posibilă:
FROM gcr.io/distroless/python3
RUN pip3 install numpyDockerfile, folosind imaginea distroless Python 3
Trimiterea contextului de construcție către daemonul Docker 2.048kB
Pasul 1/2 : FROM gcr.io/distroless/python3
---> 556d570d5c53
Pasul 2/2 : RUN pip3 install numpy
---> Se execută în dbfe5623f125
/bin/sh: 1: pip3: nu a fost găsitPip nu este prezent în imagine
De obicei, această problemă se rezolvă printr-o construcție multi-etapă:
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/Construcție multi-etapă
În rezultat, obținem o imagine cu dimensiunea de 130MB. Nu este deloc rău! Spre comparație: imaginea Python implicit cântărește 929MB, iar cea „slăbită” (3,7-slim) — 179MB, imaginea alpine (3,7-alpine) — 98,6MB, în timp ce imaginea distroless de bază utilizată în exemplu — 50,9MB.
Se poate argumenta că în exemplul anterior copiem un întreg catalog /usr/local/lib/python3.7/site-packages, în care s-ar putea afle dependențe inutile. Deși este clar că diferența de dimensiune a tuturor imaginilor de bază Python existente variază.
La momentul scrierii acestor rânduri, Google distroless nu suportă atât de multe imagini: Java și Python sunt încă în faza de experimentare, iar Python există doar pentru 2.7 și 3.5.
Imagini minuscule
Să ne întoarcem la obsesia mea de a crea imagini mici.
În general, voiam să văd cum sunt structurate imaginile distroless. Proiectul distroless folosește un instrument de construire dezvoltat de Google bazel. Cu toate acestea, pentru a instala Bazel și a scrie propriile imagini, a fost nevoie de mult efort (și dacă vreau să fiu complet cinstit, a fost ca și cum aș reinventa roata - este distractiv și instructiv). Am vrut să simplific crearea imaginilor reduse: actul de creare a unei imagini ar trebui să fie extrem de simplu, banal. Fără fișiere de configurare, doar o singură linie în consolă: doar construiește o imagine pentru.
Așadar, dacă doriți să creați propriile imagini, știți că există o astfel de imagine unică docker, scratch. Scratch este o imagine „goală”, nu conține fișiere, deși în mod implicit cântărește - wow! - 77 de octeți.
FROM scratchImaginea scratch
Ideea imaginii scratch este că poți copia în ea orice dependențe de pe mașina gazdă și fie să le folosești în Dockerfile (este ca și cum ai copia și apt instala de la zero), fie mai târziu, când imaginea Docker s-a materializat. Aceasta permite controlul complet al conținutului containerului Docker și, prin urmare, controlul complet al dimensiunii imaginii.
Acum trebuie să găsim o modalitate de a colecta aceste dependențe. Instrumentele existente cum ar fi apt permit descărcarea pachetelor, dar sunt legate de mașina curentă și, în cele din urmă, nu suportă Windows sau MacOS.
Așadar, am decis să creez un instrument propriu care să construiască automat imaginea de bază de cea mai mică dimensiune posibilă și să poată rula orice aplicație. Am folosit pachete Ubuntu/Debian, am făcut selecții (obținând pachetele direct din repozitoare) și am găsit recursiv dependențele acestora. Programul trebuia să descarce automat cea mai recentă versiune stabilă a pachetului, reducând la minimum riscurile de securitate.
Instrumentul l-am numit fetchy, pentru că… găsește și aduce… ceea ce ai nevoie [din engleză „fetch”, „a aduce” — nota traducătorului.]. Instrumentul funcționează printr-o interfață de linie de comandă, dar oferă și un API.
Pentru a construi o imagine folosind fetchy (de data aceasta vom lua imaginea Python), tot ce trebuie să faci este să folosești CLI astfel: fetchy dockerize python. Poate că ți se va solicita sistemul de operare țintă și numele de cod, deoarece fetchy încă folosește doar pachete bazate pe Debian și Ubuntu.
Acum poți alege ce dependențe sunt complet inutile (în contextul nostru) și să le excluzi. De exemplu, Python depinde de Perl, deși funcționează perfect fără acesta instalat.
Rezultate
Imaginea Python creată cu comanda fetchy dockerize python3.5 cântărește doar 35 MB (sunt mai mult decât sigur că, în viitor, va putea fi și mai ușoară). Așadar, de pe imaginea distroless, am reușit să „tăiem” încă 15 MB.
Toate imaginile adunate până acum pot fi vizualizate .
Proiectul — .
Dacă îți lipsesc funcțiile, pur și simplu deschide o solicitare — voi fi bucuros să ajut 🙂 Mai mult, în acest moment lucrez la integrarea altor manageri de pachete în fetchy, astfel încât necesitatea construcțiilor în mai multe etape să dispară.
Sursa: habr.com
