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):

 

# ls /bin
‘[‘               hardlink          runcon
 addpart           head              savelog
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:

# ls -1 /bin
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.