Pourquoi utiliser Ubuntu comme image de base Docker alors qu’Alpine existe ?

Lorsque vous choisissez une image de base pour la création d’un nouveau conteneur, votre instinct peut être de sélectionner l’image de base la plus légère possible. Après tout, les images de base plus petites accélèrent les opérations de génération. Elles sont également plus sûres, dans le sens où elles ont une surface d’attaque plus petite.

Cela ne signifie pas, cependant, qu'une base plus petite est toujours à privilégier comme image de base. Pour prouver ce point, cet article passe en revue les différences entre deux types d’images de base fondamentalement distincts : Ceux basés sur Ubuntu Linux et ceux basés sur Alpine Linux.

Comme nous le verrons, bien qu’aucune image de base ne soit intrinsèquement meilleure que l’autre, chacune est mieux adaptée à certains cas d’utilisation. Vous ne devriez pas nécessairement choisir Alpine plutôt qu’Ubuntu simplement parce qu’Ubuntu est une image de base plus grande.

Table des matières

Pourquoi est-il important de choisir la bonne image de base ?

Le choix de l’image de base adaptée à votre conteneur est l’une des premières étapes de la conteneurisation réussie d’une application. Le type d’image de base que vous sélectionnez est important pour les raisons suivantes :

  • Dépendances : Si les dépendances dont votre application a besoin pour s’exécuter sont incluses dans l’image de base, vous n’aurez pas à faire autant de travail lors de la configuration de votre image Docker en ajoutant des commandes personnalisées à votre fichier Dockerfile.
  • Extensibilité : Le fait d’avoir plus de dépendances et d’autres ressources intégrées dans l’image de base facilite également la mise à jour de vos conteneurs au fil du temps sans avoir à modifier les fichiers Docker.
  • Sécurité : Moins vous avez de composants dans votre image de base, plus le risque que l’image contienne une bibliothèque vulnérable ou une autre ressource que les attaquants pourraient exploiter est faible.
  • Image « bloat » : L’utilisation d’une image de base inutilement grande peut entraîner un gonflement de l’image, c’est-à-dire des images conteneur volumineuses – et donc plus longues à télécharger – car elles contiennent des composants dont l’application n’a pas besoin.

Pour sélectionner la bonne image de base, vous devez donc trouver le bon équilibre entre, d’une part, le nombre de ressources incluses dans l’image et, d’autre part, la taille globale de l’image. Celles-ci ont tendance à être des priorités concurrentes car plus vous incluez d’utilitaires et de bibliothèques dans votre image de base, plus l’image de base sera grande.

En général, les images de base se répartissent en deux catégories principales. La première est constituée d’images de base créées à l’aide de systèmes d’exploitation à grande échelle, comme Ubuntu. L’autre comprend des images basées sur des systèmes d’exploitation minimalistes, comme Alpine Linux.

En utilisant Ubuntu et Alpine comme exemples, comparons chaque type d’image de base et pesons ses avantages et ses inconvénients.

Utiliser Ubuntu comme image de base

Les images de base Ubuntu, que vous pouvez trouver sur Docker Hub, sont créées à l’aide du système de fichiers racine d’Ubuntu Base, une variante du système d’exploitation Ubuntu Linux.

Il est important de noter qu’Ubuntu Base est une version plus légère d’Ubuntu que si vous installiez la version de bureau d’Ubuntu sur votre ordinateur. La base Ubuntu ne contient pas le logiciel nécessaire pour exécuter une interface graphique, des logiciels bureautiques et d’autres utilitaires qui ne sont pas pertinents pour la plupart des cas d’utilisation de conteneurs. Ainsi, même lorsque vous utilisez Ubuntu comme image de base, vous obtenez une image relativement maigre ; les images de base Ubuntu actuelles ont une taille inférieure à 75 mégaoctets.

Néanmoins, si vous exécutez l’image de base Ubuntu 20.04 et affichez le contenu du répertoire /bin, vous verrez qu’il contient des centaines d’utilitaires (et il s'agit juste de /bin ; il y a des logiciels supplémentaires dans d’autres parties du système de fichiers) :

# 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

Si vous vous demandez combien de fichiers cela représente en tout, voici la réponse :

# ls /bin | wc -l
294

Comme vous pouvez le voir, il y a 294 utilitaires dans le répertoire / bin dans l’image de base d’Ubuntu. Tous ces logiciels sont disponibles dans l’image de base Ubuntu par défaut, il n'est pas nécessaire que les développeurs les ajoutent.

Utilisation des images de base Ubuntu

Pour utiliser Ubuntu comme image de base pour votre conteneur, créez d’abord un fichier Dockerfile qui identifie Ubuntu comme image. Par exemple :

FROM ubuntu:20.04
COPY app /usr/bin/app

Ce Dockerfile utilise Ubuntu 20.04 comme image de base, et il y installe une application appelée « app ».

Si vous vouliez installer un logiciel supplémentaire et l’inclure dans votre conteneur, vous configureriez le Dockerfile pour exécuter apt et installer les packages souhaités. Par exemple :

FROM ubuntu:20.04
RUN apt update; apt -y install package1 package2
COPY app /usr/bin/app

Pour créer un conteneur à partir du Dockerfile, exécutez :

docker build -t container_name

Utilisation des images de base Alpine

Si vous choisissez d’utiliser une image de base Alpine, il vous suffit de créer un fichier Dockerfile tel que :

FROM alpine
COPY app /usr/bin/app

Si vous avez besoin d’installer un logiciel supplémentaire, vous pouvez le faire en utilisant apk, le gestionnaire de packages d’Alpine :

FROM alpine
RUN apk add –update –no-cache package1 package2
COPY app /usr/bin/app

Avec votre Dockerfile correctement configuré, allez-y et construisez votre conteneur comme d’habitude :

docker build -t container_name

Avantages d'Ubuntu par rapport à Alpine

Grâce en partie à cette vaste collection d’outils intégrés, les images de base Ubuntu offrent certains avantages par rapport aux images de base vraiment minimalistes, comme Alpine :

  • Plus d’outils : Les images de base Ubuntu incluent plus de bibliothèques et d’utilitaires par défaut. Cela réduit la quantité de logiciels que vous devez installer au-dessus de l’image de base lors de la création de votre propre image de conteneur.
  • Apt par défaut : Apt, le gestionnaire de packages Ubuntu, est intégré aux images de base Ubuntu. Vous pouvez utiliser apt pour installer des logiciels supplémentaires à partir des 60 000 packages d’Ubuntu lors de la création d’un conteneur. Alpine Linux propose également un gestionnaire de packages, mais il n’a pas accès à autant de packages qu'apt.
  • Un support étendu : Ubuntu est l’une des distributions Linux les plus populaires, et elle est largement utilisée non seulement pour exécuter des conteneurs, mais à plusieurs autres fins. Cela signifie qu’Ubuntu sera probablement familier aux développeurs et aux administrateurs système, même s’ils n’ont jamais utilisé Docker auparavant. Alpine Linux est moins connu en dehors du contexte de Docker.

Désavantages d'Ubuntu par rapport à Alpine

Bien qu’une image de base Ubuntu présente des avantages à bien des égards, Alpine Linux est un meilleur choix dans certaines situations. Les inconvénients d’Ubuntu par rapport à Alpine incluent :

  • Taille d’image plus grande : Les images de base Alpine totalisent environ 5,5 mégaoctets, soit beaucoup moins que les quelque 75 mégaoctets utilisés par Ubuntu. En conséquence, les conteneurs créés en utilisant Alpine comme image de base seront également plus petits. À leur tour, le téléchargement, la numérisation et l'exécution (dans la plupart des cas) des conteneurs basés sur Alpine prendra moins de temps.
  • Surface d’attaque plus large : Parce que les images de base Ubuntu incluent beaucoup plus d’utilitaires et de bibliothèques par défaut qu’Alpine, les risques liés à la sécurité sont plus élevés.

Pour avoir une idée de la taille d’Alpine, voici une liste des utilitaires inclus dans /bin dans l’image de base d’Alpine :

# ls -1 /bin
arch
ash
base64
bbconfig
busybox
cat
chgrp
chmod
chown
cp
date
dd
df
dmesg
dnsdomainname
dumpkmap
écho
ed
egrep
faux
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
vrai
umount
uname
usleep
watch
zcat

Cela fait un total de 81 utilitaires dans /bin – un nombre non négligeable, mais toujours beaucoup moins que les 294 d’Ubuntu.

De plus, si vous regardez de plus près, vous découvrirez que la plupart des utilitaires d’Alpine ne sont en fait que des liens symboliques vers BusyBox, un exécutable qui fournit un certain nombre d’outils Unix dans une seule application :

# 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

Donc, techniquement parlant, Alpine ne contient vraiment qu’un seul utilitaire – BusyBox. En ce sens, Alpine est encore plus léger et plus facile à sécuriser, car les seules vulnérabilités dont vous devez vous soucier sont celles qui affectent BusyBox. Ce n’est pas le cas dans Ubuntu, où chacun des centaines d’outils installés par défaut pourrait être soumis à un certain nombre de vulnérabilités.

La conclusion : Dans les cas d’utilisation où la sécurité est une priorité absolue et / ou où votre application a très peu de dépendances, il est plus logique d’utiliser Alpine comme image de base qu’Ubuntu ou une distribution Linux similaire « complète ».

Pourquoi Ubuntu est parfois un meilleur choix d’image de base qu’Alpine

Il est certain qu’Alpine crée une image de base plus petite et plus maigre qu’Ubuntu. Cela ne signifie pas, cependant, qu’Alpine est toujours à privilégier comme image de base. Dans les situations où vos conteneurs Docker ont besoin des utilitaires et bibliothèques supplémentaires inclus dans Ubuntu, il est logique d’opter pour Ubuntu plutôt qu’Alpine.