Alpine zhromažďuje Docker buildy pod Pythonom 50-krát pomalšie a obrazy sú 2-krát ťažšie

Alpine zhromažďuje Docker buildy pod Pythonom 50-krát pomalšie a obrazy sú 2-krát ťažšie

Alpine Linux — často doporučovaný jako základní obraz pro Docker. Říkají vám, že použití Alpine učiní vaše buildy menšími a proces sestavení rychlejším.

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

  • Způsobuje, že vaše buildy jsou mnohem pomalejší.
  • Způsobuje, že vaše obrazy jsou větší.
  • Zabírá váš čas.
  • A nakonec může být příčinou chyb za běhu.


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

Proč lidé doporučují Alpine?

Předpokládejme, že potřebujeme gcc jako součást našeho obrazu a chceme porovnat Alpine Linux vs Ubuntu 18.04 z hlediska rychlosti sestavení a konečné velikosti obrazu.

Nejprve si stáhneme dva obrazy a porovnáme jejich velikost:

$ 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ší. Zkusme nyní nainstalovat gcc a začněme 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/*

Psaní ideálních 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 totéž pro Alpine (Dockerfile):

FROM alpine
RUN apk add --update gcc

Sestavíme, podíváme se na č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 jsou samy o sobě menší: 15 sekund místo 30 a velikost obrazu 105MB oproti 150MB. To je docela dobré!

Ale pokud se přepneme na stavbu Python aplikace, tak to už tak růžové není.

Python obraz

Python aplikace často používají pandas a matplotlib. Proto je jednou z možností vzít oficiální obraz na základě Debianu, použitím takového Dockerfile:

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

Sestavíme ho:

$ docker build -f Dockerfile.slim -t python-matpan.
Sending build context to Docker daemon  3.072kB
Step 1/2 : FROM python:3.8-slim
 ---> 036ea1506a85
Step 2/2 : RUN pip install --no-cache-dir matplotlib pandas
 ---> Running in 13739b2a0917
Collecting matplotlib
  Downloading matplotlib-3.1.2-cp38-cp38-manylinux1_x86_64.whl (13.1 MB)
Collecting pandas
  Downloading pandas-0.25.3-cp38-cp38-manylinux1_x86_64.whl (10.4 MB)
...
Successfully built b98b5dc06690
Successfully tagged python-matpan:latest

real    0m30.297s
user    0m0.043s
sys     0m0.020s

Získavame obraz s veľkosťou 363 MB.
Bude to lepšie s Alpine? Skúsme to:

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

$ docker build -t python-matpan-alpine -f Dockerfile.alpine .
Sending build context to Docker daemon  3.072kB
Step 1/2 : FROM python:3.8-alpine
 ---> a0ee0c90a0db
Step 2/2 : RUN pip install --no-cache-dir matplotlib pandas
 ---> Running in 6740adad3729
Collecting matplotlib
  Downloading matplotlib-3.1.2.tar.gz (40.9 MB)
    ERROR: Command errored out with exit status 1:
     command: /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

...
ERROR: Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.
The command '/bin/sh -c pip install matplotlib pandas' returned a non-zero code: 1

Čo sa deje?

Alpine nepodporuje wheels

Ak sa pozriete na build, ktorý je postavený na Debiane, uvidíte, že sťahuje matplotlib-3.1.2-cp38-cp38-manylinux1_x86_64.whl.

Toto je binárka pre wheel. Alpine sťahuje zdrojové súbory `matplotlib-3.1.2.tar.gz`, pretože nepodporuje štandardné wheels.

Prečo? Väčšina Linux distribúcií používa GNU verziu (glibc) štandardnej knižnice C, ktorá je potrebná pre každú programáciu napísanú v C, vrátane Pythonu. Ale Alpine používa `musl`, a preto sú binárky určené pre `glibc`, jednoducho nepoužiteľné.

Preto, ak používate Alpine, musíte skompilovať celý kód napísaný v C v každom balíku Python.

Ach, áno, zoznam všetkých takýchto závislostí, ktoré sa musia kompilovať, budete musieť nájsť sami.
V tomto prípade dostaneme toto:

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 čas buildu trvá...

… 25 minút 57 sekúnd! A veľkosť obrazu je 851 MB.

Obrázky na báze Alpine sa zostavujú oveľa dlhšie, sú väčšie a musíte hľadať všetky závislosti. Samozrejme, môžete zmenšiť veľkosť zostavenia použitím multi-stage builds ale to znamená, že musíte vykonať ešte viac práce.

To však nie je všetko!

Alpine môže byť dôvodom neočakávaných chýb v runtime

  • Teoreticky je musl kompatibilný s glibc, ale v praxi môžu byť rozdiely príčinou mnohých problémov. A ak sa vyskytnú, určite nebudú príjemné. Tu sú niektoré problémy, ktoré môžu nastať:
  • Alpine má predvolene menšiu veľkosť zásobníka vlákna, čo môže viesť k chybám v Pythone
  • Niektorí používatelia zistili, že aplikácie Python bežia pomalšie kvôli spôsobu, akým musl prideľuje pamäť (odlišuje sa od glibc).
  • Jeden z používateľov objavil chybu pri formátovaní dátumu

Určite tieto chyby už opravili, ale kto vie, koľko ich ešte existuje.

Nepoužívajte obrázky Alpine pre Python

Ak nechcete mať starosti s veľkými a dlhými zostavami, hľadaním závislostí a potenciálnymi chybami — nepoužívajte Alpine Linux ako základný obrázok. Výber dobrého základného obrázka.

Zdroj: habr.com

Kúpte si spoľahlivý hosting pre webové stránky s ochranou proti DDoS, VPS VDS servery 🔥 Kúpte si spoľahlivý hosting pre webové stránky s ochranou proti DDoS, VPS VDS servery | ProHoster