Linux Embedded

Le blog des technologies libres et embarquées

Configuration réseau de LXC

LXC est un système d'isolation qui permet d'exécuter plusieurs environnements Linux sur une seule plate-forme. Ce système utilise en fait un seul noyau mais permet de créer de multiples conteneurs Linux possédant chacun ses propres processus et interfaces réseau. LXC est similaire à OpenVZ mais a l'avantage d'être officiellement intégré au noyau.

Contrairement aux machines virtuelles (VirtualBox, VMware, KVM) ou à la paravirtualisation (Xen), LXC :

  • n'est pas dépendant de l'architecture (x86, ARM, MIPS, ...)
  • est plus léger en consommation mémoire puisque l'espace mémoire est partagé entre tous les conteneurs (il n'est pas nécessaire de définir la quantité de mémoire à allouer à chaque conteneur)
  • peut encore être plus léger en consommation mémoire et stockage. En effet, il est possible de créer des conteneurs ayant accès aux répertoires /lib, /bin, /usr et /sbin du système hôte (via des montages utilisant les options bind,ro). Ainsi, il est possible de lancer un service dans un conteneur sans aucun impact sur l'utilisation mémoire.

Ces derniers points montrent qu'il est tout à fait envisageable d'intégrer LXC sur un système embarqué.

La suite de cet article évoque les différentes possibilités de configuration réseau de LXC. Pour des détails sur l'installation et la création de LXC, je vous invite à rechercher les nombreux articles que l'on peut trouver sur la toile (cf. section références).

Configuration réseau des LXC

Pour rappel, un conteneur LXC se crée généralement avec une commande comme :

lxc-create -n <name> -t debian -f </path/to/virtualization/config>

Le fichier de configuration donné avec l'option -f contient notamment la configuration réseau, représentée par les lignes suivantes :

lxc.network.type = <type>
lxc.network.flags = up
lxc.network.link = <interface>
lxc.network.hwaddr = <MAC address>
lxc.network.ipv4 = <IPv4 address>
lxc.network.ipv6 = <IPv6 address>

Voici une aperçu des différents types de configuration (champ lxc.network.type) :

  • empty : aucune interface réseau (hormis le loopback) dans le conteneur LXC
  • phys : utilisation de l'interface physique de l'hôte précisé dans lxc.network.link
  • veth : utilisation d'un bridge spécifié par lxc.network.link. Ce mode veth permet de créer deux interfaces : l'une est ajouté au bridge de l'hôte, l'autre est utilisée par le conteneur LXC. Chaque donnée émise sur une interface est reçu par l'autre.
  • vlan : utilisation d'un VLAN sur une interface de l'hôte. Le numéro du VLAN est spécifié avec lxc.network.vlan.id.
  • macvlan : utilisation de l'interface de l'hôte pour accéder au monde extérieur. Les échanges entre LXCs et entre un LXC et l'hôte ne sont pas possibles par défaut. Ceci permet de déléguer la gestion de la sécurité (pare-feu) à un switch particulier qui pourra retransférer des trames à destination d'un autre LXC ou de l'hôte.
  • macvlan en mode bridge : afin que les LXC puissent communiquer entre eux, il est possible de configurer le macvlan en mode bridge. Pour cela, il suffit d'ajouter l'option lxc.network.macvlan.mode = bridge dans le fichier de configuration. Ceci ne permettra toujours pas une communication des LXC avec la machine hôte. Pour cela, il faudra créer une interface macvlan sur l'hôte. Pour plus d'informations sur la marche à suivre, lisez cette article.

Conclusion

La configuration la plus souvent recherchée est certainement celle en mode bridge. Notez que vous pouvez utiliser le mode veth ou macvlan (en mode bridge). Même si le mode macvlan peux permettre une configuration plus dynamique et sans nécessité de configurer une interface bridge, le mode veth semble plus intuitif et permettra l'utilisation d'outils avancés auxquels nous sommes habitués (tcpdump, ebtables ...).

Références

    • le 16 juillet 2014 à 23:34

      Hello,
      Merci pour ces explications.
      Quelle est la meilleur solution dans le cas ou l'on veut pratiquer du firewalling sur la machine hôte ?

    • le 21 juillet 2014 à 16:54

      Pour utiliser un firewall sur la machine hôte, il faut que l'hôte et les conteneurs soient configurés de telle sorte que l'hôte route les paquets vers les différents conteneurs.

      Pour cela, je recommanderai d'utiliser une configuration de type veth mais sans ajouter les interfaces à un bridge (pour cela, ce pas spécifier la ligne lxc.network.link). Une fois fait, il ne vous reste plus qu'à configurer les interfaces réseau et les routes correctement, puis d'ajouter des règles iptables sur la machine hôte.

      Cette explication est très succincte, mais j'espère qu'elle donne une bonne piste :)

    • le 24 avril 2015 à 12:15

      [&#8230;] d&rsquo;avoir plusieurs configurations réseau – champs « type » , vous pouvez lire  Billet de linux Embedded qui résume très bien les différents types de [&#8230;]

    • le 09 juillet 2017 à 16:34

      Bonjour,
      J'ai essayé (à de nombreuses reprises) de lancer plusieurs conteneurs LXC sur le même vlan sans y parvenir
      Si je tente de créer deux vlan dans la config lxc, j'ai l'erreur File already exists au démarrage du conteneur.

      J'ai aussi essayé d'autre configuration, comme par exemple :
      dummy0
      br0
      vlan10@dummy0
      veth1LXC1
      veth1LXC2

      Sans succés, pas même de connectivité entre l'host et le guest.
      Si quelqu'un peut aidée cela serait cool =D

    • le 10 juillet 2017 à 09:28

      Créer 2 LXC sur le même VLAN est sans doute impossible parce que le système hôte essaye de créer 2 fois la même interface.

      Pour réaliser ce que tu veux, je vois 2 possibilités :
      1. créer un bridge br0 sur l'hôte contenant ton VLAN (exemple eth0.42) puis utiliser le type "veth" dans la configuration LXC (avec lxc.network.link=br0)
      2. créer l'interface eth0.42 sur l'hôte puis utiliser le type "macvlan" dans la confuguration LXC avec l'interface eth0.42

      La solution 2 ne permet pas de communication entre hôte et LXCs donc je préfère souvent la solution 1.
      J'espère que ça aidera.

    • le 10 juillet 2017 à 21:34

      Super !

      Merci et en passant, vraiment tres cool ton blog !

    • le 04 octobre 2019 à 11:26

      Salut, je souhaite implémenter une sonde ids dans un container, j'utilise veth, mais le souci c'est que je n'arrive pas répliquer les paquets qui circulent sur le réseau vers mon container. Tu aurais des conseils pour mon cas stp.
      Merci d'avance :)

    • le 05 octobre 2019 à 16:49

      Salut, tout d'abord merci de m'avoir répondu aussi vite. C'est vrai que j'ai oublié de préciser que j'ai déjà essayer le mode promiscious.
      Résumons l'affaire :
      - br0 est le bridge (promisc) qui permet de faire le lien entre hôte et mon container (configurer en veth avec br0).
      - mon traffic réseau est bien capturé par mon br0 (tcpdump)
      Le problème commence ici : le traffic n'est pas recopié vers mon container qui est lui aussi en promisc. J'ai aussi configuré l'interface virtuelle créé par le container (coté hote) en promisc.
      J'ai également avtivé le ipv4 forward au cas où.
      Je suis bloqué ici :/ - PS : j'ai essayé en mode phys et le container capture bien tout mon traffic réseau. (Solution obsolète selon ANSSI).
      Si t'as des pistes à me donner ça sera avec plaisir :)

    • le 06 octobre 2019 à 20:11

      J'avoue que je n'ai jamais essayé de jouer avec promisc et les veth.
      Les veth correspondent en fait à une cable et s'utilisent en fait en paire (2 interfaces correspondant aux 2 bouts du cable). Une interface veth est ajouté au bridge br0 (appelons la veth1) et l'autre n'est pas visible du host mais est utilisée par le conteneur LXC (appelons la veth2 mais elle est généralement renommé en eth0 dans le conteneur).
      Du coup, une idée à laquelle je pense est de bien s'assurer que le mode promisc est activé sur les 4 interfaces suivantes :
      * br0
      * l'interface filaire de l'host ajouté dans le bridge
      * veth1
      * veth2
      Tiens moi au courant si ça fonctionne :)

    • le 07 octobre 2019 à 14:22

      Salut,

      Mauvaise nouvelle. Après avoir essayé ta proposition le traffic réseau n'est pas recopié vers le container. :/
      J'ai aussi essayé le mode macvlan en bridge mais sans succès.

      Je vais peut-etre changer de solution parce que mon projet stagne trop.
      Je te remercie pour ton investissement :)

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée.