
Alpine Linux — често препоръчван като основен образ за Docker. Казват ви, че използването на Alpine ще направи вашите билдове по-малки и процесът на изграждане по-бърз.
Но ако използвате Alpine Linux за Python приложения, то той:
- Прави вашите билдове много по-бавни
- Прави вашите образи по-големи
- Отнема вашето време
- И в крайна сметка може да доведе до грешки по време на работа
Нека разгледаме защо препоръчват Alpine, но защо все пак не трябва да го използвате заедно с Python.
Защо хората препоръчват Alpine?
Да предположим, че ни трябва gcc като част от нашия образ и искаме да сравним Alpine Linux с Ubuntu 18.04 по скорост на билд и краен размер на образа.
Първо, нека изтеглим двата образа и да сравним техния размер:
$ 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
Както виждате, основният образ на Alpine е много по-малък. Сега нека опитаме да инсталираме gcc и да започнем с 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/*
Написването на идеалния Dockerfile излиза извън рамките на тази статия
Нека измерим скоростта на билд:
$ 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
Повтаряме същото и за Alpine (Dockerfile):
FROM alpine
RUN apk add --update gcc
Изграждаме, гледаме времената и размера на изграждане:
$ 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
Както обещахме, образите на базата на Alpine се изграждат по-бързо и по природа са по-малки: 15 секунди вместо 30 и размер на образа 105MB срещу 150MB. Това е доста добре!
Но ако преминем към изграждане на Python приложение, нещата не стоят толкова добре.
Python образ
Python приложенията често използват pandas и matplotlib. Следователно, един от вариантите е да вземем официалния образ на базата на Debian, използвайки такъв Dockerfile:
FROM python:3.8-slim
RUN pip install --no-cache-dir matplotlib pandas
Изграждаме го:
$ docker build -f Dockerfile.slim -t python-matpan.
Изпращане на контекста на изграждането до Docker демона 3.072kB
Стъпка 1/2 : FROM python:3.8-slim
---> 036ea1506a85
Стъпка 2/2 : RUN pip install --no-cache-dir matplotlib pandas
---> Изпълнява се в 13739b2a0917
Събиране на matplotlib
Изтегляне на matplotlib-3.1.2-cp38-cp38-manylinux1_x86_64.whl (13.1 MB)
Събиране на pandas
Изтегляне на pandas-0.25.3-cp38-cp38-manylinux1_x86_64.whl (10.4 MB)
...
Успешно изградена b98b5dc06690
Успешно маркирана python-matpan:latest
реално 0m30.297s
потребител 0m0.043s
система 0m0.020s
Получаваме образ с размер 363MB.
Ще ни се получи ли по-добре с Alpine? Нека опитаме:
FROM python:3.8-alpine
RUN pip install --no-cache-dir matplotlib pandas
$ docker build -t python-matpan-alpine -f Dockerfile.alpine .
Изпращане на контекста на изграждането до Docker демона 3.072kB
Стъпка 1/2 : FROM python:3.8-alpine
---> a0ee0c90a0db
Стъпка 2/2 : RUN pip install --no-cache-dir matplotlib pandas
---> Изпълнява се в 6740adad3729
Събиране на matplotlib
Изтегляне на matplotlib-3.1.2.tar.gz (40.9 MB)
ГРЕШКА: Командата приключи с код 1:
команда: /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
...
ГРЕШКА: Командата приключи с код 1: python setup.py egg_info Проверете журналите за пълния изход на командата.
Командата '/bin/sh -c pip install matplotlib pandas' върна код различен от нула: 1
Какво става?
Alpine не поддържа wheels
Ако погледнете изграждането, основано на Debian, ще видите, че то изтегля matplotlib-3.1.2-cp38-cp38-manylinux1_x86_64.whl.
Това е бинарен файл за wheel. Alpine изтегля изходните файлове `matplotlib-3.1.2.tar.gz`, тъй като не поддържа стандартния .
Защо? Повечето Linux дистрибуции използват GNU версия (glibc) на стандартната библиотека C, която всъщност е необходима за всяка програма, написана на C, включително Python. Но Alpine използва `musl`, а тъй като тези бинарни файлове са предназначени за `glibc`, те просто не са опция.
Затова, ако използвате Alpine, ще трябва да компилирате целия код, написан на C, за всеки Python пакет.
Ах, да, списъкът на всички такива зависимости, които трябва да се компилират, ще трябва да търсите сами.
В този случай получаваме следното:
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
И времето за изграждане е...
… 25 минути 57 секунди! А размерът на образа е 851MB.
Образите на базата Alpine се събират много по-дълго, самите те са с по-голям размер и вие трябва да търсите всички зависимости. Разбира се, можете да намалите размера на сглобяването, като използвате но това означава, че трябва да направите още повече работа.
Това не е всичко!
Alpine може да бъде причина за неочаквани грешки по време на изпълнение
- В теоретичен план musl е съвместим с glibc, но на практика различията могат да причинят много проблеми. И ако възникнат, вероятно ще бъдат неприятни. Ето някои от проблемите, които могат да се появят:
- Alpine по подразбиране има по-малък размер на стека на нишката, което може да доведе до
- Някои потребители откриха, че поради начина, по който musl разпределя памет (различава се от glibc).
- Един от потребителите
Сигурно тези грешки вече са поправени, но кой знае колко още има.
Не използвайте образи Alpine за Python
Ако не искате да се занимавате с големи и дълги изграждания, търсене на зависимости и потенциални грешки — не използвайте Alpine Linux като базов образ. .
Източник: habr.com
