Alpine përpilon ndërtimet e Docker për Python 50 herë më ngadalë dhe imazhet janë 2 herë më të rënda

Alpine përpilon ndërtimet e Docker për Python 50 herë më ngadalë dhe imazhet janë 2 herë më të rënda

Alpine Linux rekomandohet shpesh si një imazh bazë për Docker. Ju thuhet se përdorimi i Alpine do t'i bëjë ndërtimet tuaja më të vogla dhe procesin e ndërtimit më të shpejtë.

Por nëse përdorni Alpine Linux për aplikacionet Python, atëherë:

  • I bën ndërtimet tuaja shumë më të ngadalta
  • I bën imazhet tuaja më të mëdha
  • Duke humbur kohën tuaj
  • Dhe në fund mund të shkaktojë gabime në kohën e ekzekutimit


Le të shohim pse rekomandohet Alpine, por pse ende nuk duhet ta përdorni me Python.

Pse njerëzit rekomandojnë Alpine?

Le të supozojmë se na nevojitet gcc si pjesë e imazhit tonë dhe duam të krahasojmë Alpine Linux vs Ubuntu 18.04 për sa i përket shpejtësisë së ndërtimit dhe madhësisë përfundimtare të imazhit.

Së pari, le të shkarkojmë dy imazhe dhe të krahasojmë madhësitë e tyre:

$ 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

Siç mund ta shihni, imazhi bazë për Alpine është shumë më i vogël. Le të përpiqemi tani të instalojmë gcc dhe të fillojmë me 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/*

Shkrimi i skedarit të përsosur Docker është përtej qëllimit të këtij artikulli.

Le të matim shpejtësinë e montimit:

$ 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

Ne përsërisim të njëjtën gjë për Alpine (Dockerfile):

FROM alpine
RUN apk add --update gcc

Ne montojmë, shikojmë kohën dhe madhësinë e montimit:

$ 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

Siç u premtua, imazhet e bazuara në Alpine mblidhen më shpejt dhe janë më të vogla: 15 sekonda në vend të 30 dhe madhësia e imazhit është 105 MB kundrejt 150 MB. Është shumë mirë!

Por nëse kalojmë në ndërtimin e një aplikacioni Python, atëherë gjithçka nuk është aq rozë.

Imazhi i Python

Aplikacionet Python shpesh përdorin panda dhe matplotlib. Prandaj, një opsion është të merrni imazhin zyrtar të bazuar në Debian duke përdorur këtë Dockerfile:

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

Le ta mbledhim:

$ 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

Ne marrim një imazh prej 363 MB në madhësi.
A do të bëjmë më mirë me Alpine? Le te perpiqemi:

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

Çfarë po ndodh?

Alpine nuk mbështet rrota

Nëse shikoni ndërtimin, i cili bazohet në Debian, do të shihni se ai shkarkon matplotlib-3.1.2-cp38-cp38-manylinux1_x86_64.derisa.

Ky është një binar për timon. Alpine shkarkon burimet `matplotlib-3.1.2.tar.gz` meqenëse nuk e mbështet standardin rrota.

Pse? Shumica e shpërndarjeve Linux përdorin versionin GNU (glibc) të bibliotekës standarde C, e cila në fakt kërkohet nga çdo program i shkruar në C, duke përfshirë Python. Por Alpine përdor 'musl', dhe meqenëse ato binare janë krijuar për 'glibc', ato thjesht nuk janë një opsion.

Prandaj, nëse përdorni Alpine, duhet të përpiloni të gjithë kodin e shkruar në C në çdo paketë Python.

Oh, po, do t'ju duhet të kërkoni listën e të gjitha varësive të tilla që duhet të përpilohen vetë.
Në këtë rast marrim këtë:

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

Dhe koha e ndërtimit kërkon ...

... 25 minuta 57 sekonda! Dhe madhësia e imazhit është 851 MB.

Imazhet e bazuara në alpine kërkojnë shumë më shumë kohë për t'u ndërtuar, ato janë më të mëdha në përmasa dhe ju ende duhet të kërkoni të gjitha varësitë. Sigurisht, ju mund të zvogëloni madhësinë e montimit duke përdorur ndërtime me shumë faza por kjo do të thotë se duhet bërë edhe më shumë punë.

Kjo nuk është e gjitha!

Alpine mund të shkaktojë defekte të papritura në kohën e ekzekutimit

  • Në teori, musl është në përputhje me glibc, por në praktikë ndryshimet mund të shkaktojnë shumë probleme. Dhe nëse janë, ndoshta do të jenë të pakëndshme. Këtu janë disa probleme që mund të shfaqen:
  • Alpine ka si parazgjedhje një madhësi më të vogël të pirgut të fillit, gjë që mund të çojë në gabime në Python
  • Disa përdorues e kanë gjetur atë Aplikacionet Python janë më të ngadalta për shkak të mënyrës se si musl alokon kujtesën (ndryshe nga glibc).
  • Një nga përdoruesit gjeti një gabim gjatë formatimit të datës

Me siguri këto gabime tashmë janë korrigjuar, por kushedi sa do të jenë të tjera.

Mos përdorni imazhe alpine për Python

Nëse nuk doni të shqetësoheni me ndërtime të mëdha dhe të gjata, duke kërkuar për varësi dhe gabime të mundshme, mos përdorni Alpine Linux si imazh bazë. Zgjedhja e një imazhi të mirë bazë.

Burimi: www.habr.com

Shto një koment