Imatges petites de Docker que creien en elles mateixes*

[referència al conte de fades infantil nord-americà "The Little Engine That Could" - aprox. carril]*

Imatges petites de Docker que creien en elles mateixes*

Com crear automàticament petites imatges de Docker per a les vostres necessitats

Obsessió inusual

Durant els últims dos mesos, he estat obsessionat amb el petit que pot ser una imatge de Docker i encara tinc l'aplicació en execució?

Entenc, la idea és estranya.

Abans d'entrar en els detalls i els aspectes tècnics, m'agradaria explicar per què aquest problema em va molestar tant i com us afecta a vosaltres.

Per què importa la mida

En reduir el contingut de la imatge de Docker, reduïm així la llista de vulnerabilitats. A més, fem les imatges més netes, perquè només contenen el que es necessita per executar aplicacions.

Hi ha un petit avantatge més: les imatges es descarreguen una mica més ràpid, però, al meu entendre, això no és tan important.

Tingueu en compte: si us preocupa la mida, l'aspecte alpin és petit i probablement us quedarà.

Imatges sense distribució

Projecte Distroless ofereix una selecció d'imatges bàsiques "sense distribució", que no contenen gestors de paquets, shells i altres utilitats que esteu acostumats a veure a la línia d'ordres. Com a resultat, utilitzeu gestors de paquets com pip и apt no funcionarà:

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

Dockerfile utilitzant la imatge sense distribució de 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 no és a la imatge

En general, aquest problema es resol mitjançant una construcció en diverses etapes:

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/

Muntatge multietapa

El resultat és una imatge de 130 MB de mida. No tant malament! Per comparar: la imatge de Python predeterminada pesa 929 MB, i la "més prima" (3,7-slim) - 179 MB, imatge alpina (3,7-alpine) és de 98,6 MB, mentre que la imatge base sense distribució utilitzada a l'exemple és de 50,9 MB.

És just assenyalar que en l'exemple anterior estem copiant un directori sencer /usr/local/lib/python3.7/site-packages, que pot contenir dependències que no necessitem. Tot i que està clar que la diferència de mida de totes les imatges base de Python existents varia.

En el moment d'escriure, Google distroless no admet moltes imatges: Java i Python encara es troben en fase experimental, i Python només existeix per a 2,7 i 3,5.

Imatges diminutes

Torno a la meva obsessió per crear imatges petites.

En general, volia veure com es construeixen les imatges sense distribució. El projecte sense distribució utilitza l'eina de creació de Google bazel. Tanmateix, instal·lar Bazel i escriure les vostres pròpies imatges va suposar molta feina (i, per ser honest, reinventar la roda és divertit i educatiu). Volia simplificar la creació d'imatges més petites: l'acte de crear una imatge hauria de ser extremadament senzill, banal. Perquè no hi hagi fitxers de configuració per a vostè, només una línia a la consola: просто собрать образ для <приложение>.

Per tant, si voleu crear les vostres pròpies imatges, sabeu: hi ha una imatge Docker tan única, scratch. Scratch és una imatge "buida", no hi ha fitxers, tot i que pesa per defecte: vaja! - 77 bytes.

FROM scratch

Imatge de ratllat

La idea d'una imatge scratch és que podeu copiar-hi qualsevol dependència de la màquina amfitriona i utilitzar-la dins d'un Dockerfile (això és com copiar-les a apt i instal·lar des de zero), o més tard quan es materialitzi la imatge de Docker. Això us permet controlar completament el contingut del contenidor Docker i, per tant, controlar completament la mida de la imatge.

Ara hem de recollir d'alguna manera aquestes dependències. Eines existents com apt permeten descarregar paquets, però estan lligats a la màquina actual i, després de tot, no són compatibles amb Windows ni MacOS.

Així que em vaig proposar crear la meva pròpia eina que crearia automàticament una imatge base de la mida més petita possible i que també executés qualsevol aplicació. Vaig utilitzar paquets Ubuntu/Debian, vaig fer una selecció (obtenint paquets directament dels dipòsits) i vaig trobar recursivament les seves dependències. El programa havia de descarregar automàticament la darrera versió estable del paquet, minimitzant els riscos de seguretat tant com fos possible.

Vaig anomenar l'eina fetchy, perquè ell... troba i porta... el que cal [de l'anglès "aportar", "portar" - aprox. carril]. L'eina funciona mitjançant una interfície de línia d'ordres, però al mateix temps ofereix una API.

Per muntar una imatge utilitzant fetchy (Agafem una imatge de Python aquesta vegada), només cal que utilitzeu la CLI d'aquesta manera: fetchy dockerize python. És possible que se us demani el sistema operatiu de destinació i el nom en clau perquè fetchy actualment només utilitza paquets basats en Debian i Ubuntu.

Ara podeu triar quines dependències no són necessàries (en el nostre context) i excloure-les. Per exemple, Python depèn de Perl, tot i que funciona bé sense instal·lar Perl.

Troballes

Imatge de Python creada amb l'ordre fetchy dockerize python3.5 només pesa 35 MB (estic més que segur que en el futur es podrà fer encara més lleuger). Resulta que vam aconseguir eliminar 15 WW més de la imatge sense distribució.

Podeu veure totes les imatges recollides fins ara aquí.

Projecte - aquí.

Si us falten funcions, només heu de crear una sol·licitud; estaré encantat d'ajudar-vos :) Encara més, actualment estic treballant per integrar altres gestors de paquets a fetchy, de manera que no calgui compilacions en diverses etapes.

Font: www.habr.com

Afegeix comentari