[nawiązanie do amerykańskiej bajki dla dzieci „Mały silnik, który mógł” – ok. uliczka]*

Jak automatycznie tworzyć małe obrazy Dockera dla swoich potrzeb
Niezwykła obsesja
Przez ostatnie kilka miesięcy miałem obsesję na punkcie tego, jak mały może być obraz Dockera, a aplikacja nadal działa?
Rozumiem, pomysł jest dziwny.
Zanim przejdę do szczegółów i zawiłości technicznych, chciałbym wyjaśnić, dlaczego ten problem tak mnie niepokoił, a jak dotyczy Ciebie.
Dlaczego rozmiar ma znaczenie
Zmniejszając zawartość obrazu Dockera, zmniejszamy w ten sposób listę luk. Dodatkowo sprawiamy, że obrazy są czystsze, ponieważ zawierają tylko to, co jest potrzebne do uruchomienia aplikacji.
Jest jeszcze jedna mała zaleta - obrazy pobierają się nieco szybciej, ale moim zdaniem nie jest to aż tak istotne.
Uwaga: jeśli martwisz się rozmiarem, modele Alpine same w sobie są małe i prawdopodobnie będą na Ciebie pasować.
Obrazy bez Distroless
oferuje wybór podstawowych obrazów „distroless”, nie zawierają one menedżerów pakietów, powłok i innych narzędzi, które zwykle widzisz w wierszu poleceń. W rezultacie użyj menedżerów pakietów, takich jak pip и apt nie będzie działać:
FROM gcr.io/distroless/python3
RUN pip3 install numpy
Dockerfile przy użyciu obrazu Python 3 bez dystrybucji
Sending build context to Docker daemon 2.048kB
Step 1/2 : FROM gcr.io/distroless/python3
---> 556d570d5c53
Step 2/2 : RUN pip3 install numpy
---> Running in dbfe5623f125
/bin/sh: 1: pip3: not found
Pipa nie ma na obrazku
Zwykle problem ten rozwiązuje się poprzez wieloetapową kompilację:
FROM python:3 as builder
RUN pip3 install numpy
FROM gcr.io/distroless/python3
COPY --from=builder /usr/local/lib/python3.7/site-packages /usr/local/lib/python3.5/
Montaż wieloetapowy
Rezultatem jest obraz o rozmiarze 130MB. Nieźle! Dla porównania: domyślny obraz Pythona waży 929 MB, a „cieńszy” (3,7-slim) - 179 MB, obraz alpejski (3,7-alpine) wynosi 98,6 MB, podczas gdy podstawowy obraz Distroless użyty w przykładzie to 50,9 MB.
Warto zaznaczyć, że w poprzednim przykładzie kopiujemy cały katalog /usr/local/lib/python3.7/site-packages, które mogą zawierać zależności, których nie potrzebujemy. Chociaż jasne jest, że różnica wielkości wszystkich istniejących obrazów podstawowych Pythona jest różna.
W chwili pisania tego tekstu Google distroless nie obsługuje wielu obrazów: Java i Python są wciąż w fazie eksperymentalnej, a Python istnieje tylko w wersjach 2,7 i 3,5.
Malutkie obrazy
Wracając do mojej obsesji na punkcie tworzenia małych obrazów.
Ogólnie chciałem zobaczyć, jak konstruowane są obrazy distroless. Projekt distroless wykorzystuje narzędzie do kompilacji Google bazel. Jednak instalacja Bazela i napisanie własnych obrazów wymagało dużo pracy (i szczerze mówiąc, wymyślanie koła na nowo jest zabawne i edukacyjne). Chciałem uprościć tworzenie mniejszych obrazów: sam akt tworzenia obrazu powinien być niezwykle prosty, banalny. Żeby nie było dla Ciebie żadnych plików konfiguracyjnych, tylko jedna linijka w konsoli: просто собрать образ для <приложение>.
Jeśli więc chcesz tworzyć własne obrazy, wiedz: istnieje taki unikalny obraz dokera, scratch. Scratch to „pusty” obraz, nie ma w nim żadnych plików, chociaż domyślnie waży - wow! - 77 bajtów.
FROM scratch
Zdrap obraz
Ideą obrazu podstawowego jest to, że możesz skopiować na niego dowolne zależności z komputera hosta i albo użyć ich w pliku Dockerfile (to jakby skopiować je do apt i zainstaluj od zera) lub później, gdy obraz Dockera zostanie zmaterializowany. Pozwala to na pełną kontrolę zawartości kontenera Docker, a co za tym idzie pełną kontrolę nad rozmiarem obrazu.
Teraz musimy jakoś zebrać te zależności. Istniejące narzędzia, takie jak apt umożliwiają pobieranie pakietów, ale są one powiązane z bieżącą maszyną i ostatecznie nie obsługują Windows lub MacOS.
Postanowiłem więc stworzyć własne narzędzie, które automatycznie tworzyłoby obraz bazowy o najmniejszym możliwym rozmiarze i uruchamiało na nim dowolną aplikację. Użyłem pakietów Ubuntu/Debian, przeprowadził selekcję (pobierając pakiety bezpośrednio z repozytoriów) i rekurencyjnie znalazł ich zależności. Program miał automatycznie pobrać najnowszą stabilną wersję pakietu, minimalizując ryzyko bezpieczeństwa.
Nazwałem to narzędzie fetchy, bo on... znajduje i przynosi... to, co jest potrzebne [z angielskiego „przynieś”, „przynieś” – ok. uliczka] Narzędzie działa poprzez interfejs wiersza poleceń, ale jednocześnie oferuje API.
Aby złożyć obraz za pomocą fetchy (tym razem weźmy obraz w języku Python), wystarczy użyć interfejsu CLI w następujący sposób: fetchy dockerize python. Możesz zostać poproszony o podanie docelowego systemu operacyjnego i nazwy kodowej, ponieważ fetchy obecnie używa tylko pakietów opartych na Debian и Ubuntu.
Teraz możesz wybrać, które zależności nie są w ogóle potrzebne (w naszym kontekście) i je wykluczyć. Na przykład Python zależy od Perla, chociaż działa dobrze bez zainstalowanego Perla.
wyniki
Obraz Pythona utworzony za pomocą polecenia fetchy dockerize python3.5 waży tylko 35 MB (jestem więcej niż pewien, że w przyszłości można go uczynić jeszcze lżejszym). Okazuje się, że udało nam się ogolić kolejne 15 WW z obrazu distroless.
Możesz zobaczyć wszystkie zebrane do tej pory obrazy .
Projekt - .
Jeśli brakuje Ci funkcji, po prostu utwórz wniosek - chętnie pomogę :) Co więcej, obecnie pracuję nad integracją innych menedżerów pakietów z fetchy, aby nie było potrzeby wieloetapowej kompilacji.
Źródło: www.habr.com
