[verwijzing naar het Amerikaanse kindersprookje "The Little Engine That Could" - ca. rijbaan]*
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
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
Project-
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