Présentation générale de Docker
v1.0, 02/03/2025
Généralités
Docker est une solution de virtualisation alternative par rapport aux hyperviseurs de type 1 (→ Hyper-V, VMware ESXi, Citrix XenServer…) ou de type 2 (→ VMware Workstation, Oracle VirtualBox, …).
Docker est utilisé pour déployer, de manière fiable et reproductible, des applications dans des environnements isolés qui sont indépendants de l’infrastructure matérielle ou logicielle sous-jacente. Ceci en fait une solution (quasi-)idéale pour le test, le développement ou la mise en production d’applications.
Quand on parle d’environnements isolés, ceci ne signifie pas pour autant qu’ils ne peuvent pas communiquer entre eux. Bien au contraire ! Docker favorise d’ailleurs cette communication entre environnements en mettant à disposition une multitude de moyens (volumes, réseaux de type bridge/host/macVLAN/ipVLAN) et ceci, pour encourager justement à scinder les applications en plusieurs environnements. Exemple : pour une application web, on mettra en place un environnement dédié au serveur web Apache et un autre environnement dédié au serveur de base de données MySQL. |
Docker s’appuie sur les notions d'images et de containers.
Un container contient tout ce qui est nécessaire à l’exécution d’une application dans un environnement isolé du système d’exploitation de la machine hôte (→ Host OS), un peu à la façon d’une machine virtuelle s’exécutant sur un hyperviseur de type 2. Cependant, contrairement à cette dernière, un container ne requiert pas l’installation d’un système d’exploitation invité (→ Guest OS).
Ceci en fait une solution de virtualisation beaucoup plus légère et rapide que celle basée sur les hyperviseurs de type 2. En revanche, elle isole moins les applications les unes par rapport aux autres (⇒ plus de risques de faille de sécurité).
Un container est créé à partir de ce qu’on appelle une image.
On peut assimiler une image Docker au fichier d’installation d’une application (fichiers de type .msi ou .iso) ou à celui d’une exportation de machine virtuelle (fichier .ova), c’est-à-dire à un fichier qui contient tous les éléments dont l’application a besoin pour fonctionner. Le container correspondrait, quant à lui, au système ou à l’application après leur installation.
On peut construire ses propres images pour déployer des containers d’applications populaires comme des serveurs web (Apache, Nginx…), bases de données (MySQL, Postgres…), langages de programmation (C, Python, PHP, Rust…) etc… mais beaucoup sont déjà disponibles dans des registres (→ registries) présents sur internet : dockerhub (registre par défaut), Amazon Elastic Container Registry
, Harbor
…
Docker utilise une architecture client-serveur :
-
Le client Docker offre une interface en ligne de commande pour exécuter diverses opérations sur le démon/serveur Docker (→ Docker Engine)
-
Le serveur Docker effectue le gros du travail de création, d’exécution et de distribution des conteneurs Docker.
Le client et le Docker Engine peuvent coexister sur une seule machine ou être installés sur des machines différentes (→ système réparti/distribué).
Ci-dessous, un schéma qui résume ce qui précède :
Les 2 vidéos ci-dessous reprennent/complètent ce qui vient d’être présenté :
Commandes de base
docker container run
-
Cette commande permet de lancer un conteneur à partir d’une image.
Par exemple, pour lancer un conteneur à partir de l’image NGinx, vous pouvez utiliser la commande suivante :
docker container run -it -d -p 8080:80 nginx
L’option-d
permet de lancer le container en arrière-plan et-p
pour lier le port 8080 de la machine hôte avec le port 80 du conteneur. docker image pull
-
Cette commande permet de télécharger une image depuis un dépôt en ligne (comme Docker Hub).
Par exemple, pour télécharger l’image NGinx, vous pouvez utiliser la commande suivante :
docker image pull nginx
docker image ls
-
Cette commande permet de lister les images disponibles sur la machine locale.
Par exemple, pour lister toutes les images disponibles, vous pouvez utiliser la commande suivante :
docker image ls
docker container ls
-
Cette commande permet de lister les conteneurs en cours d’exécution sur la machine locale.
Par exemple, pour lister tous les conteneurs en cours d’exécution, vous pouvez utiliser la commande suivante :
docker container ls
docker container start
-
Cette commande permet de démarrer un conteneur qui a été arrêté.
Par exemple, pour démarrer un conteneur avec l’IDabcd1234
, vous pouvez utiliser la commande suivante :
docker container start abcd1234
docker container stop
-
Cette commande permet d’arrêter un conteneur en cours d’exécution.
Par exemple, pour arrêter un conteneur avec l’IDabcd1234
, vous pouvez utiliser la commande suivante :
docker container stop abcd1234
docker container rm
-
Cette commande permet de détruire un container sépcifique à l’aide de son ID ou de son nom.
La commandedocker container prune
permet de détruire tous les conteneurs arrêtés. docker container exec
-
Cette commande permet de se connecter à un conteneur en cours d’exécution.
Par exemple, pour se connecter à un conteneur avec l’IDabcd1234
et exécuter la commandels
, vous pouvez utiliser la commande suivante :
docker container exec -it abcd1234 ls
L’option-it
permet d’interagir avec le conteneur en cours d’exécution, docker container logs
-
Cette commande permet d’afficher les logs d’un conteneur.
Par exemple, pour afficher les logs d’un conteneur avec l’IDabcd1234
, vous pouvez utiliser la commande suivante :
docker logs abcd1234
docker container rm
-
Cette commande permet de supprimer un conteneur.
Par exemple, pour supprimer un conteneur avec l’IDabcd1234
, vous pouvez utiliser la commande suivante :
docker rm abcd1234
docker image rm
-
Cette commande permet de supprimer une image.
Par exemple, pour supprimer une image avec l’IDabcd1234
, vous pouvez utiliser la commande suivante :
docker image rm abcd1234
docker inspect
-
Cette puissante commande fournit des informations détaillées — au format JSON — sur les objets Docker (images, conteneurs, réseaux, volumes…)
Par exemple, pour obtenir tous les détails d’un conteneur nommémyhttpd
, vous pouvez utiliser la commande suivante :
docker inspect myhttpd
Pour obtenir uniquement un détail particulier, on utilise l’option-f
(ou`--format
).
Par exemple, pour obtenir l’adresse IP affectée au conteneur nomméhttpd
, vous pouvez utiliser la commande :
docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' myhttpd
La syntaxe utilisée pour spécifier la valeur de l’option-f
est propre au moduletext\template
du langage Go, dans lequel est écrit Docker.
La plupart des commandes données ci-dessus possèdent des alias/raccourcis pour faciliter la saisie. Exemples :
La version longue des commandes offre l’avantage de bien montrer sur quoi elle agit (conteneur ou image) ⇒ c’est préférable lorsqu’on débute en Docker. |
Les images Docker
Pour créer une image Docker, il faut utiliser la commande docker build
.
Cette commande prend en entrée un chemin vers un fichier nommé Dockerfile
(nom par défaut), qui contient les instructions pour construire l’image.
Voici les étapes pour créer une image à partir d’un fichier Dockerfile
:
-
Créer un fichier
Dockerfile
dans le répertoire du projet avec les instructions pour construire l’image. -
Ouvrir une invite de commande ou un terminal et aller dans le répertoire du projet.
-
Exécuter la commande “docker build” en spécifiant le chemin vers le fichier Dockerfile.
Par exemple :docker build -t myimage:latest .
-
La commande
docker build
va lire les instructions dans le fichierDockerfile
, télécharger les dépendances nécessaires et créer l’image.
Pour gérer les images Docker, vous pouvez utiliser les commandes suivantes :
-
docker image ls
→ pour lister toutes les images sur votre système -
docker image rm
→ pour supprimer une image spécifique -
docker push
→ pour envoyer une image sur un dépôt distant (comme Docker Hub) -
docker pull
→ pour télécharger une image à partir d’un dépôt distant.
Lorsqu’on utilise une commande |
Les réseaux Docker
Les réseaux Docker permettent de connecter des conteneurs entre eux et à l’extérieur de la machine hôte.
Réseaux de base
Il existe différents types de réseaux de base dans Docker :
-
Le réseau de type “bridge” (par défaut) : Ce type de réseau est utilisé par défaut lorsqu’on lance un conteneur sans spécifier de réseau.
Il crée un réseau virtuel interne sur l’hôte auquel tous les conteneurs sont connectés via des adresses IP privées (172.17.0.0/16 par défaut).
Les conteneurs ainsi connectés sont isolés du réseau de l’hôte. Ceci implique de mettre en place un mappage de ports pour les rendre accessibles depuis l’extérieur.Le mode bridge (sans ‘d’ à la fin) de Docker est à différencier du mode bridged (avec un ‘d’ à la fin) dans les hyperviseurs de type 2 comme VirtualBox ou VMware Wokrstation.
Bien que les termes soient similaires, le réseau bridge de Docker crée un réseau virtuel isolé pour les conteneurs, tandis que le réseau bridged de VirtualBox ou VMware Workstation intègre les machines virtuelles directement dans le réseau physique auquel appartient l’hôte.
-
Le réseau de type “host” : Ce type de réseau utilise les interfaces réseau de la machine hôte pour connecter les conteneurs entre eux et à l’extérieur. Les conteneurs utilisant ce type de réseau ne sont pas isolés entre eux, ils partagent donc les mêmes ports et IP que la machine hôte, ce qui a un impact en terme de sécurité. Ceci fait qu’ils doivent être utilisés avec précaution et uniquement dans des cas particuliers (performances réseau optimales, accès direct à la pile réseau).
-
Le réseau de type “none” : Ce type de réseau désactive toute connexion réseau pour le conteneur.
Il est également possible de créer des réseaux personnalisés en utilisant la commande docker network create
.
Pour connecter un conteneur à un réseau existant, vous pouvez utiliser l’option --network
lors de la création d’un conteneur
avec la commande docker run
ou utiliser la commande docker network connect
pour connecter un conteneur existant à un réseau.
$ docker network create --driver=bridge --subnet=172.28.0.0/16 --ip-range=172.28.5.0/24 --gateway=172.28.5.254 mynetwork (1)
$ docker run --network=mynetwork myimage (2)
1 | Création du réseau personnalisé “mynetwork” (sous-réseau 172.28.0.0/16 avec la plage d’IPs 172.28.5.0/24 pour les conteneurs et la passerelle 172.28.5.254) |
2 | Exécution de l’image “myimage” en utilisant le réseau personnalisé “mynetwork” |
Réseaux avancés
Docker propose également 2 autres type avancés de réseau pour connecter des conteneurs à des réseaux externes :
-
réseau MACVlan
-
réseau IPVlan
Réseau IPVan
Les réseaux IPVlan utilisent les adresses IP de la machine hôte, permettant ainsi aux conteneurs de communiquer directement avec les autres conteneurs et les hôtes du réseau physique.
Pour créer un réseau IPVlan, il faut utiliser l’option --driver
pour spécifier “ipvlan” et utiliser l’option --ip-range
pour
spécifier la plage d’adresses IP à utiliser.
Par exemple, pour créer un réseau IPVlan nommé “mynetwork” utilisant l’interface réseau “eth0” de l’hôte et qui fonctionne au niveau de la couche 2 du modèle OSI (→ Liaison de données) avec une plage d’adresses IP de 192.168.0.0/24, vous pouvez utiliser la commande suivante :
docker network create --driver=ipvlan \
--subnet=192.168.0.0/24 \
--gateway=192.168.0.1 \
-o parent=eth0 \
-o ipvlan_mode=l2 \
mynetwork
Il est important de noter que pour utiliser les réseaux IPVlan, il faut disposer d’un noyau Linux qui supporte les modes IPVlan et également des privilèges nécessaires pour configurer les interfaces réseau de votre machine hôte
Réseau Macvlan
Les réseaux MACVlan permettent aux conteneurs d’avoir des adresses MAC uniques sur le réseau physique, ce qui leur permet de communiquer directement avec les autres hôtes du réseau physique.
Pour créer un réseau MACVlan, il faut utiliser l’option --driver
pour spécifier “macvlan” et utiliser l’option --subnet
pour
spécifier la plage d’adresses IP à utiliser.
Par exemple, pour créer un réseau MACVlan nommé “mynetwork” qui utilise l’interface réseau “eth0” de l’hôte avec une plage d’adresses IP de 192.168.0.0/24, vous pouvez utiliser la commande suivante :
docker network create --driver=macvlan \
--subnet=192.168.0.0/24 \
--gateway=192.168.0.1 \
-o parent=eth0 \
mynetwork
🞄 🞄 🞄