LXC et connection au réseau par pont
Lorsqu'on crée des machines virtuelles avec libvirt ou VirtualBox, ces applications s'occupent de gérer les connections au réseau. Mais on n'utilise pas toujours libvirt ou VirtualBox. Dans mon cas, je voulais tester LXC (le site n'a pas l'air très frais...) afin de pouvoir bénéficier d'une machine virtuelle tout en économisant la mémoire vive. En effet, une fois que j'ai lancé gnome-shell, firefox et thunderbird, il ne reste plus beaucoup de mes 2 Go de mémoire vive ! LXC permet de cloisonner des processus et donc de lancer tout un système d'exploitation sans avoir à émuler du matériel.
Créer un environnement avec LXC est simple. Après avoir installé les outils (pacman -S lxc
), il suffit de lancer lxc-create -n nom_de_la_machine -t debian
pour créer une machine virtuelle nommée nom_de_la_machine
en se basant sur le template debian. L'utilisation du template debian nécessite toutefois d'installer d'autres outils (comme dpkg
et debootstrap
).
Maintenant, on peut manipuler notre environnement Debian avec les commandes :
lxc-start -n nom_de_la_machine
: démarre l'environnement. On pourra rajouter l'option -d pour lancer l'environnement en mode démon (enfin, simplement en arrière plan).lxc-console -n nom_de_la_machine
: se connecte à l'environnement virtualisé.lxc-stop -n nom_de_la_machine
: éteint l'environnement.lxc-ls
: affiche les environnements disponibles.
De base, la machine créée n'est pas connetée au réseau. Nous allons donc voir comment configurer l'hôte et l'environnement virtualisé.
Plusieurs scénarios sont possibles. Ici, nous allons créer un réseau entre l'hôte et l'environnement virtualisé, puis configurer l'hôte pour servir de passerelle NAT. Le principe du réseau interne consiste à créer un pont réseau virtuel auquel la machine virtuelle et l'hôte vont se connecter. Voici les commandes pour créer le pont :
# sur l'hôte
brctl addbr lxcbr0 ifconfig lxcbr0 192.168.222.1 netmask 255.255.255.0 up
Maintenant, nous devons configurer notre environnement pour qu'au lancement, il crée une interface virtuelle qui fasse partie du pont. Il faut s'assurer que les lignes suivantes soient présentes dans /var/lib/lxc/nom_de_la_machine/config
:
lxc.network.type = veth lxc.network.flags = up lxc.network.link = lxcbr0
Maintenant, on peut redémarrer l'environnement, puis configurer le réseau :
# sur l'environnement cloisonné
ifconfig eth0 192.168.222.2 netmask 255.255.255.0 up route add default gw 192.168.222.1 dev eth0
À ce niveau, on peut constater que l'environnement a une interface :
[nom_de_la_machine]$ ifconfig eth0 eth0 Link encap:Ethernet HWaddr 6e:b2:2a:ef:1b:d6 inet addr:192.168.222.2 Bcast:192.168.222.255 Mask:255.255.255.0 inet6 addr: fe80::6cb2:2aff:feef:1bd6/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:5469 errors:0 dropped:0 overruns:0 frame:0 TX packets:3135 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:7573740 (7.2 MiB) TX bytes:245057 (239.3 KiB)
Et sur l'hôte, on constate qu'une interface a été créée et s'est enregistrée au pont :
[host]$ brctl show bridge name bridge id STP enabled interfaces lxcbr0 8000.fe4df3f631c5 no vethFcOTZN [host]$ ifconfig vethFcOTZN vethFcOTZN: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet6 fe80::fc4d:f3ff:fef6:31c5 prefixlen 64 scopeid 0x20<link> ether fe:4d:f3:f6:31:c5 txqueuelen 1000 (Ethernet) RX packets 3135 bytes 245057 (239.3 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 5469 bytes 7573740 (7.2 MiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
Et les deux machines devraient se pinguer (ping 192.168.222.2
sur l'hôte et ping 192.168.222.1
sur l'environnement virtuel).
Maintenant, il suffit d'activer le NAT, et configurer le DNS sur l'environnement cloisonné :
# sur l'hôte
echo 1 > /proc/sys/net/ipv4/ip_forward # wlp11s0 est mon interface relié à internet iptables -t nat -A POSTROUTING -o wlp11s0 -j MASQUERADE # configurer le DNS cp /etc/resolv.conf /var/lib/lxc/nom_de_la_machine/rootfs/etc/
Et vous pourrez accèder au monde entier depuis l'environnement virtualisé !
Dans les autres options possibles, on pourrait relier directement l'interface virtuelle de notre environnement cloisonné vers l'interface reliée au réseau (mais je suis connecté au réseau par le wifi, et ce n'est apparemment pas supporté). On pourrait également configurer l'environnement par DHCP, utiliser un serveur DNS local... il y a beaucoup de scénarios possibles... À explorer !
Si LXC vous intéresse, un article assez complet a été publié dans GNU/Linux Magazine 159.