Comment un désaccord MTU entre Docker et OpenStack casse le CI/CD : Diagnostic et correction
Un échec de build un vendredi soir n’est souvent pas un simple bug aléatoire — c’est généralement un désaccord de MTU entre les conteneurs Docker et le réseau overlay d’OpenStack. Le problème ne se manifeste qu’avec des transferts de données volumineux, comme le clonage d’un dépôt, tandis que les petites requêtes passent sans souci. Cela donne une fausse impression d’un réseau fonctionnel jusqu’à ce que les vraies charges de travail arrivent.
Pourquoi les petites requêtes marchent mais pas les grosses
Le signe distinctif de ce problème, c’est sa sélectivité. Les commandes comme curl -I ou ping qui envoient de minuscules paquets réussissent à tous les coups. Les ennuis commencent avec les opérations nécessitant de gros blocs de données : git clone, docker pull, téléchargements d’artefacts. Le coupable ? L’Unité de Transmission Maximale (MTU) — la taille maximale d’un paquet IP qui peut être transmis sans fragmentation.
Les réseaux Ethernet standards utilisent une MTU de 1500 octets. Mais dans les environnements cloud comme OpenStack, les technologies overlay comme VXLAN ou GRE construisent des réseaux isolés en enveloppant chaque paquet dans environ 50 octets de surcharge. Donc même si le réseau physique gère 1500, les paquets de votre VM n’ont plus que 1450 octets disponibles.
Docker utilise par défaut un réseau bridge avec MTU 1500, ignorant les particularités de l’infra. Les conteneurs construisent leurs paquets selon cette spec. Quand ils arrivent sur l’interface MTU 1450 de l’hôte, ils ne peuvent pas être transmis à cause du drapeau DF (Don't Fragment). La découverte de MTU de chemin devrait normalement intervenir, mais les pare-feu, groupes de sécurité ou routeurs capricieux bloquent souvent les messages ICMP « Fragmentation Needed ».
Diagnostic en 30 secondes
Repérez un désaccord MTU avec ces trois commandes :
- Vérifiez la MTU de l’interface réseau de l’hôte :
```
ip link show ens3 | grep mtu
```
Dans OpenStack, attendez-vous à mtu 1450.
- Vérifiez la MTU à l’intérieur d’un conteneur :
```
docker run --rm alpine ip link show eth0 | grep mtu
```
Docker utilise par défaut mtu 1500. Si c’est plus élevé que l’hôte, vous avez trouvé le problème.
- Lancez un test ping bloquant la fragmentation :
```
docker run --rm alpine ping -s 1422 -M do -c 3 gitlab.example.com
docker run --rm alpine ping -s 1423 -M do -c 3 gitlab.example.com
```
Le premier (1422 = 1450 − 28) devrait réussir ; le second échouer avec Message too long.
Correction étape par étape
Définir la MTU dans Docker
La solution principale : configurez Docker pour utiliser la bonne MTU. Modifiez /etc/docker/daemon.json :
{
"mtu": 1450
}
Redémarrez le démon Docker :
sudo systemctl restart docker
Gérer les réseaux existants
Note : les changements dans daemon.json n’affectent que les nouveaux réseaux. Les existants — surtout ceux de Docker Compose — gardent l’ancienne MTU. Deux options :
- Recréez tout :
```
docker compose down && docker compose up -d
```
- Définissez explicitement la MTU dans Docker Compose :
```yaml
networks:
app-net:
driver: bridge
driver_opts:
com.docker.network.driver.mtu: 1450
```
Étapes finales
Redémarrez GitLab Runner et testez :
sudo gitlab-runner restart
docker run --rm alpine ping -s 1422 -M do -c 3 gitlab.example.com
Si le test passe, c’est bon.
Pièges courants et bonnes pratiques
- N’abaissez pas la MTU « au cas où ». Descendre à 1300 réduit le débit de 10-15 % à cause des paquets supplémentaires. Utilisez la valeur diagnostiquée exacte.
- Automatisez. Intégrez la MTU dans la config de votre infra (Terraform, Ansible, cloud-init) — pas de bidouilles manuelles.
- Surveillez les réseaux personnalisés.
daemon.jsonignore les existants. Vérifiez avecdocker network inspect. - Oubliez l’espoir de la découverte MTU de chemin. Les environnements cloud la cassent avec les blocages ICMP.
Points clés à retenir
- Le désaccord MTU ne frappe qu’avec les transferts de gros volumes, ce qui le rend furtif.
- Les overlays OpenStack consomment 50 octets de MTU avec leurs en-têtes.
- Le 1500 par défaut de Docker entre en conflit dans le cloud.
- Correction : Alignez la MTU Docker sur celle de l’interface hôte.
- Automatisez la config dans votre pipeline de déploiement.
— Editorial Team
Aucun commentaire pour le moment.