Warum sollte man Ubuntu als Docker-Base-Image nutzen, wenn es auch Alpine gibt?
Wenn man ein Base-Image für die Erstellung eines neuen Containers auswählt ist man vielleicht geneigt, ein möglichst schlankes Base-Image zu wählen. Schließlich führen kleinere Basis-Images zu schnelleren Build-Vorgängen. Außerdem gelten sie als sicherer, weil sie eine geringere Angriffsfläche bieten.
Das heißt jedoch nicht, dass kleiner immer besser ist, wenn man ein Basis-Image auswählt. Um das zu zeigen, gehen wir in diesem Artikel die Unterschiede zwischen zwei grundlegend verschiedenen Arten von Basis-Images durch: Solche, die auf Ubuntu Linux basieren, und solche, die auf Alpine Linux basieren.
Wie wir sehen werden, ist zwar keines der beiden Base-Images grundsätzlich besser als das andere, aber für gewisse Anwendungsfälle ist das eine oder andere besser geeignet. Nicht immer sollte man Alpine gegenüber Ubuntu bevorzugen, nur weil Ubuntu ein größeres Basis-Image ist.
Inhalt:
- Warum die Wahl des richtigen Base-Images wichtig ist
- Ubuntu als Base-Image verwenden
- Arbeiten mit Ubuntu-Base-Images
- Arbeiten mit Alpine-Base-Images
- Vorteile von Ubuntu gegenüber Alpine
- Nachteile von Ubuntu im Vergleich zu Alpine
- Warum Ubuntu manchmal die bessere Wahl für ein Base-Image ist als Alpine
Warum die Wahl des richtigen Base-Images wichtig ist
Die Auswahl des richtigen Base-Images für den Container ist einer der ersten Schritte zur erfolgreichen Containerisierung einer Anwendung. Der Typ des Base-Images, den man auswählt, ist aus folgenden Gründen wichtig:
- Abhängigkeiten: Wenn die Abhängigkeiten, die die Anwendung zur Ausführung benötigt, im Basis-Image enthalten sind, muss man bei der Konfiguration des Docker-Images weniger Aufwand betreiben, um eigene Funktionen zum Dockerfile hinzuzufügen.
- Erweiterbarkeit: Sind mehr Abhängigkeiten und andere Ressourcen in das Base-Image integriert, lassen sich die Container später einfacher aktualisieren, ohne dass Dockerdateien geändert werden müssen.
- Sicherheit: Je weniger Komponenten im Base Image enthalten sind, desto geringer ist das Risiko, dass das Image eine anfällige Bibliothek oder eine andere Ressource enthält, die Angreifer ausnutzen könnten.
- Aufgeblasenes Image: Die Verwendung eines unnötig großen Base-Images kann zu einer Überfrachtung des Images führen, d. h. zu großen Container-Images, deren Download länger dauert, weil sie Komponenten enthalten, die für die Anwendung nicht gebraucht werden.
Für die Auswahl des richtigen Base-Images gilt es also, die richtige Balance zwischen der Anzahl der im Image enthaltenen Komponenten einerseits und der Gesamtgröße des Images andererseits zu finden. Meistens handelt es sich dabei um gegensätzliche Anforderungen, denn je mehr Utilities und Libraries man in das Base-Image aufnimmt, desto größer wird es.
Generell lassen sich Base-Images in zwei Hauptkategorien einteilen. Die erste Kategorie sind Base-Images, die auf der Grundlage kompletter Betriebssysteme, wie Ubuntu, erstellt werden. Die andere Kategorie umfasst Images, die auf minimalistischen Betriebssystemen basieren, wie Alpine Linux.
Am Beispiel von Ubuntu und Alpine wollen wir die beiden Arten von Base-Images vergleichen und ihre Vor- und Nachteile abwägen.
Ubuntu als Base-Image verwenden
Die Ubuntu-Base-Images, die man auf Docker Hub findet, werden unter Verwendung des Root-Dateisystems von Ubuntu Base, einer Variante des Ubuntu-Linux-Betriebssystems, erstellt.
Dabei muss man wissen, dass Ubuntu Base eine abgespeckte Version von Ubuntu ist, verglichen mit der Desktop-Version von Ubuntu, die man auf dem Computer installieren kann. In Ubuntu Base fehlt die Software, die für die grafische Oberfläche, die Office-Programme und andere Hilfsprogramme erforderlich ist, weil sie für die meisten Anwendungsfälle in Containern irrelevant sind. Selbst wenn man Ubuntu als Basis-Image verwendet, erhält man also ein relativ schlankes Image; die aktuellen Base-Images von Ubuntu sind kleiner als 75 Megabyte.
Wenn man jedoch das Base-Image von Ubuntu 20.04 startet und sich den Inhalt des /bin-Verzeichnisses ansieht, entdeckt Hunderte von Dienstprogrammen (und das ist nur /bin; es gibt noch weitere Software in anderen Teilen des Dateisystems):
apt hostid script
apt-cache hostname scriptlive
apt-cdrom i386 scriptreplay
apt-config iconv sdiff
apt-get id sed
apt-key infocmp select-editor
apt-mark infotocap sensible-browser
arch install sensible-editor
awk ionice sensible-pager
b2sum ipcmk seq
base32 ipcrm setarch
base64 ipcs setpriv
basename ischroot setsid
basenc join setterm
bash kill sg
bashbug last sh
captoinfo lastb sha1sum
cat lastlog sha224sum
chage ldd sha256sum
chattr link sha384sum
chcon linux32 sha512sum
chfn linux64 shred
chgrp ln shuf
chmod locale skill
choom locale-check slabtop
chown localedef sleep
chrt logger snice
chsh login sort
cksum logname split
clear ls stat
clear_console lsattr stdbuf
cmp lsblk stty
comm lscpu su
cp lsipc sum
csplit lslocks sync
cut lslogins tabs
dash lsmem tac
date lsns tail
dd man tar
deb-systemd-helper mawk taskset
deb-systemd-invoke mcookie tee
debconf md5sum tempfile
debconf-apt-progress md5sum.textutils test
debconf-communicate mesg tic
debconf-copydb mkdir timeout
debconf-escape mkfifo tload
debconf-set-selections mknod toe
debconf-show mktemp top
delpart more touch
df mount tput
diff mountpoint tr
diff3 mv true
dir namei truncate
dircolors nawk tset
dirname newgrp tsort
dmesg nice tty
dnsdomainname nisdomainname tzselect
domainname nl uclampset
dpkg nohup umount
dpkg-deb nproc uname
dpkg-divert nsenter uncompress
dpkg-maintscript-helper numfmt unexpand
dpkg-query od uniq
dpkg-realpath pager unlink
dpkg-split partx unshare
dpkg-statoverride passwd update-alternatives
dpkg-trigger paste uptime
du pathchk users
echo perl utmpdump
egrep perl5.34.0 vdir
env pgrep vmstat
expand pidof w
expiry pidwait wall
expr pinky watch
factor pkill wc
faillog pldd wdctl
fallocate pmap whereis
false pr which
fgrep printenv which.debianutils
fincore printf who
find prlimit whoami
findmnt ps x86_64
flock ptx xargs
fmt pwd yes
fold pwdx ypdomainname
free rbash zcat
getconf readlink zcmp
getent realpath zdiff
getopt renice zdump
gpasswd reset zegrep
gpgv resizepart zfgrep
grep rev zforce
groups rgrep zgrep
gunzip rm zless
gzexe rmdir zmore
gzip run-parts znew
Wenn Sie sich fragen, wie viele Dateien das insgesamt sind, hier ist die Antwort:
# ls /bin | wc -l 294
Sie sehen also, dass sich im /bin Verzeichnis des Ubuntu Base Images 294 Dienstprogramme befinden. All diese Programme sind im Base-Image von Ubuntu standardmäßig vorhanden, ohne dass Entwickler sie ergänzen müssen.
Arbeiten mit Ubuntu-Base-Images
Um Ubuntu als Base-Image für den Container zu verwenden, erstellt man zunächst eine Dockerdatei, die Ubuntu als Image identifiziert. Zum Beispiel:
FROM ubuntu:20.04 COPY app /usr/bin/app
Dieses Dockerfile verwendet Ubuntu 20.04 als Base-Image und installiert darauf eine App namens “app”.
Wenn man weitere Software installieren und in den Container einbinden möchte, muss man das Dockerfile so einrichten, dass es apt ausführt und die gewünschten Pakete installiert. Zum Beispiel:
FROM ubuntu:20.04 RUN apt update; apt -y install package1 package2 COPY app /usr/bin/app
Um einen Container aus dem Dockerfile zu erstellen, führen Sie folgendes aus:
docker build -t container_name
Arbeiten mit Alpine Base Images
Wenn man sich für die Nutzung eines Alpine Base-Images entscheidet, erstellt man einfach eine Dockerdatei wie die folgende:
FROM alpine COPY app /usr/bin/app
Will man zusätzliche Software installieren , kann man das mit apk, dem Paketmanager von Alpine, tun:
FROM alpine RUN apk add --update --no-cache package1 package2 COPY app /usr/bin/app
Nachdem das Dockerfile richtig konfiguriert ist, bauen wir unseren Container wie gewohnt:
docker build -t container_name
Vorteile von Ubuntu gegenüber Alpine
Ubuntu-Base-Images bieten, auch aufgrund dieser umfangreichen Sammlung eingebauter Tools, gewisse Vorteile gegenüber wirklich minimalistischen Base-Images wie Alpine:
- Mehr Tools: Ubuntu Base Images enthalten standardmäßig mehr Libraries und Dienstprogramme. Das reduziert die Menge an Software, die man zusätzlich zum Basis-Image installieren muss, wenn man sein eigenes Container-Image erstellt.
- Apt standardmäßig: Apt, der Ubuntu-Paketmanager, ist in die Base-Images von Ubuntu integriert. Mit apt kann man beim Erstellen des Containers aus den 60.000 Paketen von Ubuntu zusätzliche Software installieren. Alpine Linux bietet ebenfalls einen Paketmanager, der aber nicht auf so viele Pakete zugreifen kann wie apt.
- Breite Unterstützung: Ubuntu ist eine der beliebtesten Linux-Distributionen und wird nicht nur für den Betrieb von Containern, sondern auch für eine Reihe anderer Zwecke verwendet. Das heißt, dass Ubuntu Entwicklern und Systemadministratoren wahrscheinlich vertraut ist, auch wenn sie Docker bisher nicht verwendet haben. Alpine Linux ist außerhalb des Docker-Kontexts weniger verbreitet.
Nachteile von Ubuntu im Vergleich zu Alpine
Während ein Base-Image von Ubuntu viele Vorteile mit sich bringt, kann Alpine Linux in manchen Situationen die bessere Wahl sein. Zu den Nachteilen von Ubuntu im Vergleich zu Alpine gehören:
- Größere Image-Größe: Alpine-Base-Images sind insgesamt nur etwa 5,5 Megabyte groß – viel kleiner als die etwa 75 Megabyte, die Ubuntu beansprucht. Folglich sind Container, die mit Alpine als Base-Image erstellt werden, auch entsprechend kleiner. Dadurch benötigen Alpine-basierte Container weniger Zeit um heruntergeladen, gescannt und (in den meisten Fällen) auch ausgeführt zu werden.
- Größere Angriffsfläche: Da Ubuntu Base Images standardmäßig viel mehr Dienstprogramme und Bibliotheken enthalten als Alpine, bergen sie auch ein höheres Sicherheitsrisiko.
Um ein Gefühl dafür zu bekommen, um wie viel kleiner Alpine ist, hier eine Liste der Utilities, die in /bin im Basis-Image von Alpine enthalten sind:
arch
ash
base64
bbconfig
busybox
cat
chgrp
chmod
chown
cp
date
dd
df
dmesg
dnsdomainname
dumpkmap
echo
ed
egrep
false
fatattr
fdflush
fgrep
fsync
getopt
grep
gunzip
gzip
hostname
ionice
iostat
ipcalc
kbd_mode
kill
link
linux32
linux64
ln
login
ls
lzop
makemime
mkdir
mknod
mktemp
more
mount
mountpoint
mpstat
mv
netstat
nice
pidof
ping
ping6
pipe_progress
printenv
ps
pwd
reformime
rev
rm
rmdir
run-parts
sed
setpriv
setserial
sh
sleep
stat
stty
su
sync
tar
touch
true
umount
uname
usleep
watch
zcat
Das sind insgesamt 81 Dienstprogramme in /bin – keine geringe Anzahl, aber immer noch deutlich weniger als die 294 von Ubuntu.
Und wenn man genau hinsieht, entdeckt man, dass die meisten Dienstprogramme von Alpine eigentlich nur symbolische Links zu BusyBox sind, einer ausführbaren Datei, die eine Reihe von Unix-Tools in einer einzigen Anwendung bereitstellt:
# ls -l /bin total 808 lrwxrwxrwx 1 root root 12 Apr 4 16:06 arch -> /bin/busybox lrwxrwxrwx 1 root root 12 Apr 4 16:06 ash -> /bin/busybox lrwxrwxrwx 1 root root 12 Apr 4 16:06 base64 -> /bin/busybox lrwxrwxrwx 1 root root 12 Apr 4 16:06 bbconfig -> /bin/busybox -rwxr-xr-x 1 root root 824984 Apr 4 10:19 busybox …
Technisch gesehen enthält Alpine also nur ein einziges Dienstprogramm – BusyBox. In diesem Sinne ist Alpine sogar noch schlanker und einfacher abzusichern, weil die einzigen Schwachstellen, über die man sich Gedanken machen muss, nur die sind, die BusyBox betreffen. Das ist bei Ubuntu nicht der Fall, wo jedes der vielen hundert Tools, die standardmäßig installiert sind, von einer Reihe von Sicherheitslücken betroffen sein kann.
Fazit: In Anwendungsfällen, in denen es auf Sicherheit ankommt und/oder in denen die Anwendung nur wenige Abhängigkeiten hat, ist es sinnvoller, Alpine als Basis-Image zu verwenden als Ubuntu oder eine ähnliche ” vollwertige” Linux-Distribution.
Warum Ubuntu manchmal die bessere Wahl für ein Base-Image ist als Alpine
Sicherlich ist Alpine ein kleineres, schlankeres Base-Image als Ubuntu. Das heißt aber nicht, dass Alpine als Base-Image immer besser ist. In Situationen, in denen Docker-Container auf zusätzliche Dienstprogramme und Libraries angewiesen sind, die in Ubuntu enthalten sind, ist es sinnvoll, Ubuntu statt Alpine zu nutzen.