Mikroskopické obrazy Docker, které věřily v sebe*

[odkaz na americkou dětskou pohádku „Malý vláček, který věřil v sebe“ („The Little Engine That Could“) — pozn. př.]*

Mikroskopické obrazy Docker, které věřily v sebe*

Jak automagicky vytvářet malé dockerové obrazy pro své potřeby

Neobvyklá posedlost

Poslední dva měsíce jsem byl posedlý myšlenkou: jak moc lze zmenšit obraz Docker, aby aplikace stále fungovala?

Chápu, že myšlenka je podivná.

Než se ponořím do detailů a technických zákrutů, chtěl bych vysvětlit, proč mě tato otázka tolik zasáhla a jak se to týká vás.

Proč velikost má význam

Zmenšováním obsahu dockerového obrazu zároveň zmenšujeme seznam zranitelností. Navíc děláme obrazy čistší, protože obsahují pouze to, co je potřebné pro spuštění aplikací.

Je tu ještě jedno malé plus — obrazy se stahují o něco rychleji, ale podle mě to není tak důležité.

Všimněte si: Pokud vám na velikosti záleží, obrazy Alpine jsou samy o sobě malé a jistě se vám budou hodit.

Distroless obrazy

Projekt Distroless nabízí sbírku základních „distroless“ obrazů, které neobsahují správce balíčků, shell a další utilit, které jste zvyklí vídat v příkazovém řádku. Výsledkem je, že správci balíčků jako pip a apt nebudou fungovat:

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

Dockerfile používající distroless obraz Python 3

Odesílání kontextu sestavení Dockeru  2.048kB
Krok 1/2 : FROM gcr.io/distroless/python3
 ---> 556d570d5c53
Krok 2/2 : RUN  pip3 install numpy
 ---> Probíhá v dbfe5623f125
/bin/sh: 1: pip3: nenalezeno

Pip v obraze není

Obvykle se tento problém řeší pomocí víceetapové sestavy:

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/

Víceetapová sestava

Výsledkem je obraz o velikosti 130MB. Není to tak špatné! Pro srovnání: výchozí obraz Python váží 929MB, zatímco „zhubnutý“ (3,7-slim) — 179MB, obraz Alpine (3,7-alpine) — 98,6MB, zatímco základní distroless obraz použitý v příkladu — 50,9MB.

Můžeme s jistotou říci, že v předchozím příkladu kopírujeme celý adresář /usr/local/lib/python3.7/site-packages, ve kterém mohou být zbytečné závislosti. Ačkoli je jasné, že rozdíl ve velikosti všech existujících základních obrazů Python kolísá.

V době psaní těchto řádků Google distroless nepodporuje moc obrazů: Java a Python jsou ještě v experimentálním stádiu, a Python existuje pouze pro verze 2,7 a 3,5.

Malé obrazy

Vrátíme se k mému posedlosti vytvářením malých obrazů.

Chtěl jsem se vlastně podívat, jak fungují distroless obrazy. Projekt distroless používá Google nástroj pro sestavení bazel. Nicméně abych nainstaloval Bazel a napsal vlastní obrazy, musel jsem se zapotit (a pokud budu upřímný, tak znovu vynalézt kolo — to je zábavné a poučné). Chtěl jsem zjednodušit vytváření zmenšených obrazů: akt vytvoření obrazu by měl být co nejjednodušší, banální. Aby nebylo žádné konfigurační soubory, jen jeden řádek v konzoli: jednoduše sestavit obraz pro <aplikaci>.

Takže pokud chcete vytvářet vlastní obrazy, mějte na paměti: existuje takový unikátní docker obraz, scratch. Scratch je "prázdný" obraz, neobsahuje žádné soubory, i když standardně váží — wow! — 77 bytů.

FROM scratch

Obraz scratch

Myšlenka obrazu scratch je ta, že můžete do něj zkopírovat jakékoli závislosti z hostitelského stroje a buď je používat uvnitř Dockerfile (to je jako je zkopírovat do apt a nainstalovat znovu), nebo později, když je obraz Docker materializován. To umožňuje plně kontrolovat obsah Docker kontejneru, a tím pádem plně kontrolovat velikost obrazu.

A teď potřebujeme nějakým způsobem sestavit tyto závislosti. Stávající nástroje jako apt umožňují stahovat balíčky, ale jsou vázány na aktuální stroj a nakonec nepodporují Windows nebo MacOS.

A tak jsem se pustil do vytvoření vlastního nástroje, který by automaticky sestavil základní obraz co nejmenší velikosti a aby ten ještě spouštěl jakoukoli aplikaci. Používal jsem balíčky Ubuntu/Debian, prováděl jsem výběr (dostával jsem balíčky přímo z repozitářů) a rekurzivně nacházel jejich závislosti. Program měl automaticky stahovat nejnovější stabilní verzi balíčku, minimalizující bezpečnostní rizika.

Nástroj jsem nazval fetchy, protože on… nachází a přináší… co je potřeba [z anglického „fetch“, „přinášet“ — pozn. př.]. Nástroj funguje přes rozhraní příkazového řádku, ale zároveň nabízí i API.

Abychom sestavili obraz pomocí fetchy (vezmeme tentokrát obraz Python), stačí použít CLI takto: fetchy dockerize python. Může být požadována cílová operační systém a kódové jméno, protože fetchy zatím používá pouze balíčky založené na Debianu a Ubuntu.

Nyní si můžete vybrat, které závislosti jsou zcela zbytečné (v našem kontextu) a vyloučit je. Například Python závisí na perlu, ale skvěle funguje i bez nainstalovaného Perlu.

Výsledky

Obraz Pythonu vytvořený pomocí příkazu fetchy dockerize python3.5 váží pouhých 35 MB (jsem si více než jistý, že v budoucnu to bude možné ještě více zjednodušit). Z distroless obrazu se podařilo „ušetřit“ dalších 15 MB.

Všechny dosud shromážděné obrazy můžete vidět zde.

Projekt — tady.

Pokud vám chybí funkce, jednoduše vytvořte požadavek — budu rád pomoci 🙂 Dokonce jsem v současné době pracuji na integraci dalších balíčkových manažerů do fetchy, takže potřeba vícestupňových sestavení odpadne.

Zdroj: habr.com

Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery 🔥 Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery | ProHoster