DCNA
Docker Certified Network Associate
DCNAOverlay Networks & Docker Swarm

Overlay Networks & Docker Swarm

Les bridges et les driver locaux ne fonctionnent qu'à l'intérieur d'un seul host. Dès que tes containers sont sur plusieurs machines physiques, tu as besoin d'un overlay network — un réseau virtuel qui s'étend sur plusieurs hosts.

Le problème que l'overlay résout

Host A                    Host B
Container 1               Container 2
IP: 10.0.0.2              IP: 10.0.0.3

Comment est-ce que Container 1 peut parler à Container 2 
alors qu'ils sont sur des machines physiques différentes ?

Réponse : en encapsulant le paquet container dans un paquet UDP, et en l'envoyant via le réseau physique entre les deux hosts.

VXLAN : le mécanisme d'encapsulation

VXLAN (Virtual Extensible LAN) enveloppe les trames Ethernet (Layer 2) dans des paquets UDP (Layer 4) sur le port 4789.

Paquet envoyé par Container 1 → Container 2

AVANT encapsulation (dans le namespace container) :
┌──────────────────────────────────────────────────┐
│ Ethernet | IP src: 10.0.0.2 dst: 10.0.0.3 | TCP │
└──────────────────────────────────────────────────┘

APRÈS encapsulation VXLAN (sur le réseau physique entre hosts) :
┌────────────────────────────────────────────────────────────────────┐
│ ETH hôte | IP src: 192.168.1.10 dst: 192.168.1.11 | UDP:4789 | VXLAN header | [trame container originale] │
└────────────────────────────────────────────────────────────────────┘

VNI (VXLAN Network Identifier) : un identifiant 24 bits qui isole les différents overlay networks. Chaque docker network create --driver overlay génère un VNI unique.

Host A                                    Host B
┌──────────────────────┐                ┌──────────────────────┐
│ Container 1          │                │ Container 2          │
│ 10.0.0.2             │                │ 10.0.0.3             │
└──────────┬───────────┘                └──────────┬───────────┘
           │ veth                                  │ veth
┌──────────▼───────────┐                ┌──────────▼───────────┐
│ br0 (overlay bridge) │                │ br0 (overlay bridge) │
│ 10.0.0.0/24          │                │ 10.0.0.0/24          │
└──────────┬───────────┘                └──────────┬───────────┘
           │ VXLAN tunnel                          │
           │ (UDP 4789 entre les IPs des hosts)    │
Host A eth0: 192.168.1.10 ──────────── Host B eth0: 192.168.1.11

Docker Swarm : le gestionnaire de cluster

Swarm est le orchestrateur intégré de Docker. Il gère plusieurs hosts comme un seul cluster et est nécessaire pour créer des overlay networks multi-host.

Architecture Swarm

  • Manager nodes : maintiennent l'état du cluster (algorithme Raft), planifient les services
  • Worker nodes : exécutent les containers (tasks)
Cluster Swarm :
┌─────────────────────────────────────────┐
│  Manager 1 (leader)                     │
│  Manager 2 (follower)   ← Raft quorum   │
│  Manager 3 (follower)                   │
├─────────────────────────────────────────┤
│  Worker 1                               │
│  Worker 2      ← exécutent les tasks    │
│  Worker 3                               │
└─────────────────────────────────────────┘

Initialiser un Swarm

# Sur le premier manager
docker swarm init --advertise-addr 192.168.1.10
# → Swarm initialized: current node is now a manager.
# → To add a worker to this swarm, run the following command:
# →   docker swarm join --token SWMTKN-1-... 192.168.1.10:2377

# Récupérer le token worker (si perdu)
docker swarm join-token worker

# Récupérer le token manager
docker swarm join-token manager

# Ajouter un worker
docker swarm join --token SWMTKN-1-... 192.168.1.10:2377

# Voir tous les nodes
docker node ls
# ID         HOSTNAME   STATUS  AVAILABILITY  MANAGER STATUS
# abc123 *   host-a     Ready   Active        Leader
# def456     host-b     Ready   Active

Port 2377 : communication entre managers (TCP)
Port 7946 : gossip protocol entre nodes (TCP/UDP)
Port 4789 : VXLAN data plane (UDP)

Overlay Networks dans Swarm

# Créer un overlay network (requiert un swarm actif)
docker network create \
  --driver overlay \
  --subnet 10.0.9.0/24 \
  my-overlay

# Un réseau overlay "attachable" permet d'y connecter des containers standalone
docker network create \
  --driver overlay \
  --attachable \
  my-overlay

Docker crée automatiquement deux réseaux dans Swarm :

  • ingress : trafic externe vers les services publiés (routing mesh)
  • docker_gwbridge : connexion entre les containers et le réseau physique de l'hôte

Services Swarm

Un service = version Swarm de docker run (mais distribué sur plusieurs nodes).

# Service répliqué (N copies réparties sur le cluster)
docker service create \
  --name web \
  --replicas 3 \
  --network my-overlay \
  --publish published=80,target=80 \
  nginx

# Service global (une copie sur CHAQUE node)
docker service create \
  --name log-agent \
  --mode global \
  fluentd

# Voir l'état du service et où les tasks tournent
docker service ls
docker service ps web
# ID         NAME    IMAGE   NODE    DESIRED STATE  CURRENT STATE
# abc123     web.1   nginx   host-a  Running        Running 2m
# def456     web.2   nginx   host-b  Running        Running 2m
# ghi789     web.3   nginx   host-a  Running        Running 2m

# Scaler
docker service scale web=5

# Mise à jour progressive (rolling update)
docker service update \
  --image nginx:1.27 \
  --update-parallelism 1 \
  --update-delay 10s \
  web

Service Discovery dans Swarm

Swarm attribue un Virtual IP (VIP) stable à chaque service. Les containers résolvent le nom du service → VIP, et IPVS distribue les connexions aux replicas.

Container → DNS "web" → 10.0.9.5 (VIP du service "web")
                             │
                          IPVS (kernel)
                             ├── Replica 1 (10.0.9.6, sur host-a)
                             ├── Replica 2 (10.0.9.7, sur host-b)
                             └── Replica 3 (10.0.9.8, sur host-a)
# Mode VIP (défaut) — VIP stable + IPVS
docker service create --name api --endpoint-mode vip ...

# Mode DNS round-robin — chaque lookup DNS retourne une IP de replica différente
docker service create --name api --endpoint-mode dnsrr ...

Le mode VIP est préféré en production car le VIP reste stable même quand des replicas redémarrent.

Ingress Routing Mesh

Le routing mesh permet à n'importe quel node du swarm de recevoir le trafic pour un port publié, même si aucun replica ne tourne dessus.

Client externe → http://host-b:80
                      │
                host-b n'a pas de replica web
                      │
                 iptables redirect → ingress network
                      │
                 IPVS → replica web sur host-a
# Publier un port via le routing mesh
docker service create \
  --name web \
  --publish mode=ingress,published=80,target=80 \
  nginx

# Port publié en mode "host" (uniquement sur les nodes avec un replica)
docker service create \
  --name web \
  --publish mode=host,published=80,target=80 \
  nginx

Chiffrement Overlay

# Créer un overlay chiffré (AES-GCM 256-bit sur le data plane)
docker network create \
  --driver overlay \
  --opt encrypted=true \
  secure-overlay

Sans chiffrement, le trafic VXLAN circule en clair sur le réseau physique. Le chiffrement ajoute une légère charge CPU (AES hardware acceleration disponible sur les CPUs modernes).

Le management plane (Raft entre managers) est toujours chiffré avec TLS — seul le data plane nécessite --opt encrypted.

Résumé

  • VXLAN encapsule les trames container dans UDP:4789 pour traverser le réseau physique
  • Chaque overlay network a un VNI unique qui l'isole
  • Swarm requiert les ports 2377 (TCP), 7946 (TCP/UDP), 4789 (UDP)
  • Les services remplacent docker run dans un contexte Swarm
  • Le VIP + IPVS distribue les connexions aux replicas d'un service
  • Le routing mesh fait que n'importe quel node peut recevoir le trafic externe
  • --opt encrypted chiffre le data plane en AES-GCM 256-bit