Docker Macvlan : isoler ses conteneurs avec une IP dédiée

Lorsque l’on utilise Docker en production, on profite rapidement de ses avantages : déploiement rapide, isolation des applications et surtout mutualisation des ressources. Une seule machine peut désormais héberger plusieurs services, réduisant considérablement le nombre de machines virtuelles à maintenir.

Cependant, cette mutualisation peut rapidement poser des problématiques réseau, notamment en matière de sécurité et de gestion des accès. Par défaut, les conteneurs Docker partagent le réseau de l’hôte (ou passent par du NAT), ce qui implique que les règles de filtrage s’appliquent souvent à toute la machine, et non à un service précis.

C’est ici qu’intervient Macvlan.

Macvlan est un driver réseau Docker qui permet d’attribuer une adresse IP propre à chaque conteneur, directement sur votre réseau local. Concrètement, un conteneur devient un hôte à part entière sur le réseau, avec sa propre identité réseau. Cela permet de segmenter finement les accès et d’appliquer des règles de sécurité beaucoup plus précises.

Dans mon cas, l’utilisation de Macvlan m’a permis de répondre à plusieurs problématiques concrètes rencontrées en production.

Depuis maintenant quelques temps, je déploie la majorité de mes applications avec Docker afin de réduire le nombre de machines virtuelles. Une seule VM peut ainsi supporter plusieurs services, ce qui permet de rationaliser l’infrastructure. Mais dans ce type d’architecture mutualisée, certaines contraintes réseau apparaissent rapidement.

Voici deux cas concrets où Macvlan m’a permis d’apporter une solution efficace :

  • Guacamole (RDP / SSH pour prestataires)
    Dans une configuration classique, il est nécessaire d’autoriser l’adresse IP du serveur Docker à accéder aux serveurs en RDP ou SSH, parfois même à travers plusieurs VLANs. Le problème est que cette autorisation s’applique à toute la machine hôte, ce qui élargit inutilement la surface d’exposition.
    Avec Macvlan, il est possible d’attribuer une IP dédiée uniquement au service guacd, et de limiter les droits réseau à ce seul conteneur.
  • Proxy Zabbix dans plusieurs VLANs
    Avant Macvlan, j’utilisais un conteneur ou une VM (type LXC) par VLAN pour déployer un proxy Zabbix, ce qui multipliait les instances et complexifiait la gestion.
    Grâce à Macvlan, j’ai pu regrouper tous mes proxies sur un seul serveur Docker, tout en attribuant une IP distincte à chaque conteneur dans le VLAN correspondant (serveurs, DMZ, équipements réseau, etc.).

Dans ce tutoriel, nous allons voir comment mettre en place Macvlan avec Docker, comprendre son fonctionnement et l’adapter à vos besoins en environnement réel.

Avec Macvlan, chaque conteneur est directement connecté au réseau physique et obtient sa propre adresse IP et MAC, ce qui lui permet de se comporter comme un hôte autonome.

Prérequis (Hyperviseur & Hôte)

Avant de configurer un réseau Macvlan avec Docker, il est important de vérifier certains prérequis, aussi bien côté hyperviseur que système hôte.

Côté hôte Docker

  • Un système Linux (Macvlan n’est pas supporté nativement sur Windows/Mac en mode classique)
  • Docker installé (version récente recommandée)
  • Accès root ou sudo
  • Une interface réseau physique (ex : eth0, ens18, etc.)
  • Le module kernel macvlan chargé (généralement déjà actif)
lsmod | grep macvlan

Côté hyperviseur

Pour que Macvlan fonctionne correctement, l’hyperviseur doit autoriser plusieurs adresses MAC sur une même interface virtuelle.

À vérifier selon l’hyperviseur :

  • Mode promiscuité activé
  • Forged Transmits / MAC spoofing autorisé
  • Pas de filtrage strict des MAC

VMware ESXi

  • Promiscuous mode: Accept
  • MAC Address Changes: Accept
  • Forged Transmits: Accept

Proxmox / KVM

  • Généralement OK par défau
  • Attention aux bridges avec sécurité activée

Hyper-V

  • Activer MAC spoofing sur la VM
  • Configurer le port en mode trunk
Set-VMNetworkAdapterVlan -VMName "NomDeLaVM" -Trunk -AllowedVlanIdList "1-4094" -NativeVlanId 1
  • -Trunk → active le mode trunk
  • -AllowedVlanIdList → VLAN autorisés (taggés)
  • -NativeVlanId → VLAN non taggé (optionnel mais recommandé)

Configurer un réseau Macvlan avec Docker

Nous allons maintenant voir comment configurer un réseau Macvlan avec Docker pour exposer des conteneurs sur le LAN.

Dans ce tutoriel, j’ai utilisé une VM Debian 13 qui fonctionne sur Proxmox, pour des raisons « pratique », j’ai ajouté une seconde carte réseau que je vais utiliser pour la configuration des interfaces Macvlan.

Comment je vais mes conteneurs sont des VLAN différents, assurer vous d’avoir le paquet vlan d’installater :

apt intall -y vlan

Afin que vous puissiez visualiser, voici les listes des interfaces du serveur.

Je vais travailler sur l’interface ens19.

La première étape va être de configurer les interfaces sur réseau sur le serveur, ci-après la configuration de mon interface ens19 dans le fichier /etc/network/interfaces.

allow-hotplug ens19
iface ens19 inet manual
        up ip link set $IFACE up


#vlan3
auto ens19.3
iface ens19.3 inet manual
        vlan-raw-device ens19
        up ip link set $IFACE up
        down ip link set $IFACE dow

Explications :

Cette configuration réseau permet de préparer une interface physique et un VLAN associé pour une utilisation avancée, notamment avec Docker et Macvlan.

La première partie concerne l’interface physique ens19. Elle est déclarée en mode manual, ce qui signifie qu’aucune adresse IP ne lui est attribuée directement par le système. L’instruction allow-hotplug ens19 indique que l’interface sera activée automatiquement dès qu’elle est détectée (par exemple au démarrage ou lors d’un branchement). La directive up ip link set $IFACE up force simplement l’interface à être montée (active), ce qui est indispensable pour pouvoir l’utiliser comme support de VLAN ou de réseau Macvlan.

La seconde partie définit une interface VLAN nommée ens19.3, correspondant au VLAN ID 3. Cette interface est basée sur l’interface physique ens19, comme indiqué par vlan-raw-device ens19. Là encore, elle est configurée en mode manual, sans adresse IP, car son objectif est d’être utilisée comme support réseau pour des conteneurs Docker plutôt que pour l’hôte lui-même. Les commandes up et down permettent respectivement d’activer et de désactiver l’interface proprement.

En résumé, cette configuration prépare une interface VLAN opérationnelle mais sans IP sur l’hôte, ce qui est une bonne pratique dans un contexte Macvlan : cela évite les conflits et permet de déléguer entièrement l’adressage IP aux conteneurs, qui pourront ainsi apparaître comme des machines indépendantes sur le réseau.

Une fois la configuration effectuée, redémarrer le service networking pour la prise en compte.

systemctl restart networking.service

Si on regarde de nouveau les interfaces, on peut voir celle configurée sur le VLAN 3.

Avant de configurer notre réseau sur notre conteneur, nous allons ajouter le réseau :

docker network create -d macvlan --subnet=192.168.3.0/24 --gateway=192.168.3.1 -o parent=ens19.3 -o macvlan_mode=bridge vlan3_net

Dans cette commande, l’option -d macvlan indique à Docker d’utiliser le driver Macvlan, qui permet aux conteneurs d’avoir une IP et une MAC distinctes sur le réseau physique. L’option --subnet=192.168.3.0/24 définit la plage IP que Docker pourra utiliser pour ses conteneurs, tandis que --gateway=192.168.3.1 correspond à la passerelle du réseau. L’option -o parent=ens19.3 permet de spécifier l’interface physique de l’hôte sur laquelle le réseau Macvlan sera attaché, ici correspondant au VLAN 3. Le paramètre -o macvlan_mode=bridge configure le Macvlan en mode bridge, recommandé pour que les conteneurs se comportent comme des machines distinctes sur le LAN. Enfin, vlan3_net est simplement le nom que l’on donne au réseau Docker, utilisé ensuite pour connecter les conteneurs.

On va maintenant passer la configuration du conteneur, pour cet exemple, je vais prendre le service guacd qui est charge de la connexion (RDP et SSH) sur Guacamole.

services:
  guacamole_db:
  container_name: guacamole_db
  hostname: guacamole_db
  networks:
    guacamole-net:
  image: mariadb:11.1
  ...

  guacd:
    container_name: guacd
    hostname: guacd
    image: guacamole/guacd:latest
    networks:
      vlan3_net:
        ipv4_address: 192.168.3.10
    restart: always
    ...

  guacamole:
    container_name: guacamole
    hostname: guacamole
    restart: always
    networks:
      proxy:
      guacamole-net:
    image: guacamole/guacamole
    ...
    environment:
      - GUACD_HOSTNAME=192.168.3.10
    ...

networks:
  vlan3_net:
    external: true
  guacamole-net:
    driver:  bridge
  proxy:
    external: true

Redémarrer le stack :

docker compose down && docker compose up -d

Le service guacd dispose désormais de sa propre adresse IP sur le réseau. De ce fait, il n’est plus nécessaire d’accorder des autorisations RDP ou SSH à l’ensemble du serveur hôte. Les règles d’accès peuvent être appliquées uniquement à cette adresse IP dédiée, ce qui permet de réduire la surface d’exposition et d’améliorer significativement la sécurité du réseau.

Conclusion

Le driver Macvlan permet d’intégrer parfaitement Docker dans un réseau existant en attribuant une adresse IP dédiée à chaque conteneur. Cela offre une meilleure granularité dans la gestion des accès, notamment dans des environnements où les contraintes réseau sont fortes (VLAN, DMZ, supervision, prestataires externes, etc.).

Comme nous l’avons vu, cette approche permet de réduire le nombre de machines tout en conservant une isolation réseau propre à chaque service. Que ce soit pour exposer un service comme Guacamole ou pour mutualiser plusieurs proxies Zabbix sur différents VLANs, Macvlan apporte une solution simple et efficace.

Cependant, son utilisation nécessite de bien comprendre son fonctionnement et ses contraintes, notamment au niveau de l’hyperviseur, du réseau et des limitations de communication avec l’hôte. Une fois ces points maîtrisés, Macvlan devient un outil particulièrement puissant pour structurer proprement son infrastructure Docker.

FAQ

Peut-on créer plusieurs réseaux Macvlan sur une même interface réseau ?

Oui, il est tout à fait possible de créer plusieurs réseaux Macvlan sur une seule interface physique (par exemple eth0 ou ens19). Chaque réseau peut être associé à un VLAN différent (ex : ens19.3, ens19.10, etc.) ou même utiliser le même parent avec des configurations distinctes.

La seule limite réelle dépendra de votre infrastructure réseau (switch, hyperviseur) et de sa capacité à gérer plusieurs adresses MAC sur un même port.

Faut-il faire attention à la configuration IP du réseau ?

Oui, c’est un point très important. Lorsque vous utilisez Macvlan, les conteneurs sont directement exposés sur le réseau et utilisent des adresses IP du même subnet que vos autres équipements.

Si un serveur DHCP est déjà présent sur ce réseau, il est fortement recommandé :

🔹soit de définir une plage IP dédiée pour Docker
🔹soit d’attribuer manuellement les adresses IP dans vos fichiers Docker (comme avec docker-compose)

👉 Sans cela, vous risquez des conflits d’adresses IP entre vos conteneurs et les autres machines du réseau.

Pourquoi l’hôte ne peut-il pas communiquer avec les conteneurs Macvlan ?

C’est un comportement normal du driver Macvlan. Par défaut, le noyau Linux isole l’hôte de ses interfaces Macvlan.

Pour contourner cette limitation, il est possible de créer une interface Macvlan supplémentaire sur l’hôte afin de rétablir la communication.

Macvlan fonctionne-t-il dans tous les environnements ?

Non. Macvlan dépend fortement du support réseau :

🔹Peut ne pas fonctionner sur le Wi-Fi
🔹Peut être limité ou bloqué dans certains environnements cloud
🔹Nécessite l’activation de fonctionnalités spécifiques côté hyperviseur (ex : MAC spoofing, mode promiscuité)

Il est donc important de valider la compatibilité avec votre infrastructure avant un déploiement en production.

Macvlan est-il adapté à tous les usages Docker ?

Pas forcément. Macvlan est particulièrement utile lorsque vous avez besoin d’intégrer vos conteneurs directement dans votre réseau (avec IP dédiée).

En revanche, pour des applications classiques (web, API, etc.), les réseaux Docker standards (bridge, overlay) sont souvent suffisants et plus simples à gérer.

Romain Drouche
Romain Drouche
Architecte Système | MCSE: Core Infrastructure
Expert en infrastructures IT avec plus de 15 ans d’expérience sur le terrain. Actuellement Chef de projet Systèmes et Réseaux et Référent SSI (Sécurité des Systèmes d’Information), je mets mon expertise au service de la fiabilité et de la sécurité des environnements technologiques.

Laisser un commentaire