Voici le neuvième volet de la formation Docker. Dans mon précédent article, nous avons abordé la nomenclature détaillée des images et les registres dans lesquels elles sont stockées. Aujourd’hui, nous allons faire un petit atelier pratique un peu plus amusant en construisant 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. UtilisezCMD
pour passer des options à cet exécutable.
Prenons un Dockerfile
pour illustrer la différence subtile entre les instructions ENTRYPOINT
et CMD
:
$ cat Dockerfile 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
ENTRYPOINT
fait en sorte que le conteneur exécute la commande/usr/bin/ping
au démarrage. - Notez que
/usr/bin/ping
est entouré de guillemets et de crochets. Le format utilisé ici est un tableau JSON. - L’instruction
CMD
utilise également un tableau JSON. Ici, nous fournissonswww.docker.com
comme 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 :
$ docker build -t kikinovak/dockerping:latest .
...
Sending build context to Docker daemon 2.048kB
Step 1/4 : FROM rockylinux:8
---> 4e97feadb276
Step 2/4 : LABEL maintainer="Microlinux <info@microlinux.fr>"
---> Running in fa96b6bf89ec
Removing intermediate container fa96b6bf89ec
---> 8c7c9a5890ed
Step 3/4 : ENTRYPOINT ["/usr/bin/ping"]
---> Running in 03a597b595e0
Removing intermediate container 03a597b595e0
---> c08c948e7bd8
Step 4/4 : CMD ["www.docker.com"]
---> Running in 7051dabcfa6e
Removing intermediate container 7051dabcfa6e
---> b06be6abe1c9
Successfully built b06be6abe1c9
Successfully tagged kikinovak/dockerping:latest
- L’option
-t
permet 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
latest
est présumée. Nous explicitions cette information ici par souci de précision. - La commande
docker build
attend un chemin où elle pourra trouver unDockerfile
utilisé pour construire l’image. Le point.
indique àdocker build
qu’il faut utiliser leDockerfile
dans 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:8
qui correspond à l’instructionFROM
de notreDockerfile
. - Ensuite, Docker a exécuté les commandes et les instructions de notre
Dockerfile
pour 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 :
$ docker login
Authenticating with existing credentials...
...
Login Succeeded
À 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 :
ENTRYPOINT ["usr/bin/ping"] CMD ["www.docker.com"]
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 :
$ cat Dockerfile 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
apt
etapt-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-get
en une seule instructionRUN
de 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 clean
sert à 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
Exercice 1
- Construisez un conteneur
nettools:latest
basé sur la dernière image de Debian, et qui comprend les commandesping
,traceroute
etcurl
. Le shell Bash devra être lancé au démarrage du conteneur. - Lancez le conteneur
nettools
et invoquez successivement les commandesping -c 3 google.fr
,curl google.fr
ettraceroute google.fr
. - Quittez le conteneur et faites un brin de ménage.
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é.
Exercice 2
- Lancez un conteneur nommé
rockyvim
basé 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:8
basée sur Rocky Linux 8 et qui contient l’éditeur Vim.
Exercice 3
- Connectez-vous à Docker Hub.
- Publiez les deux images personnalisées
nettools:latest
etrockyvim:8
sur Docker Hub.
Lire la suite : Gérer les volumes
La rédaction de cette documentation demande du temps et des quantités significatives de café espresso. Vous appréciez ce blog ? Offrez un café au rédacteur en cliquant sur la tasse.
0 commentaire