Cours/Saison C4
Saison C44 modules

Saison C4. Conteneurs et orchestration

Objectif de la saison : Comprendre et maîtriser le déploiement applicatif moderne. L'infrastructure ne se limite plus aux routeurs et aux serveurs bare-metal ; les applications s'exécutent désormais dans des environnements isolés et éphémères. L'enjeu est de savoir comment ces environnements fonctionnent, communiquent, et s'intègrent dans l'architecture réseau globale.

🐳 C401. Introduction à la conteneurisation et à Docker

Objectif : Saisir la différence fondamentale entre une machine virtuelle classique et un conteneur. Découvrir l'écosystème Docker, maîtriser les concepts d'Image et de Conteneur, et comprendre comment ces éléments s'isolent et s'exposent sur le réseau en respectant les principes de sécurité.

1. Virtualisation vs. Conteneurisation

C'est la base pour comprendre la révolution apportée par les conteneurs. L'approche pour isoler les ressources est radicalement différente.

  • La Virtualisation (Les Machines Virtuelles - VMs) :

  • Fonctionnement : Un hyperviseur (comme Proxmox, VMware ou Hyper-V) découpe les ressources matérielles physiques (CPU, RAM). Par-dessus, chaque VM embarque son propre système d'exploitation complet (Noyau/Kernel, drivers, processus d'arrière-plan).

  • Inconvénient : C'est lourd. Démarrer une VM prend du temps (boot de l'OS), et cela gaspille des ressources (chaque VM consomme de la RAM juste pour faire tourner son propre noyau).

  • Analogie : C'est l'équivalent de déployer un routeur physique dédié pour isoler chaque nouveau client.

  • La Conteneurisation (Docker) :

  • Fonctionnement : Les conteneurs partagent directement le noyau (Kernel) du système d'exploitation hôte (généralement Linux). Il n'y a pas d'OS invité. Le système isole uniquement les processus, le système de fichiers et l'espace réseau (grâce aux Namespaces de Linux).

  • Avantage : C'est ultra-léger. Un conteneur démarre en quelques millisecondes et ne pèse que quelques mégaoctets, car il ne contient que l'application et ses dépendances strictes.

  • Analogie : C'est comme utiliser des VRF (Virtual Routing and Forwarding) sur un seul gros commutateur de cœur de réseau. Vous isolez les tables de routage et les flux (conteneurs) sans avoir à multiplier le matériel ou les systèmes d'exploitation (VMs).

2. Qu'est-ce que Docker ?

Docker n'a pas inventé les conteneurs (ils existaient déjà sous Linux avec LXC), mais il a rendu la technologie accessible et standardisée.

  • Le moteur (Docker Engine) : C'est le service qui tourne sur la machine hôte. Il s'occupe de créer les environnements isolés, de monter les systèmes de fichiers, et surtout, de gérer les ponts réseaux virtuels (bridges) pour que les conteneurs puissent communiquer avec l'extérieur.
  • Le standard : Docker a créé un format standardisé. Une application "dockerisée" sur le PC d'un développeur fonctionnera exactement de la même manière sur un serveur de production. "Ça marche sur ma machine" n'est plus une excuse valable.

3. Le concept d'Image

C'est le plan de construction, la recette.

  • Nature : Une image est un modèle figé (en lecture seule). Elle contient absolument tout ce qui est nécessaire pour faire tourner l'application : le code, les librairies, les variables d'environnement et les ports réseaux par défaut à exposer.
  • Couches (Layers) : Les images sont construites en couches superposées. Si plusieurs images utilisent la même base (ex: Ubuntu), cette base n'est téléchargée et stockée qu'une seule fois sur le disque.
  • Exemple : L'image nginx:latest contient un mini-environnement Linux, les binaires du serveur web Nginx, et un fichier de configuration de base prêt à écouter sur le port 80.
  • Sécurité by Design : Une bonne pratique consiste à utiliser des images minimalistes (comme alpine ou distroless) pour réduire drastiquement la surface d'attaque et limiter les vulnérabilités (CVE) potentielles.

4. Le Conteneur

Le conteneur est l'instanciation vivante de l'Image.

  • Nature : Lorsqu'on démarre une Image, Docker crée une fine couche en "lecture/écriture" par-dessus : c'est le conteneur.
  • Éphémère : Un conteneur est conçu pour être jetable. Si on le supprime ou s'il plante, tout ce qui a été modifié à l'intérieur est perdu (sauf si l'on a explicitement monté un volume de stockage persistant depuis l'hôte).
  • Connectivité et Isolation :
  • Par défaut, un conteneur est isolé dans son propre sous-réseau interne (souvent 172.17.0.0/16) inaccessible depuis le LAN de l'entreprise.
  • Pour le rendre joignable depuis le LAN de l'entreprise, on demande à Docker d'effectuer du NAT (Redirection de port). Par exemple, on redirige le port 8080 de la machine hôte physique vers le port 80 privé du conteneur.

Exemple d'implémentation CLI :

# Déploiement d'un service web Nginx léger (Alpine) en arrière-plan (-d)
# -p 8080:80 -> Redirection du port 8080 (hôte physique) vers le port 80 (réseau interne du conteneur)
# Le pare-feu iptables de l'hôte est automatiquement mis à jour.
docker run -d --name ais_web_service -p 8080:80 nginx:alpine

5. Architecture Multi-Conteneurs (Introduction à Docker Compose)

Comme illustré dans la présentation, il est déconseillé d'insérer toute une infrastructure (Serveur Web + Code + Base de données) dans un seul conteneur. L'ingénierie moderne impose la modularité :

  • Un conteneur dédié au Front-end.
  • Un conteneur dédié au Back-end.
  • Un conteneur dédié à la Base de données. Chaque composant peut ainsi être mis à jour, sécurisé ou redimensionné de manière indépendante. L'orchestration de cette architecture fera l'objet du module suivant (Docker Compose).

🛠️ Aide-mémoire : Commandes Docker Essentielles

CatégorieCommandeCe qu'elle fait
Imagesdocker pull <image>Télécharge une image depuis le Docker Hub.
docker imagesListe toutes les images stockées sur votre machine.
docker rmi <id_image>Supprime une image locale.
Lancementdocker run -d --name <nom> -p <port_hôte>:<port_conteneur> <image>La commande reine : Crée et lance un conteneur en arrière-plan (-d), le nomme, et mappe les ports réseaux.
Gestiondocker psListe les conteneurs actuellement en cours d'exécution.
docker ps -aListe tous les conteneurs (même arrêtés ou plantés).
docker stop <nom> / docker start <nom>Arrête proprement / Redémarre un conteneur.
docker rm <nom>Supprime définitivement un conteneur (doit être arrêté).
Analysedocker logs -f <nom>Affiche les journaux du conteneur en temps réel (comme tail -f).
docker exec -it <nom> /bin/bashOuvre un terminal directement à l'intérieur du conteneur.

Challenge C401 : Déploiement Docker et découverte

📚 Ressources :

Retour en haut


🏗️ C402. Construction d'Images et Orchestration avec Docker Compose

Objectif : Maîtriser la création d'images personnalisées via des Dockerfile, assurer la persistance des données, et orchestrer des architectures multi-conteneurs sécurisées grâce à Docker Compose.

1. La Compilation d'Images (Dockerfile et docker build)

L'utilisation d'images génériques (comme ubuntu ou nginx) n'est souvent pas suffisante en entreprise. Il est nécessaire de construire des images sur mesure contenant le code applicatif spécifique. Le Dockerfile est la recette d'infrastructure (IaC) permettant cette automatisation.

  • Les Instructions Essentielles :

    • FROM : Définit l'image de base (le point de départ, ex: php:8.2-apache).
    • WORKDIR : Définit le répertoire de travail interne au conteneur (équivalent à cd).
    • COPY : Transfère les fichiers de l'hôte physique vers le système de fichiers de l'image.
    • RUN : Exécute des commandes (comme apt install ou npm install) lors de la phase de construction (Build). Crée une nouvelle couche (Layer).
    • EXPOSE : Déclare le port d'écoute (documentaire, n'ouvre pas le pare-feu de l'hôte).
    • CMD : Définit le processus principal à exécuter au démarrage du conteneur.
  • La Commande de Build :

# Compilation de l'image en tagguant le résultat et en utilisant le dossier courant (.) comme contexte
docker build -t mon-application:v1.0 .

  • Sécurité by Design (Sysadmin) : Il faut toujours spécifier un tag précis (ex: node:20-alpine) au lieu de latest. L'utilisation de latest expose l'infrastructure à des mises à jour cassantes et imprévisibles lors des futures compilations.

2. La Persistance des Données (Volumes)

Par conception, le système de fichiers d'un conteneur est éphémère. En cas de suppression (docker rm), les données internes disparaissent. Pour protéger l'information (comme une base de données), il faut extraire le stockage.

Il existe deux mécanismes principaux :

  • Les Volumes Nommés (Named Volumes) - Standard de Production :

    • Gérés intégralement par le moteur Docker (stockés nativement dans /var/lib/docker/volumes/ sous Linux).
    • Avantage : Hautes performances, indépendance vis-à-vis du système de fichiers de l'hôte, idéal pour les bases de données (MariaDB, PostgreSQL).
  • Les Points de Montage (Bind-Mounts) - Standard de Développement :

    • Liaison directe d'un dossier de la machine hôte (ex: ./src) vers un dossier du conteneur (ex: /var/www/html).
    • Avantage : Permet de modifier le code source sur l'hôte et de voir les changements en temps réel dans le conteneur.
    • Risque Sécurité/Système : Peut générer de graves conflits de permissions UNIX (droits root vs www-data) et permet théoriquement au conteneur d'interagir avec les fichiers de l'hôte. À proscrire en production pour des applications sensibles.

3. Orchestration Multi-Conteneurs (Docker Compose)

Une architecture saine ne place jamais un serveur web et une base de données dans le même conteneur. La séparation des rôles est impérative. Docker Compose permet de déployer toute une pile applicative (Stack) via un seul fichier de configuration YAML (docker-compose.yml).

  • Concepts Réseaux Avancés (Couche 3 & DNS) :

    • Lors de l'exécution, Compose crée un réseau virtuel isolé (Bridge) propre au projet.
    • Résolution DNS Interne : Les conteneurs n'ont pas besoin de connaître leurs adresses IP respectives. Le serveur applicatif contacte la base de données simplement en utilisant le nom du service (ex: db).
  • Segmentation (Firewalling interne) :

    • Il est possible de créer plusieurs réseaux virtuels (ex: frontend et backend).
    • Le conteneur Web est rattaché au frontend et au backend. Le conteneur Base de Données n'est rattaché qu'au backend. Ainsi, le Web peut parler à la base, mais une application externe ne peut pas atteindre la base de données, même virtuellement.
  • Gestion des Secrets (Fichier .env) :

    • Les mots de passe ne doivent jamais être écrits en clair dans le fichier YAML.
    • L'utilisation d'un fichier caché .env (non versionné via .gitignore) permet d'injecter dynamiquement des variables (ex: ${MYSQL_ROOT_PASSWORD}).
  • Commandes Clés :

docker compose up -d    # Démarre toute l'infrastructure en arrière-plan
docker compose down -v  # Détruit l'infrastructure ET supprime les volumes associés
docker compose logs -f  # Supervise les journaux centralisés de tous les services

4. Le Registre Central : Docker Hub

Le Docker Hub agit comme un référentiel (dépôt) public ou privé pour stocker et partager les images compilées.

  • Mécanique : Une fois l'image construite localement, elle peut être envoyée sur le registre (docker push). N'importe quel autre serveur (ou collègue) pourra alors la télécharger (docker pull) et l'exécuter, garantissant une parité absolue entre l'environnement de développement et de production.
  • Sécurité (Supply Chain) : Il est vital de ne télécharger que des images "Officielles" (Official Images) ou certifiées. Une image tierce peut contenir des malwares, des mineurs de cryptomonnaies ou des portes dérobées (Backdoors).

Challenge C402 : Déployer GLPI avec Docker Compose

📚 Ressources :

Retour en haut


🚢 C403. Orchestration avec Docker Swarm et Portainer

Objectif : Dépasser les limites d'un serveur unique. Comprendre comment transformer un parc de machines en un cluster unifié garantissant la Haute Disponibilité (HA), la tolérance aux pannes, et découvrir la gestion graphique via Portainer.

1. Pourquoi l'Orchestration ? (Les limites de Compose)

Docker Compose est parfait pour un seul serveur, mais il ne répond pas aux problématiques de production à grande échelle. Que se passe-t-il si le serveur physique tombe? Comment gérer une explosion du trafic web? Comment mettre à jour une application sans aucune coupure de service? C'est ici qu'intervient Docker Swarm, l'outil de clustering et d'orchestration intégré nativement à Docker. Il permet de piloter un ensemble de machines (nœuds) comme s'il s'agissait d'un seul et unique super-serveur Docker.

2. Architecture d'un Cluster Swarm (Topologie) 🐝

Un cluster est composé de deux types d'acteurs:

  • Les Managers (Les chefs d'orchestre) : Ils gèrent le cluster et planifient la répartition des services. Parmi eux, un "Leader" est élu automatiquement via un algorithme de consensus (Raft). Si le leader tombe, un autre est immédiatement élu. (Note : Par défaut, un manager agit aussi comme un worker ).

  • Les Workers (Les musiciens) : Leur seul rôle est d'exécuter les conteneurs que les managers leur confient.

⚠️ La Règle d'Or du Quorum (Haute Disponibilité) : Pour que le cluster fonctionne, il faut un nombre minimum de managers actifs, défini par la formule : (nombre de managers / 2) + 1. Il faut toujours concevoir une architecture avec un nombre impair de managers (1, 3, 5, etc.). Un nombre pair expose le cluster au risque de "Split-Brain" (cerveau divisé), ce qui bloque totalement l'infrastructure.

3. De l'Image au Service (Le changement de paradigme)

Dans Swarm, on ne déploie plus de simples "conteneurs".

  • Le Conteneur : C'est une instance unique tournant sur une machine précise.

  • Le Service : C'est une abstraction (une définition) qui indique à Swarm le nombre de réplicas (conteneurs) désirés et comment ils doivent être répartis sur le cluster.

Fonctionnalités avancées des Services :

  • Mode Global : Force l'exécution d'un réplica sur chaque nœud du cluster (idéal pour des agents de supervision comme Prometheus).

  • Contraintes de Placement : Permet d'obliger un service à tourner sur un nœud spécifique en fonction de son rôle (node.role==worker) ou de labels (node.labels.env==production). (C'est exactement ce que nous avons utilisé pour lier MariaDB à son volume local).

  • Rolling Updates (Mise à jour continue) : Permet de mettre à jour une image (ex: Nginx 1.18 vers 1.25) sans interruption. Swarm met à jour les conteneurs par lots (batchs) avec un délai entre chaque (--update-delay). En cas d'erreur, un "Rollback" automatique ramène l'infrastructure à la version précédente.

4. Administration et Maintenance des Nœuds

Un administrateur système doit pouvoir intervenir sur le matériel physique sans casser les applications. Swarm propose des états de disponibilité :

  • Drain : La commande ultime pour la maintenance. Elle arrête tous les conteneurs présents sur le nœud et les fait immédiatement migrer (redémarrer) sur d'autres serveurs disponibles.

  • Pause : Le nœud n'accepte plus de nouvelles tâches, mais les conteneurs qui y tournent déjà ne sont pas coupés.

5. Portainer : La Tour de Contrôle 🏗️

(Notion abordée en challenge pratique) Portainer est une interface graphique web (GUI) qui se branche sur le moteur Docker ou le cluster Swarm.

  • Visualisation : Il rend tangibles des concepts abstraits : on voit visuellement les nœuds (Endpoints), les services, et la répartition des tâches (Tasks).
  • Stacks (Piles) : C'est l'équivalent de Docker Compose dans Portainer. En collant un fichier YAML dans l'éditeur "Stacks", Portainer le traduit en commandes docker service create compréhensibles par Swarm.
  • Gestion des Secrets : Portainer permet d'injecter des variables d'environnement proprement lors du déploiement, évitant de laisser des fichiers .env en clair sur les serveurs.

🛠️ Aide-mémoire CLI : Commandes Swarm Essentielles

OpérationCommandeDescription
Clusterdocker swarm init --advertise-addr <IP>Créer un nouveau cluster (Le serveur devient Leader).
docker swarm join-token manager/workerAfficher le mot de passe (Token) pour ajouter un serveur.
Nœudsdocker node lsLister les serveurs du cluster et leur état.
docker node update --availability drain <ID>Vider un nœud de ses conteneurs pour maintenance.
docker node promote/demote <ID>Transformer un Worker en Manager, ou l'inverse.
Servicesdocker service lsLister les services déployés.
docker service ps <nom>Voir sur quels serveurs physiques tournent les réplicas.
Sauvegardetar -czvf backup.tar.gz /var/lib/docker/swarm/Sauvegarder l'état du cluster (⚠️ Ne sauvegarde pas les volumes de données des conteneurs !).

swarm

Challenge C403 : Déployer GLPI sur un cluster avec Portainer

📚 Ressources :

Retour en haut


📦 C404. Conteneurs Systèmes : LXC et LXD (Incus)

🎯 Objectif : Comprendre la conteneurisation de systèmes d'exploitation complets (OS-level virtualization). Maîtriser les différences fondamentales avec Docker, et piloter des infrastructures légères et sécurisées via LXD ou son fork communautaire, Incus.

1. L'Architecture : VM vs LXC vs Docker (🧠 Théorie)

Il est crucial de comprendre à quel niveau d'isolation opère chaque technologie pour faire les bons choix d'architecture.

  • Machine Virtuelle (VM) : C'est l'équivalent d'une maison individuelle. Elle embarque un OS complet, possède un noyau (Kernel) dédié et virtualise le matériel (isolation forte, poids en Go).

  • LXC (Linux Containers) : C'est un appartement complet. LXC conteneurise des systèmes complets, lance un processus d'initialisation (systemd), permet d'avoir des utilisateurs et des services résidents, mais partage le noyau avec l'hôte (poids ultra-léger, ~100 Mo).

  • Docker : C'est un studio meublé pour une seule application. Il n'y a pas d'OS complet ni de systemd ; Docker ne lance qu'un seul processus isolé (poids minimaliste, ~10 Mo).

Docker et LXC ne sont pas concurrents, ils partagent exactement les mêmes briques technologiques intégrées au noyau Linux:

  • Namespaces : Assurent l'isolation logique (chaque conteneur a sa propre vue du réseau, des processus et des utilisateurs).

  • Cgroups (Control Groups) : Permettent de limiter et de monitorer la consommation des ressources matérielles (CPU, RAM, I/O).

  • Chroot : Isole le système de fichiers pour que le conteneur ait sa propre racine /.

2. LXC (Le standard sous Proxmox)

  • Le Système Complet (OS-Level) : Contrairement à Docker qui isole une simple application, LXC conteneurise un système Linux entier. Il lance un véritable processus d'initialisation (comme systemd), ce qui permet d'y gérer des utilisateurs et d'exécuter des services d'arrière-plan (cron, sshd).

  • L'Analogie de l'Habitat : Si Docker est un studio meublé (juste le nécessaire pour l'application) et la VM une maison individuelle (avec son propre terrain/matériel), LXC est un appartement complet (un vrai système confortable mais dans un immeuble partagé).

  • Légèreté et Performance : Puisque LXC partage le noyau (Kernel) de la machine hôte et ne virtualise pas le matériel , il ne pèse qu'une centaine de mégaoctets et démarre en quelques secondes. C'est une économie de ressources massive comparée aux Gigaoctets d'une Machine Virtuelle.

  • L'Intégration Proxmox VE : Proxmox utilise nativement LXC. Depuis son interface web, un administrateur peut déployer instantanément des serveurs à partir de templates pré-configurés (Debian, Ubuntu, Alpine). L'hyperviseur permet ainsi de faire cohabiter sur le même serveur physique des VMs lourdes et des conteneurs LXC ultra-rapides.

💡 Cas d'usage (Architecture) : LXC est l'outil idéal pour déployer une infrastructure Linux légère, segmenter des services systèmes, ou créer un laboratoire de test réseau et cybersécurité sans saturer la RAM du serveur physique.

3. LXD & Incus : L'Orchestration Moderne (🏗️ Infrastructure)

Si LXC est le moteur, LXD est la voiture complète (avec tableau de bord et options de confort). Il s'agit d'un gestionnaire de conteneurs (et de VMs) qui ajoute une API REST et un outil en ligne de commande (CLI) moderne par-dessus LXC.

  • Le Fork "Incus" : En 2023, suite à des décisions de Canonical, la communauté a créé un fork de LXD nommé Incus. Les commandes et la philosophie restent quasi identiques.

  • Profils (Profiles) : LXD permet de créer des configurations réutilisables (ex: limiter la RAM à 1Go) et de les appliquer à plusieurs conteneurs simultanément.

  • Stockage (Storage Pools) : LXD gère des pools de stockage avancés. L'utilisation du backend ZFS est fortement recommandée en production pour sa gestion ultra-rapide des Snapshots et de la compression.

  • Machines Virtuelles : Fonctionnalité surprenante, LXD peut également instancier de véritables VMs (via QEMU) en ajoutant simplement le flag --vm à la commande de lancement.

4. Sécurité by Design (🛡️ Hardening)

LXD brille particulièrement par sa posture de sécurité par défaut :

  • Conteneurs Non-Privilégiés : Actif par défaut, ce mécanisme effectue un "mapping" des identifiants (UID/GID). L'utilisateur root à l'intérieur du conteneur correspond à un utilisateur non-privilégié (ex: UID 65536) sur la machine hôte. Cela réduit drastiquement la surface d'attaque en cas d'évasion.

  • Blindage natif : LXD applique automatiquement des profils AppArmor (restriction des accès fichiers) et Seccomp (filtrage des appels systèmes dangereux) sans aucune configuration préalable requise.

🛠️ Aide-mémoire CLI : Commandes LXD / Incus Essentielles

(Note : Remplacer lxc par incus si utilisation du fork communautaire )

ActionCommandeDescription
Créationlxc launch ubuntu:24.04 <nom>Télécharge l'image, crée et démarre un conteneur Ubuntu.
lxc launch images:debian/12 <nom>Idem pour une image Debian issue du dépôt communautaire.
Gestionlxc listListe tous les conteneurs et leurs adresses IP.
lxc exec <nom> bashOuvre un terminal bash directement dans le conteneur.
Fichierslxc file push /local/file <nom>/root/Copie un fichier de l'hôte vers le conteneur (remplace docker cp).
Ressourceslxc config set <nom> limits.memory 512MBLimite la mémoire RAM allouée au conteneur à chaud.
Snapshotslxc snapshot <nom> <nom_snap>Prend une empreinte instantanée de l'état du conteneur.
apt install lxc lxc-templates 
lxc-checkconfig 
lxc-create -n mon-conteneur -t debian -- -r bookworm 
lxc-start mon-conteneur
lxc-attach mon-conteneur
lxc-stop mon-conteneur 
lxc-destroy mon-conteneur

📚 Ressources :

Retour en haut