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é).

vms vs containers

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 link (registre par défaut), Amazon Elastic Container Registry link, Harbor link…​

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 :

docker architecture

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’ID abcd1234, 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’ID abcd1234, 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 commande docker 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’ID abcd1234 et exécuter la commande ls, 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’ID abcd1234, 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’ID abcd1234, 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’ID abcd1234, 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 module text\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 :

  • docker rundocker container run

  • docker rmidocker image rm

  • …​

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:

  1. Créer un fichier Dockerfile dans le répertoire du projet avec les instructions pour construire l’image.

  2. Ouvrir une invite de commande ou un terminal et aller dans le répertoire du projet.

  3. Exécuter la commande “docker build” en spécifiant le chemin vers le fichier Dockerfile.
    Par exemple : docker build -t myimage:latest .

  4. La commande docker build va lire les instructions dans le fichier Dockerfile, 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 docker build avec un fichier Dockerfile, cela va créer une image à partir de ces instructions. Cependant, cela ne l’enregistrera pas sur le système de fichiers local. Il faut donc utiliser la commande docker push pour l’enregistrer sur le système de fichiers local ou sur un registry distant.

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.

Exemple :
$ 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

🞄  🞄  🞄