Construire une image
Objectif de cet atelier pratique
- Construire nos premières images à l'aide d'un Dockerfile
Anatomie d'un Dockerfile
Nous avons déjà eu l'occasion de voir un Dockerfile. Voici un petit aperçu
des instructions que nous pouvons y trouver :
- 
FROM– indique l'image de départ sur laquelle on va se baser.
- 
CMD– Définit la commande à exécuter lors du lancement de l'image. Peut également être utilisé pour définir l'argument par défaut de l'instructionENTRYPOINT.
- 
RUN– Exécute une commande pour contribuer à la construction de votre image.
- 
EXPOSE– Ouvre un ou plusieurs ports du réseau.
- 
VOLUME– Crée un point de montage.
- 
COPY– Ajoute un fichier dans l'image.
- 
LABEL– Ajoute des métadonnées à l'image dans un format clé/valeur.
- 
ENV– Définit une variable d'environnement.
- 
ENTRYPOINT– Détermine l'exécutable qui doit être lancé au démarrage du conteneur. UtilisezCMDpour passer des options à cet exécutable.
Prenons un Dockerfile pour illustrer la différence subtile entre les
instructions ENTRYPOINT et CMD :
FROM rockylinux:8
LABEL maintainer="Microlinux <info@microlinux.fr>"
ENTRYPOINT ["/usr/bin/ping"]
CMD ["www.docker.com"]
- 
Nous utilisons l'image de Rocky Linux dans sa version 8 comme base pour notre image personnalisée. 
- 
La deuxième ligne est une instruction LABEL, avec une paire clé/valeur. Ici, la clé estmaintainer, suivie d'un signe égal, puis de la valeurMicrolinux <info@microlinux.fr>entre guillemets. Nous ajoutons simplement des métadonnées à notre image.
- 
L'instruction ENTRYPOINTfait en sorte que le conteneur exécute la commande/usr/bin/pingau démarrage.
- 
Notez que /usr/bin/pingest entouré de guillemets et de crochets. Le format utilisé ici est un tableau JSON.
- 
L'instruction CMDutilise également un tableau JSON. Ici, nous fournissonswww.docker.comcomme argument àENTRYPOINT.
- 
Au final, la commande qui va être exécutée sera /usr/bin/ping www.docker.com.
- 
Lorsque vous créez un Dockerfile, il vaut mieux le nommerDockerfile.
La commande docker build permet de construire l'image :
- 
L'option -tpermet de spécifier un nom et un tag pour l'image.
- 
Notez le format utilisé pour le nom de l'image : identifiant Docker + barre oblique + nom du dépôt + deux-points + tag. 
- 
Si vous ne fournissez pas de tag, la valeur latestest présumée. Nous explicitions cette information ici par souci de précision.
- 
La commande docker buildattend un chemin où elle pourra trouver unDockerfileutilisé pour construire l'image. Le point.indique àdocker buildqu'il faut utiliser leDockerfiledans le répertoire courant.
Vérifions si l'image est bien disponible :
$ docker image ls
REPOSITORY             TAG       IMAGE ID       CREATED         SIZE
kikinovak/dockerping   latest    b06be6abe1c9   6 minutes ago   197MB
rockylinux             8         4e97feadb276   5 weeks ago     197MB
Notez que nous avons deux images :
- 
Dans un premier temps, Docker a téléchargé notre image de base rockylinux:8qui correspond à l'instructionFROMde notreDockerfile.Ensuite, Docker a exécuté les commandes et les instructions de notre Dockerfilepour créer l'imagekikinovak/dockerping.
Maintenant que j'ai mon image, je peux la publier sur Docker Hub. Pour ce faire, je dois d'abord m'authentifier avec mon identifiant Docker :
À présent, je peux télécharger mon image sur Docker Hub :
$ docker push kikinovak/dockerping
Using default tag: latest
The push refers to repository [docker.io/kikinovak/dockerping]
b9674b668e06: Mounted from library/rockylinux
latest: digest: sha256:8fd30a6170de239ec761b42cc3a7b91412c0... size: 529
Je vérifie si mon image apparaît bien sur Docker Hub :
Je retourne dans ma console et je lance mon image :
$ docker run kikinovak/dockerping
PING d1syzps6kort6n.cloudfront.net (52.222.174.72) 56(84) bytes of data.
64 bytes from server-52-222-174-72.fra54.r.cloudfront.net (52.222.174.72):
icmp_seq=1 ttl=241 time=28.6 ms
64 bytes from server-52-222-174-72.fra54.r.cloudfront.net (52.222.174.72):
icmp_seq=2 ttl=241 time=28.4 ms
64 bytes from server-52-222-174-72.fra54.r.cloudfront.net (52.222.174.72):
icmp_seq=3 ttl=241 time=28.3 ms
Notre conteneur tourne et envoie une série de ping vers docker.com. Appuyez
sur Ctrl+C pour l'arrêter.
Rappelons-nous le contenu du Dockerfile utilisé pour créer cette image :
La valeur par défaut de CMD peut être substituée en fournissant une option en
ligne de commande :
$ docker run kikinovak/dockerping google.fr
PING google.fr (142.250.74.227) 56(84) bytes of data.
64 bytes from par10s40-in-f3.1e100.net (142.250.74.227): icmp_seq=1 ttl=118
time=19.9 ms
64 bytes from par10s40-in-f3.1e100.net (142.250.74.227): icmp_seq=2 ttl=118
time=19.8 ms
64 bytes from par10s40-in-f3.1e100.net (142.250.74.227): icmp_seq=3 ttl=118
time=19.10 ms
Dans l'exemple ci-dessus, la commande ping utilisée était déjà présente dans
l'image de base. Or, dans certains cas, le ou les logiciels utilisés peuvent ne
pas être présents dans l'image de départ. Si nous nous étions basés sur l'image
de Debian, voici ce que nous aurions obtenu :
$ docker pull debian:latest
$ docker run -it --name debianping debian:latest
root@c098cce01e95:/# ping docker.com
bash: ping: command not found
Dans ce cas, nous pouvons très bien ajouter la ou les commandes en question. En l'occurrence :
root@c098cce01e95:/# apt update
...
root@c098cce01e95:/# apt install iputils-ping
...
root@c098cce01e95:/# which ping
/bin/ping
root@c098cce01e95:/# ping docker.com
PING docker.com (141.193.213.20) 56(84) bytes of data.
64 bytes from 141.193.213.20 (141.193.213.20): icmp_seq=1 ttl=57 time=21.6 ms
64 bytes from 141.193.213.20 (141.193.213.20): icmp_seq=2 ttl=57 time=21.2 ms
64 bytes from 141.193.213.20 (141.193.213.20): icmp_seq=3 ttl=57 time=21.7 ms
Voici le Dockerfile qui va nous permettre de réaliser cette opération :
FROM debian:latest
LABEL maintainer="Microlinux <info@microlinux.fr>"
RUN apt-get update \
    && apt-get install -y iputils-ping \
    && apt-get clean
ENTRYPOINT ["/usr/bin/ping"]
CMD ["www.docker.com"]
- 
Debian utilise les gestionnaires de paquets aptetapt-get. Le premier est plutôt utilisé de manière interactive, alors que le second servira plutôt dans les scripts.
- 
Nous regroupons toutes les commandes apt-geten une seule instructionRUNde manière à produire une seule couche par-dessus l'image de base.
- 
Théoriquement nous pourrions très bien nous servir de plusieurs commandes RUN, mais chacune d'entre elles résulterait en une couche supplémentaire.
- 
L'antislash \en fin de ligne est simplement utilisé pour améliorer la lisibilité duDockerfile.
- 
La commande apt-get cleansert à supprimer les paquets téléchargés, ce qui nous permet de réduire la taille de l'image résultante.
Construisez et exécutez cette image :
$ docker build -t kikinovak/debianping .
...
$ docker run kikinovak/debianping
PING emzm5pam37e4.wpeproxy.com (141.193.213.20) 56(84) bytes of data.
64 bytes from 141.193.213.20 (141.193.213.20): icmp_seq=1 ttl=57 time=21.1 ms
64 bytes from 141.193.213.20 (141.193.213.20): icmp_seq=2 ttl=57 time=21.2 ms
64 bytes from 141.193.213.20 (141.193.213.20): icmp_seq=3 ttl=57 time=21.2 ms
Notre image fonctionne comme prévu, nous pouvons donc la publier sur Docker Hub :
$ docker push kikinovak/debianping
Using default tag: latest
The push refers to repository [docker.io/kikinovak/debianping]
cdb2a396502f: Pushed
61581d479298: Mounted from library/debian
latest: digest: sha256:8ea7476028d70b638e6bb17da7f33cf512b0fa556... size: 741
À vous de jouer !
Challenge n° 1
- 
Construisez un conteneur nettools:latestbasé sur la dernière image de Debian, et qui comprend les commandesping,tracerouteetcurl. Le shell Bash devra être lancé au démarrage du conteneur.
- 
Lancez le conteneur nettoolset invoquez successivement les commandesping -c 3 google.fr,curl google.frettraceroute google.fr.
- 
Quittez le conteneur et faites un brin de ménage. 
ENTRYPOINT ou CMD ?
Ne vous cassez pas trop la tête si vous ne saisissez pas encore la
différence entre ENTRYPOINT et CMD. Utilisez simplement ce qui
fonctionne dans le contexte donné.
Challenge n° 2
- 
Lancez un conteneur nommé rockyvimbasé sur Rocky Linux 8 et connectez-vous au shell Bash de ce conteneur.
- 
Installez l'éditeur de texte Vim de manière interactive. 
- 
Lancez Vim pour vérifier si tout va bien. 
- 
Quittez le conteneur. 
- 
Construisez une image personnalisée rockyvim:8basée sur Rocky Linux 8 et qui contient l'éditeur Vim.
Challenge n° 3
- 
Connectez-vous à Docker Hub. 
- 
Publiez les deux images personnalisées nettools:latestetrockyvim:8sur Docker Hub.

