Alpine vytváří Docker buildy pod Pythonem 50krát pomaleji a obrazy jsou 2krát větší.

Alpine vytváří Docker buildy pod Pythonem 50krát pomaleji a obrazy jsou 2krát větší.

Alpine Linux je často doporučován jako základní obraz pro Docker. Říkají vám, že použití Alpine zmenší vaše buildy a urychlí proces sestavení.

Ale pokud používáte Alpine Linux pro Python aplikace, pak:

  • Vaše buildy budou mnohem pomalejší.
  • Vaše obrazy budou větší.
  • Ztratíte čas.
  • A nakonec to může vést k runtime chybám.


Podívejme se na to, proč je Alpine doporučován, ale proč byste ho neměli používat spolu s Pythonem.

Proč lidé doporučují Alpine?

Představme si, že potřebujeme gcc jako součást našeho obrazu a chceme porovnat Alpine Linux s Ubuntu 18.04 co do rychlosti sestavení a konečné velikosti obrazu.

Nejprve stáhneme dva obrazy a porovnáme jejich velikosti:

$ docker pull --quiet ubuntu:18.04
docker.io/library/ubuntu:18.04
$ docker pull --quiet alpine
docker.io/library/alpine:latest
$ docker image ls ubuntu:18.04
REPOSITORY          TAG        IMAGE ID         SIZE
ubuntu              18.04      ccc6e87d482b     64.2MB
$ docker image ls alpine
REPOSITORY          TAG        IMAGE ID         SIZE
alpine              latest     e7d92cdc71fe     5.59MB

Jak vidíte, základní obraz pro Alpine je mnohem menší. Teď se pokusíme nainstalovat gcc a začneme s Ubuntu:

FROM ubuntu:18.04
RUN apt-get update && 
    apt-get install --no-install-recommends -y gcc && 
    apt-get clean && rm -rf /var/lib/apt/lists/*

Napsání dokonalého Dockerfile přesahuje rámec tohoto článku.

Změříme rychlost sestavení:

$ time docker build -t ubuntu-gcc -f Dockerfile.ubuntu --quiet .
sha256:b6a3ee33acb83148cd273b0098f4c7eed01a82f47eeb8f5bec775c26d4fe4aae

real    0m29.251s
user    0m0.032s
sys     0m0.026s
$ docker image ls ubuntu-gcc
REPOSITORY   TAG      IMAGE ID      CREATED         SIZE
ubuntu-gcc   latest   b6a3ee33acb8  9 seconds ago   150MB

Opakujeme to samé pro Alpine (Dockerfile):

FROM alpine
RUN apk add --update gcc

Sestavujeme, sledujeme čas a velikost sestavení:

$ time docker build -t alpine-gcc -f Dockerfile.alpine --quiet .
sha256:efd626923c1478ccde67db28911ef90799710e5b8125cf4ebb2b2ca200ae1ac3

real    0m15.461s
user    0m0.026s
sys     0m0.024s
$ docker image ls alpine-gcc
REPOSITORY   TAG      IMAGE ID       CREATED         SIZE
alpine-gcc   latest   efd626923c14   7 seconds ago   105MB

Jak bylo slíbeno, obrazy založené na Alpine se sestavují rychleji a samotné jsou menší: 15 sekund místo 30 a velikost obrazu 105MB oproti 150MB. To je docela dobré!

Ale pokud přepneme na sestavení Python aplikace, situace není tak růžová.

Python obraz

Python aplikace často využívají pandas a matplotlib. Proto jedna z možností je vzít oficiální obraz založený na Debianu s tímto Dockerfile:

FROM python:3.8-slim
RUN pip install --no-cache-dir matplotlib pandas

Sestavujeme ho:

$ docker build -f Dockerfile.slim -t python-matpan.
Odesílání kontextu buildu do Docker daemon  3.072kB
Krok 1/2 : FROM python:3.8-slim
 ---> 036ea1506a85
Krok 2/2 : RUN pip install --no-cache-dir matplotlib pandas
 ---> Probíhá v 13739b2a0917
Získávání matplotlib
  Stahování matplotlib-3.1.2-cp38-cp38-manylinux1_x86_64.whl (13.1 MB)
Získávání pandas
  Stahování pandas-0.25.3-cp38-cp38-manylinux1_x86_64.whl (10.4 MB)
...
Úspěšně sestaveno b98b5dc06690
Úspěšně označeno python-matpan:latest

skutečný    0m30.297s
uživatel    0m0.043s
systém     0m0.020s

Získáváme obraz o velikosti 363MB.
Bude lepší použít Alpine? Zkusme to:

FROM python:3.8-alpine
RUN pip install --no-cache-dir matplotlib pandas

$ docker build -t python-matpan-alpine -f Dockerfile.alpine .                                 
Odesílání kontextu buildu do Docker daemon  3.072kB                                               
Krok 1/2 : FROM python:3.8-alpine                                                             
 ---> a0ee0c90a0db                                                                            
Krok 2/2 : RUN pip install --no-cache-dir matplotlib pandas                                                  
 ---> Probíhá v 6740adad3729                                                                 
Získávání matplotlib                                                                         
  Stahování matplotlib-3.1.2.tar.gz (40.9 MB)                                               
    CHYBA: Příkaz se nezdařil s výstupním stavem 1:                                            
     příkaz: /usr/local/bin/python -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/${
tmp}/pip-install-a3olrixa/matplotlib/setup.py'"'"'; __file__='"'"'/${tmp}/pip-install-a3olrixa/matplotlib/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'rn'"'"', '"'"'n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base /tmp/pip-install-a3olrixa/matplotlib/pip-egg-info                              

...
CHYBA: Příkaz se nezdařil s výstupním stavem 1: python setup.py egg_info Zkontrolujte protokoly pro úplný výstup příkazů.
Příkaz '/bin/sh -c pip install matplotlib pandas' vrátí nenulový kód: 1

Co se děje?

Alpine nepodporuje wheels.

Pokud se podíváte na build založený na Debiánu, uvidíte, že stahuje matplotlib-3.1.2-cp38-cp38-manylinux1_x86_64.whl.

To je binární formát pro wheel. Alpine však stahuje zdrojové kódy `matplotlib-3.1.2.tar.gz`, protože nepodporuje standardní wheels..

Proč? Většina distribucí Linuxu používá GNU verzi (glibc) standardní knihovny C, kterou potřebuje každá program napsaný v C, včetně Pythonu. Ale Alpine používá `musl`, a protože tyto binárky jsou určeny pro `glibc`, jednoduše nejsou kompatibilní.

Proto, pokud používáte Alpine, musíte zkompilovat veškerý kód napsaný v C ve všech Python balíčcích.

Ach, ano, seznam všech těchto závislostí, které je třeba zkompilovat, budete muset hledat sami.
V tomto případě získáváme něco takového:

FROM python:3.8-alpine
RUN apk --update add gcc build-base freetype-dev libpng-dev openblas-dev
RUN pip install --no-cache-dir matplotlib pandas

A doba buildu trvá…

… 25 minut a 57 sekund! A velikost obrazu je 851MB.

Obrázky založené na Alpine se sestavují mnohem déle, jsou větší a musíte také hledat všechny závislosti. Samozřejmě, že byste mohli zmenšit velikost sestavení pomocí vícefázového sestavení , ale to znamená, že budete muset udělat ještě více práce.

To však není všechno!

Alpine může být příčinou neočekávaných chyb za běhu

  • Teoreticky je musl kompatibilní s glibc, ale v praxi se rozdíly mohou stát příčinou mnoha problémů. A pokud se vyskytnou, budou pravděpodobně nepříjemné. Zde jsou některé problémy, které mohou nastat:
  • Alpine má ve výchozím nastavení menší velikost zásobníku vlákna, což může vést k chybám v Pythonu
  • Někteří uživatelé zjistili, že Python aplikace běží pomaleji kvůli způsobu, jakým musl alokuje paměť (lišší se od glibc).
  • Jeden z uživatelů objevil chybu při formátování data

Určitě tyto chyby již opravili, ale kdo ví, kolik jich ještě je.

Nepoužívejte obraz Alpine pro Python

Pokud se nechcete potýkat s velkými a dlouhými sestaveními, hledáním závislostí a potenciálními chybami — nepoužívejte Alpine Linux jako základní obraz. Výběr dobrého základního obrazu.

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