Kleine Docker-afbeeldingen die in zichzelf geloofden*

[verwijzing naar het Amerikaanse kindersprookje "The Little Engine That Could" - ca. rijbaan]*

Kleine Docker-afbeeldingen die in zichzelf geloofden*

Hoe u automatisch kleine Docker-images kunt maken voor uw behoeften

Ongebruikelijke obsessie

De afgelopen maanden ben ik geobsedeerd geweest door hoe klein een Docker-image kan zijn en hoe de applicatie nog steeds actief kan zijn?

Ik begrijp het, het idee is vreemd.

Voordat ik op de details en technische details inga, wil ik graag uitleggen waarom dit probleem mij zoveel hinderde, en hoe u er last van heeft.

Waarom grootte ertoe doet

Door de inhoud van de Docker-image te verkleinen, verkleinen we daarmee de lijst met kwetsbaarheden. Bovendien maken we de afbeeldingen schoner, omdat ze alleen bevatten wat nodig is om applicaties te laten draaien.

Er is nog een klein voordeel: afbeeldingen worden iets sneller gedownload, maar naar mijn mening is dit niet zo belangrijk.

Let op: als je je zorgen maakt over de maat: de Alpine-looks zelf zijn klein en zullen waarschijnlijk bij je passen.

Distroloze afbeeldingen

Project Distroless biedt een selectie van standaard “distroless” afbeeldingen, ze bevatten geen pakketbeheerders, shells en andere hulpprogramma's die u gewend bent te zien op de opdrachtregel. Gebruik daarom pakketbeheerders zoals pip и apt zal niet werken:

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

Dockerfile met behulp van Python 3 distroless-image

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 staat niet in beeld

Meestal wordt dit probleem opgelost door een meerfasige build:

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/

Meertrapsmontage

Het resultaat is een afbeelding van 130 MB groot. Niet slecht! Ter vergelijking: de standaard Python-afbeelding weegt 929 MB, en de ‘dunnere’ (3,7-slim) - 179 MB, alpine afbeelding (3,7-alpine) is 98,6 MB, terwijl de basis distroless-afbeelding die in het voorbeeld wordt gebruikt 50,9 MB is.

Het is eerlijk om erop te wijzen dat we in het vorige voorbeeld een hele map kopiëren /usr/local/lib/python3.7/site-packages, die afhankelijkheden kan bevatten die we niet nodig hebben. Al is het duidelijk dat het verschil in grootte van alle bestaande Python-basisimages varieert.

Op het moment van schrijven ondersteunt Google distroless nog niet veel afbeeldingen: Java en Python bevinden zich nog in de experimentele fase, en Python bestaat alleen voor 2,7 en 3,5.

Kleine afbeeldingen

Terug naar mijn obsessie met het maken van kleine afbeeldingen.

Over het algemeen wilde ik zien hoe distributieloze afbeeldingen worden geconstrueerd. Het distributieloze project maakt gebruik van de build-tool van Google bazel. Het installeren van Bazel en het schrijven van je eigen afbeeldingen kostte echter veel werk (en om eerlijk te zijn: het wiel opnieuw uitvinden is leuk en leerzaam). Ik wilde het maken van kleinere afbeeldingen vereenvoudigen: het maken van een afbeelding zou uiterst eenvoudig moeten zijn, banaal. Zodat er geen configuratiebestanden voor u zijn, slechts één regel in de console: просто собрать образ для <приложение>.

Dus als je je eigen afbeeldingen wilt maken, weet dan: er is zo'n unieke docker-afbeelding, scratch. Scratch is een "lege" afbeelding, er staan ​​geen bestanden in, hoewel deze standaard weegt - wauw! - 77 bytes.

FROM scratch

Kras afbeelding

Het idee van een scratch-image is dat je alle afhankelijkheden van de hostmachine ernaar kunt kopiëren en ze in een Dockerfile kunt gebruiken (dit is hetzelfde als ze kopiëren naar apt en helemaal opnieuw installeren), of later wanneer de Docker-image is gerealiseerd. Hierdoor heeft u volledige controle over de inhoud van de Docker-container, en dus ook over de grootte van de afbeelding.

Nu moeten we deze afhankelijkheden op de een of andere manier verzamelen. Bestaande tools zoals apt kunt u pakketten downloaden, maar deze zijn gebonden aan de huidige machine en ondersteunen immers geen Windows of MacOS.

Dus begon ik mijn eigen tool te bouwen die automatisch een basisimage van de kleinst mogelijke grootte zou bouwen en ook elke applicatie zou kunnen draaien. Ik heb Ubuntu/Debian-pakketten gebruikt, een selectie gemaakt (pakketten rechtstreeks uit de repository's gehaald) en recursief hun afhankelijkheden gevonden. Het programma moest automatisch de nieuwste stabiele versie van het pakket downloaden, waardoor de beveiligingsrisico's zoveel mogelijk werden geminimaliseerd.

Ik heb het gereedschap een naam gegeven fetchy, omdat hij... vindt en brengt... wat nodig is [van Engels "halen", "brengen" - ca. rijbaan]. De tool werkt via een opdrachtregelinterface, maar biedt tegelijkertijd een API.

Om een ​​afbeelding samen te stellen met behulp van fetchy (laten we deze keer een Python-afbeelding nemen), je hoeft de CLI alleen maar als volgt te gebruiken: fetchy dockerize python. Mogelijk wordt u gevraagd naar het doelbesturingssysteem en de codenaam omdat fetchy gebruikt momenteel alleen pakketten gebaseerd op Debian en Ubuntu.

Nu kun je kiezen welke afhankelijkheden helemaal niet nodig zijn (in onze context) en deze uitsluiten. Python is bijvoorbeeld afhankelijk van perl, hoewel het prima werkt zonder dat Perl is geïnstalleerd.

Bevindingen

Python-afbeelding gemaakt met behulp van de opdracht fetchy dockerize python3.5 weegt slechts 35 MB (ik ben er meer dan zeker van dat het in de toekomst nog lichter kan worden gemaakt). Het blijkt dat we erin zijn geslaagd nog eens 15 WW van het distroloze imago af te schaven.

Je kunt alle tot nu toe verzamelde afbeeldingen bekijken hier.

Project- hier.

Als je functies mist, maak dan gewoon een verzoek aan - ik help je graag verder :) Sterker nog, ik werk momenteel aan het integreren van andere pakketbeheerders in fetchy, zodat er geen noodzaak is voor builds in meerdere fasen.

Bron: www.habr.com

Voeg een reactie