Små Docker-bilder som trodde på sig själva*

[hänvisning till den amerikanska barnsagan "The Little Engine That Could" - ca. körfält]*

Små Docker-bilder som trodde på sig själva*

Hur man automatiskt skapar små Docker-bilder för dina behov

Ovanlig besatthet

Under de senaste månaderna har jag varit besatt av hur liten en Docker-bild kan vara och fortfarande ha applikationen igång?

Jag förstår, tanken är konstig.

Innan jag går in på detaljerna och de tekniska detaljerna skulle jag vilja förklara varför det här problemet störde mig så mycket och hur det berör dig.

Varför storlek spelar roll

Genom att minska innehållet i Docker-bilden minskar vi därmed listan över sårbarheter. Dessutom gör vi bilderna renare, eftersom de bara innehåller det som behövs för att köra applikationer.

Det finns ytterligare en liten fördel - bilder laddas ner lite snabbare, men enligt min mening är detta inte så viktigt.

Observera: Om du är orolig för storleken är själva alpina utseendet små och kommer troligen att passa dig.

Otroliga bilder

Projekt Distroless erbjuder ett urval av grundläggande "distroless" bilder, de innehåller inte pakethanterare, skal och andra verktyg som du är van vid att se på kommandoraden. Som ett resultat, använd pakethanterare som pip и apt kommer inte att fungera:

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

Dockerfil med Python 3 distroless bild

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 finns inte i bilden

Vanligtvis löses det här problemet med en flerstegsbyggnad:

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/

Montering i flera steg

Resultatet är en bild på 130 MB. Inte så dåligt! Som jämförelse: standard Python-bilden väger 929MB, och den "tunnare" (3,7-slim) - 179 MB, alpin bild (3,7-alpine) är 98,6 MB, medan den distrolösa basbilden som används i exemplet är 50,9 MB.

Det är rättvist att påpeka att i det föregående exemplet kopierar vi en hel katalog /usr/local/lib/python3.7/site-packages, som kan innehålla beroenden som vi inte behöver. Även om det är tydligt att storleksskillnaden för alla befintliga Python-basbilder varierar.

I skrivande stund har Google distroless inte stöd för många bilder: Java och Python är fortfarande på experimentstadiet, och Python finns bara för 2,7 och 3,5.

Små bilder

Tillbaka till min besatthet av att skapa små bilder.

Generellt ville jag se hur distroless bilder är uppbyggda. Det distroless-projektet använder Googles byggverktyg bazel. Men att installera Bazel och skriva dina egna bilder tog en hel del arbete (och för att vara helt ärlig, att återuppfinna hjulet är roligt och lärorikt). Jag ville förenkla skapandet av mindre bilder: handlingen att skapa en bild ska vara extremt enkel, banal. Så att det inte finns några konfigurationsfiler för dig, bara en rad i konsolen: просто собрать образ для <приложение>.

Så om du vill skapa dina egna bilder, vet du: det finns en så unik docker-bild, scratch. Scratch är en "tom" bild, det finns inga filer i den, även om den väger som standard - wow! - 77 byte.

FROM scratch

Skrapa bilden

Tanken med en skrapbild är att du kan kopiera alla beroenden från värddatorn till den och antingen använda dem inuti en Dockerfil (detta är som att kopiera dem till apt och installera från början), eller senare när Docker-bilden materialiseras. Detta gör att du kan kontrollera innehållet i Docker-behållaren helt och hållet och därmed helt kontrollera storleken på bilden.

Nu måste vi på något sätt samla in dessa beroenden. Befintliga verktyg som apt låter dig ladda ner paket, men de är knutna till den aktuella maskinen och stöder trots allt inte Windows eller MacOS.

Så jag satte mig för att bygga ett eget verktyg som automatiskt skulle bygga en basbild av minsta möjliga storlek och även köra vilken applikation som helst. Jag använde Ubuntu/Debian-paket, gjorde ett urval (hämtade paket direkt från arkiven) och hittade rekursivt deras beroenden. Programmet var tänkt att automatiskt ladda ner den senaste stabila versionen av paketet, vilket minimerar säkerhetsriskerna så mycket som möjligt.

Jag döpte verktyget fetchy, för han... hittar och tar med sig... det som behövs [från engelska "hämta", "ta med" - ca. körfält]. Verktyget fungerar via ett kommandoradsgränssnitt, men erbjuder samtidigt ett API.

För att sätta ihop en bild med hjälp av fetchy (låt oss ta en Python-bild den här gången), du behöver bara använda CLI så här: fetchy dockerize python. Du kan bli ombedd att ange måloperativsystemet och kodnamnet pga fetchy använder för närvarande bara paket baserade på Debian och Ubuntu.

Nu kan du välja vilka beroenden som inte alls behövs (i vårt sammanhang) och utesluta dem. Till exempel beror Python på perl, även om det fungerar bra utan att Perl är installerat.

Resultat

Python-bild skapad med kommandot fetchy dockerize python3.5 väger bara 35MB (jag är mer än säker på att den i framtiden kan göras ännu lättare). Det visar sig att vi lyckades raka bort ytterligare 15 WW från den distrolösa bilden.

Du kan se alla bilder som samlats in hittills här.

Projekt - här.

Om du saknar funktioner, skapa bara en förfrågan - jag hjälper gärna till :) Ännu mer, jag arbetar just nu med att integrera andra pakethanterare i fetchy, så att det inte finns något behov av flerstegsbyggnationer.

Källa: will.com

Lägg en kommentar