
Alpine Linux este adesea recomandat ca imagine de bază pentru Docker. Vi se spune că utilizarea Alpine va face imaginile mai mici și procesul de compilare mai rapid.
Dar dacă folosiți Alpine Linux pentru aplicațiile Python, atunci el:
- Vă încetinește multă compilarea
- Vă crește dimensiunea imaginilor
- Vă consumă timpul
- Și în cele din urmă poate cauza erori în runtime
Să vedem de ce se recomandă Alpine, dar de ce nu ar trebui să-l utilizați împreună cu Python.
De ce oamenii recomandă Alpine?
Să presupunem că avem nevoie de gcc ca parte a imaginii noastre și dorim să comparăm Alpine Linux cu Ubuntu 18.04, în ceea ce privește viteza de compilare și dimensiunea finală a imaginii.
Pentru început, să descărcăm cele două imagini și să le comparăm dimensiunea:
$ 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
După cum vedeți, imaginea de bază pentru Alpine este mult mai mică. Să încercăm acum să instalăm gcc și să începem cu 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/*
Scrierea unui Dockerfile perfect depășește cadrul acestui articol
Să măsurăm viteza de compilare:
$ 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
Repetăm totul pentru Alpine (Dockerfile):
FROM alpine
RUN apk add --update gcc
Compilăm, vedem timpul și dimensiunea compilării:
$ 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
Așa cum s-a promis, imaginile pe baza Alpine se compilează mai repede și sunt mai mici: 15 secunde în loc de 30 și dimensiunea imaginii 105MB față de 150MB. Este destul de bine!
Dar dacă trecem la compilarea unei aplicații Python, lucrurile nu mai sunt atât de optimiste.
Imaginea Python
Aplicațiile Python folosesc adesea pandas și matplotlib. Prin urmare, una dintre opțiuni este să luăm imaginea oficială bazată pe Debian, folosind un astfel de Dockerfile:
FROM python:3.8-slim
RUN pip install --no-cache-dir matplotlib pandas
O compilăm:
$ docker build -f Dockerfile.slim -t python-matpan.
Trimiterea contextului de construcție către daemon-ul Docker 3.072kB
Pasul 1/2 : FROM python:3.8-slim
---> 036ea1506a85
Pasul 2/2 : RUN pip install --no-cache-dir matplotlib pandas
---> Se rulează în 13739b2a0917
Colectarea matplotlib
Descărcare matplotlib-3.1.2-cp38-cp38-manylinux1_x86_64.whl (13.1 MB)
Colectarea pandas
Descărcare pandas-0.25.3-cp38-cp38-manylinux1_x86_64.whl (10.4 MB)
...
Construcție realizată cu succes b98b5dc06690
Etichetată cu succes python-matpan:latest
real 0m30.297s
user 0m0.043s
sys 0m0.020s
Obținem o imagine de dimensiunea 363MB.
Va fi mai bun cu Alpine? Hai să încercăm:
FROM python:3.8-alpine
RUN pip install --no-cache-dir matplotlib pandas
$ docker build -t python-matpan-alpine -f Dockerfile.alpine .
Trimiterea contextului de construcție către daemon-ul Docker 3.072kB
Pasul 1/2 : FROM python:3.8-alpine
---> a0ee0c90a0db
Pasul 2/2 : RUN pip install --no-cache-dir matplotlib pandas
---> Se rulează în 6740adad3729
Colectarea matplotlib
Descărcare matplotlib-3.1.2.tar.gz (40.9 MB)
EROARE: Comanda a eșuat cu codul de ieșire 1:
comanda: /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
...
EROARE: Comanda a eșuat cu codul de ieșire 1: python setup.py egg_info Consultați jurnalele pentru ieșirea completă a comenzii.
Comanda '/bin/sh -c pip install matplotlib pandas' a returnat un cod non-zero: 1
Ce se întâmplă?
Alpine nu suportă wheels
Dacă te uiți la build-ul bazat pe Debian, vei observa că descarcă matplotlib-3.1.2-cp38-cp38-manylinux1_x86_64.whl.
Acesta este un binar pentru wheel. Alpine descarcă sursele `matplotlib-3.1.2.tar.gz`, deoarece nu suportă standardul .
De ce? Majoritatea distribuțiilor Linux folosesc versiunea GNU (glibc) a bibliotecii C standard, care este de fapt necesară pentru fiecare program scris în C, inclusiv Python. Dar Alpine folosește `musl`, și deoarece acele binare sunt destinate `glibc`, pur și simplu nu sunt o opțiune.
Prin urmare, dacă folosești Alpine, trebuie să compilezi tot codul scris în C din fiecare pachet Python.
Ah, da, lista tuturor acestor dependențe care trebuie compilate va trebui să o cauți singur.
În acest caz obținem următoarele:
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
Și timpul de build durează...
… 25 de minute și 57 de secunde! Iar dimensiunea imaginii este 851MB.
Imaginile bazate pe Alpine se compilează mult mai lent, sunt mai mari și va trebui să căutați toate dependențele. Puteți, desigur, să reduceți dimensiunea compilării folosind dar asta înseamnă că va trebui să faceți și mai multă muncă.
Asta nu e tot!
Alpine poate fi cauza unor bug-uri neașteptate în runtime
- În teorie, musl este compatibil cu glibc, dar în practică, diferențele pot cauza multe probleme. Și dacă există, atunci cu siguranță neplăcute. Iată câteva probleme care pot apărea:
- Alpine are, în mod implicit, o dimensiune mai mică a stivei de thread-uri, ceea ce poate duce la
- Unii utilizatori au descoperit că din cauza modului în care musl alocă memorie (care diferă de glibc).
- Un utilizator
Cu siguranță, aceste erori au fost deja corectate, dar cine știe câte mai sunt.
Nu folosiți imagini Alpine pentru Python
Dacă nu doriți să vă ocupați cu construcții mari și lungi, căutarea de dependențe și potențiale erori — nu folosiți Alpine Linux ca și imagine de bază. .
Sursa: habr.com
