
Alpine Linux — häufig empfohlen als Basisimage für Docker. Ihnen wird gesagt, dass die Verwendung von Alpine Ihre Builds kleiner macht und der Build-Prozess schneller ist.
Aber wenn Sie Alpine Linux für Python-Anwendungen verwenden, dann:
- Macht Ihre Builds deutlich langsamer.
- Macht Ihre Images größer.
- Verschwendet Ihre Zeit.
- Und kann letztendlich zu Laufzeitfehlern führen.
Lassen Sie uns betrachten, warum Alpine empfohlen wird, aber warum Sie es dennoch nicht zusammen mit Python verwenden sollten.
Warum empfehlen die Leute Alpine?
Angenommen, wir benötigen gcc als Teil unseres Images und möchten Alpine Linux mit Ubuntu 18.04 hinsichtlich der Build-Geschwindigkeit und der Endgröße des Images vergleichen.
Zunächst laden wir zwei Images herunter und vergleichen ihre Größe:
$ 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
Wie Sie sehen, ist das Basisimage für Alpine viel kleiner. Lassen Sie uns jetzt versuchen, gcc zu installieren und beginnen wir mit 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/*
Das Schreiben perfekter Dockerfiles geht über diesen Artikel hinaus.
Messen wir die Build-Geschwindigkeit:
$ 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 Sekunden zuvor 150MB
Wiederholen Sie dasselbe für Alpine (Dockerfile):
FROM alpine
RUN apk add --update gcc
Bauen wir, schauen wir auf die Zeit und die Größe des Builds:
$ 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 Sekunden zuvor 105MB
Wie versprochen, bauen sich die von Alpine basierenden Images schneller und sind selbst kleiner: 15 Sekunden statt 30 und die Größe des Images beträgt 105MB gegenüber 150MB. Das ist ziemlich gut!
Aber wenn wir zur Erstellung einer Python-Anwendung wechseln, sieht es nicht so rosig aus.
Python-Image
Python-Anwendungen verwenden häufig pandas und matplotlib. Daher ist eine Option, das offizielle Image auf Debian-Basis zu verwenden, indem wir folgendes Dockerfile verwenden:
FROM python:3.8-slim
RUN pip install --no-cache-dir matplotlib pandas
Bauen wir es:
$ 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
Wir erhalten ein Image mit einer Größe von 363 MB.
Wird es mit Alpine besser? Lassen Sie uns das versuchen:
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 Überprüfen Sie die Protokolle für die vollständige Befehlsausgabe.
Der Befehl '/bin/sh -c pip install matplotlib pandas' gab einen ungleich Null-Code zurück: 1
Was passiert?
Alpine unterstützt keine Wheels
Wenn Sie sich das Docker-Image ansehen, das auf Debian basiert, werden Sie sehen, dass es matplotlib-3.1.2-cp38-cp38-manylinux1_x86_64 herunterlädt.whl.
Das ist das Binary für Wheel. Alpine lädt hingegen den Quellcode `matplotlib-3.1.2.tar.gz` herunter, da es die standardmäßigenwheelsnicht unterstützt. .
Daher müssen Sie, wenn Sie Alpine verwenden, jeden in C geschriebenen Code in jedem Python-Paket kompilieren.
Ach ja, die Liste aller Abhängigkeiten, die kompiliert werden müssen, müssen Sie selbst suchen.
In diesem Fall erhalten wir Folgendes:
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
Und die Build-Zeit beträgt…
… 25 Minuten 57 Sekunden! Und die Größe des Images beträgt 851MB.
… 25 Minuten 57 Sekunden! Und die Bildgröße beträgt 851MB.
Alpine-basierte Images benötigen viel länger zum Erstellen, sie sind auch größer und Sie müssen außerdem alle Abhängigkeiten suchen. Man kann natürlich die Größe des Builds reduzieren, indem man , aber das bedeutet, dass man noch mehr Arbeit leisten muss.
Das ist noch nicht alles!
Alpine kann die Ursache für unerwartete Bugs zur Laufzeit sein.
- In der Theorie ist musl mit glibc kompatibel, aber in der Praxis können die Unterschiede viele Probleme verursachen. Und wenn sie auftreten, werden sie sicherlich unangenehm sein. Hier sind einige Probleme, die auftreten können:
- Alpine hat standardmäßig eine kleinere Thread-Stack-Größe, was zu
- Einige Benutzer haben festgestellt, dass wegen der Art, wie musl Speicher zuweist (was sich von glibc unterscheidet).
- Einer der Benutzer
Diese Fehler wurden sicherlich bereits behoben, aber wer weiß, wie viele es noch gibt.
Verwenden Sie keine Alpine-Images für Python.
Wenn Sie sich nicht mit großen und langen Builds, der Suche nach Abhängigkeiten und potenziellen Fehlern herumschlagen möchten, verwenden Sie Alpine Linux nicht als Basis-Image. .
Quelle: habr.com
