Les différentes formes de configuration du réseau avec OpenVZ

Il existe deux façons de configurer le réseau des serveurs virtuels OpenVZ : venet (Virtual Network) et veth (Virtual Ethernet). Jusqu’ici j’ai parlé uniquement de la première, plus simple à utiliser et qui convient dans la majorité des cas. Mais si votre serveur virtuel héberge un service ou une application qui nécessite, par exemple, de recevoir du broadcast, alors venet n’est pas suffisant, et il faut utiliser une interface réseau veth.

Différences entre venet et veth

(note : cette section est une traduction de la page http://wiki.openvz.org/Differences_between_venet_and_veth, que j’ai trouvée claire et concise)

  • veth transmet le broadcast aux machines virtuelles, de sorte que vous pouvez y installer des applications comme un serveur DHCP ou un serveur samba (NDT: sans serveur WINS)
  • veth a des conséquences sur la sécurité, et il n’est pas recommandé dans des environnements non sûrs, comme pour la fourniture de services d’hébergement. Ceci est lié au broadcast, à la capture de paquets, au risque de collision d’adresses IP, etc. Un utilisateur de machine virtuelle avec veth peut vraiment mettre à mal votre réseau avec un tel accès direct à la couche ethernet.
  • Avec une interface virtuelle venet, seul l’administrateur du serveur physique OpenVZ peut attribuer une adresse IP à une machine virtuelle. Avec une interface virtuelle veth, les paramètres réseau peuvent être intégralement définis dans la machine virtuelle, depuis l’administrateur de cette dernière. La machine virtuelle doit paramétrer correctement une adresse IP, le masque de sous réseau, la passerelle par défaut… et l’administrateur du serveur physique peut seulement choisir vers où router le trafic de la machine virtuelle.
  • Les interfaces virtuelles veth peuvent être bridgées ensemble et/ou avec d’autres interfaces. Par exemple, l’administrateur du système hôte peut bridger les veth de deux machines virtuelles avec une interface VLAN eth0.X. Dans ce cas, ces deux machines virtuelles seront connectées à ce VLAN.
  • Une interface venet est légèrement plus rapide et plus efficiente.
  • Pour une interface veth, l’adresse IPv6 est auto-générée depuis l’adresse MAC.

Tableau récapitulatif :

Differences entre veth et venet
Caractéristique veth venet
Adresse MAC Oui Non
Machine virtuelle reçoit le broadcast Oui Non
Possibilité de renifler les paquets Oui Non
Sécurité du  réseau Faible [1] Elevée
Capacité à être bridgé Oui Non
Performance Rapide Plus rapide
  1. En raison du broadcast, de la possibilité de renifler le réseau ou d’obtenir des collisions d’adresses IP collisions, etc.

En résumé

Le gros intérêt de l’interface venet, c’est que ça permet à l’administrateur du serveur physique de décider de la configuration réseau de la machine virtuelle. C’est particulièrement appréciable pour un hébergeur qui souhaite vendre un service d’hébergement de machines virtuelles, car il peut librement laisser ses clients administrer leur serveur virtuel OpenVZ tout en étant certain qu’ils ne pourront pas perturber le réseau, s’attribuer davantage d’adresses IP que prévu, bidouiller les tables de routage, etc. Si vous utilisez OpenVZ pour fournir des services d’hébergement à vos clients, l’interface veth n’est pas faite pour vous. Je ne suis pas dans ce cas de figure, donc les potentiels problèmes de sécurité que peuvent poser l’interface veth pour un hébergeur ne me concernent pas.

J’utilise à la fois venet et veth sur les serveurs que j’administre : veth lorsque j’ai besoin d’avoir un accès aux couches ethernet depuis les serveurs virtuels, et venet dans tous les autres cas. Mais, contrairement à la simplicité offerte par les interfaces venet, pour pouvoir utiliser une interface veth dans un serveur virtuel, il faut faire quelques opérations de configuration complémentaires pour préparer le serveur physique à recevoir des serveurs virtuels utilisant veth. C’est ce que je vais décrire dans les sections suivantes.

Préparation du serveur physique

Ceci est valable pour un serveur physique Debian Etch et Ubuntu 8.04, et avec les paquets conçus pour ces distributions, qui fournissent OpenVZ dans une version 3.0.22. Au delà de la version 3.0.22 d’OpenVZ, cela devrait être un peu plus simple.

Pour que les serveurs virtuels aient une interface ethernet, via veth, il faut bridger les interfaces veth avec une interface physique du serveur. Nous allons commencer par créer le bridge sur le serveur, puis nous verrons comment faire pour que les interfaces virtuelles s’ajoutent ou se retirent du bridge en fonction du démarrage ou de l’arrêt des serveurs virtuels.

Configuration du bridge sur le serveur physique

Votre serveur physique est certainement déjà paramétré pour votre réseau. Son fichier de configuration du réseau, /etc/network/interfaces, doit ressembler à ceci :

root@vz_host:~# cat /etc/network/interfaces
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
    address 192.168.1.1
    netmask 255.255.255.0
    network 192.168.1.0
    broadcast 192.168.1.255
    gateway 192.168.1.254

Pour que vos serveurs virtuels aient une interface veth qui soit « branchée » sur l’interface physique eth0 du serveur, il faut qu’au moment du boot, le serveur créée un bridge qui, au début, ne contient que l’interface eth0. Pour cela, il est  nécessaire que le paquet bridge-utils soit installé, si ce n’est pas déjà fait :

root@vz_host:~# apt-get install bridge-utils

Ensuite, il suffit de modifier le fichier /etc/network/interfaces comme ceci (il faut également que le serveur ait chargé le module vzethdev, ce qui devrait être le cas si vous avez suivi le tuto jusqu’ici) :

root@vz_host:~# cat /etc/network/interfaces
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet manual

auto vzbr0
iface vzbr0 inet static
    bridge_ports eth0
    address 192.168.1.216
    netmask 255.255.255.0
    network 192.168.1.0
    broadcast 192.168.1.255
    gateway 192.168.1.254

et rebooter.

Après redémarrage, l’exécution des commandes suivantes sur le serveur doit retourner ceci :

root@vz_host:~$ ifconfig
eth0      Link encap:Ethernet  HWaddr 00:15:f2:97:ad:e1 
          adr inet6: fe80::215:f2ff:fe97:ade1/64 Scope:Lien
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          Packets reçus:925 erreurs:0 :0 overruns:0 frame:0
          TX packets:714 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 lg file transmission:1000
          Octets reçus:893972 (873.0 KB) Octets transmis:86440 (84.4 KB)
          Interruption:16 Adresse de base:0x2000 

lo        Link encap:Boucle locale 
          inet adr:127.0.0.1  Masque:255.0.0.0
          adr inet6: ::1/128 Scope:Hôte
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          Packets reçus:8 erreurs:0 :0 overruns:0 frame:0
          TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 lg file transmission:0
          Octets reçus:560 (560.0 B) Octets transmis:560 (560.0 B)

venet0    Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 
          UP BROADCAST POINTOPOINT RUNNING NOARP  MTU:1500  Metric:1
          Packets reçus:0 erreurs:0 :0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 lg file transmission:0
          Octets reçus:0 (0.0 B) Octets transmis:0 (0.0 B)

vzbr0     Link encap:Ethernet  HWaddr 00:15:f2:97:ad:e1 
          inet adr:192.168.1.216  Bcast:192.168.1.255  Masque:255.255.255.0
          adr inet6: fe80::215:f2ff:fe97:ade1/64 Scope:Lien
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          Packets reçus:904 erreurs:0 :0 overruns:0 frame:0
          TX packets:708 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 lg file transmission:0
          Octets reçus:880056 (859.4 KB) Octets transmis:82416 (80.4 KB)

root@vz_host:~# brctl show
bridge name	bridge id		STP enabled	interfaces
vzbr0		8000.0015f297ade1	no		eth0

ce qui montre que l’interface du bridge détient bien l’adresse IP définie dans /etc/network/interfaces et que le bridge est bien constitué, pour le moment, de la seule interface eth0.

Paramétrage OpenVZ sur le serveur hôte

Afin qu’au lancement d’un serveur virtuel OpenVZ ajoute ou retire dynamiquement une interface veth au bridge, il faut créer quelques fichiers sur le serveur physique. Cette opération est à faire une bonne fois pour toutes sur le serveur physique, indépendamment du nombre de serveurs virtuels qui seront créés par la suite. Il est également possible de la faire sur un serveur qui, au final, n’héberge que des serveurs virtuels utilisant des interfaces venet, cela ne perturbe en rien ces derniers.

D’abord, il faut créer le fichier /etc/vz/vznet.conf, avec le contenu suivant :

#!/bin/bash
EXTERNAL_SCRIPT="/usr/local/sbin/vznetaddbr"

puis le fichier /usr/local/sbin/vznetaddbr, avec le contenu suivant :

#!/bin/bash
# /usr/local/sbin/vznetaddbr
# a script to add virtual network interfaces (veth's) in a VE to a bridge on VE0
CONFIGFILE=/etc/vz/conf/$VEID.conf
. $CONFIGFILE
VZHOSTIF=`echo $NETIF |sed 's/^.*host_ifname=\(.*\),.*$/\1/g'`
if [ ! -n "$VZHOSTIF" ]; then
   echo "According to $CONFIGFILE VE$VEID has no veth interface configured."
   exit 1
fi
if [ ! -n "$VZHOSTBR" ]; then
   echo "According to $CONFIGFILE VE$VEID has no bridge interface configured."
   exit 1
fi
echo "Adding interface $VZHOSTIF to bridge $VZHOSTBR on VE0 for VE$VEID"
/sbin/ifconfig $VZHOSTIF 0
echo 1 > /proc/sys/net/ipv4/conf/$VZHOSTIF/proxy_arp
echo 1 > /proc/sys/net/ipv4/conf/$VZHOSTIF/forwarding
/usr/sbin/brctl addif $VZHOSTBR $VZHOSTIF
exit 0

Il faut également associer le droit d’exécution à ce fichier en tapant la commande :

chmod +x /usr/local/sbin/vznetaddbr

Voila. Ce n’était pas grand chose, et à présent le serveur peut héberger des serveurs virtuels dont les interfaces veth seront bridgées avec la ou les siennes. Pour cela, il faut adapter le paramétrage réseau des serveurs virtuels, ce qui fait l’objet de la section suivante.

Paramétrage d’un serveur virtuel pour utiliser une interface veth

En tant qu’administrateur du serveur hôte, vous pouvez ajouter une interface réseau veth à un serveur virtuel avec la commmande

root@vz_host:~# vzctl set $VEID --netif_add eth0 --save

où $VEID est à remplacer par le numéro du serveur virtuel concerné, et eth0 par le nom que vous souhaitez donner à l’interface ethernet à l’interieur du serveur virtuel. Pour le serveur physique, cette interface sera nommée veth$VEID.0, soit, pour le serveur virtuel désigné par le VEID n° 1, veth1.0.

Une fois cette commande appliquée, vous pourrez constater que, dans le fichier de configuration du serveur virtuel; situé dans /etc/vz/conf/$VEID.conf, une ligne telle que celle-ci a été ajoutée.

NETIF="ifname=eth0,mac=00:18:51:2A:AB:99,host_ifname=veth1.0,host_mac=00:18:51:87:7C:50"

Cette commande a généré automatiquement deux adresses MAC qui seront utilisées pour l’interface veth. Une d’entre elles est associée à l’interface eth0, côté serveur virtuel, et l’autre à l’interface veth1.0, côté serveur physique. Il est possible de spécifier les adresses MAC souhaitées sur la ligne de commande vzctl, mais vous devrez alors prendre soin de ne pas avoir de collision d’adresses MAC sur votre réseau.

Nous n’avons pas encore eu l’occasion de spécifier à OpenVZ avec quelle interface physique du serveur il faut bridger cette interface virtuelle. C’est normal, ce paramètre n’est pas pris en charge par OpenVZ dans les versions jusqu’à 3.0.22. C’est pour ça qu’il faut ajouter à la main un script pour la gestion du bridge et qu’il faut ajouter à la main, dans le fichier de configuration du serveur virtuel (dans /etc/vz/conf/$VEID.conf) la ligne suivante :

VZHOSTBR=vzbr0

afin de spécifier à quel bridge du serveur physique l’interface veth doit être ajoutée.

Si vous avez suivi ce tutoriel pour créer le serveur virtuel, vous lui avez peut-être associé une interface réseau venet qui n’est plus nécessaire. Le cas échéant, pour la supprimer, faites :

root@vz_host:~# vzctl set 1 --ipdel 192.168.1.1 --save

Il est temps de (re)lancer le serveur virtuel. Ce n’est qu’à son redémarrage que le script vnetaddbr sera invoqué et que l’interface ethernet virtuelle sera bridgée avec celle du serveur physique. Une fois le serveur virtuel démarré, vous devriez pouvoir constater que le bridge contient bien l’interface veth du serveur virtuel, avec la commande :

root@vz_host:~# brctl show vrzb0
bridge name    bridge id            STP enabled    interfaces
vzbr0          8000.0015f297ade1    no             eth0
                                                   veth1.0

C’est terminé pour la configuration à faire côté serveur hôte. Il vous reste à entrer dans le serveur virtuel pour définir les paramètres réseau. Configuré avec une interface veth, le paramétrage du réseau se fait comme sur un serveur physique : dans l’exemple ci-dessus, le serveur virtuel dispose d’une interface eth0 qui peut être configuré comme d’habitude sur la distribution que vous avez utilisée pour le serveur virtuel (par exemple, sur Debian et Ubuntu, dans le fichier /etc/network/interfaces du serveur virtuel).

  1. salut encore et toujours moi!

    J’ai une question qui est un peu Hors sujet mais qui va toucher celui qui mettra en place du vserver chez lui…

    C’est bien d’avoir plusieurs serveur sur une même machine mais il n’y a que une seule adresse ip pour la ligne adls ou sdls.

    Comment gérer Plusieurs adresses (domaines) avec une seule adresse ip… Ca me semble gérable avec les vhost de apache mais si ce n’est pas du apache?… Vous gérez ça comment chez vous?
    merci pour votre réponse.

  2. Désolé pour le délai de réponse, beaucoup de boulot sur cette fin d’année.

    Je n’ai pas le problème, car j’utilise OpenVZ sur un réseau d’entreprise. J’utilise les adresses IP prévues par la RFC 1918 (adresses non routables telles que 192.168.x.x) et j’attribue une adresse au serveur physique et une par serveur virtuel.

    Evidemment, si tu comptes utiliser une adresse IP de l’espace public pour servir plusieurs serveurs virtuels, tu vas avoir quelques problèmes :)

    Mais tu dois pouvoir t’en sortir en faisant ceci :
    - attribuer l’adresse publique au serveur physique
    - attribuer au serveur physique et aux serveurs virtuels des adresses IP de la rfc 1918 (par exemple une interface réseau virtuelle avec 192.168.1.254 pour le serveur physique, et 192.168.1.1, 192.168.1.2, etc pour tes serveurs virtuels)
    - configurer le serveur physique pour qu’il soit routeur
    - configurer de la translation d’adresse pour les paquets sortants et de la translation de port pour les paquets entrants, avec iptables.

    Mais ca n’a plus rien à voir avec OpenVZ.

    Ca risque d’être un peu chaud comme configuration, surtout si tu ne connais pas iptables, mais par chance, réaliser des routeurs linux qui utilisent iptables sont des choses très bien documentées. Si tu souhaites t’investir dans cette configuration, tu devrais trouver pas mal de ressources.

    Si tu n’es pas familier d’iptables, commence par faire de ton serveur un simple routeur avec deux cartes réseau : une pour internet, l’autre raccordée à un autre serveur qui héberge les machines virtuelles.

  3. J’ai corrigé l’article aujourd’hui, afin :
    - de corriger une erreur : le fichier est /etc/vz/vznet.conf et non pas /etc/vz/venet.conf

    - d’ajouter un prérequis, nécessaire au fonctionnement mais pas forcément installé : le paquet bridge-utils

  4. Bonjour

    Bonne idée ce tuto en français, surtout que les docs sur Openvz sont rares.
    Je reviens sur le sujet.

    J’aurais besoin de mettre mes VE sur plusieurs Vlan (au moins 2)

    Mon serveur HE a deux cartes internet, une (eth1) pour l’administration, l’autre (eth0) monté en bridge (suivant le tuto mais sans adresse IP) pour mes VE.
    Si j’améne un trunk en 802.1Q sur ce bridge, Est ce qu’il pourra distribuer les différents vlan sur mes VE?

    Je pourrais mettre une carte dans un Vlan et l’autre dans un autre, mais si je dois gérer mes VE sur plus de deux vlan, je serais bloqué.
    Mon idée serait de mettre mes VE sur une baie et de venir les chercher avec des HE indépendamment du domaine IP.
    (je sais pas si je suis bien clair)

    Le wiki d’openvz dit que c’est possible mais sans décrire la procédure.

    Merci d’avance.

    {Sinon un soucis que je ne comprend pas… Après avoir monté le bridge en veth. si je fais un vzctl stop $veid cela arrête le HE ?? vous avez déjà vu ça?}

  5. En mode veth, les adresses des VE sont véritablement bridgées avec ta carte ethernet, donc ça ne devrait pas poser de problème.

    Pour ce qui est de stocker les VE dans une baie de disques, c’est exactement comme ça que je les installe.
    J’ai plusieurs serveurs capables d’exécuter des VE stockés dans une baie externe, et moyennant un peu de bricolage (scripts shell persos) ça me permet d’avoir un cluster HA de VE OpenVZ.

    Par ce tuto, et les autres, j’essaie par étapes de décrire tout ça, car j’ai l’intention d’aborder ces points aussi, mais j’ai besoin de planter le décor avant. Ce sera pour dans quelques articles, un de ces jours :)

    Je n’ai jamais vu de cas ou, en arrêtant un VE, le serveur physique s’arrêtait aussi. Par contre, sur mes serveurs, j’ai une conf réseau un peu différente de celle décrite ici parce qu’en plus du bridge, j’utilise aussi du channel bonding et j’en ai un peu bavé pour trouver une configuration qui fonctionne.
    Vu ce que tu veux faire, j’imagine que tu as besoin d’une configuration réseau assez particulière aussi. J’ignore si ça pourrait t’aider vu que je n’ai jamais monté une configuration similaire à ce que tu veux faire, mais si jamais tu veux jeter un oeil aux scripts shells qui me permettent de configurer un host avec bridge + bonding, pour le cas où tu pourrais y trouver une quelconque inspiration, je peux t’envoyer ça.

  6. Hello

    Il faut que j’essaye le trunk dés que notre service réseau me configure ça.

    J’ai aussi envisagé un cluster de HE, comme les VE sont accessibles par tous sur la baie (qui est sauvegardé).
    Par contre pour la sécurité j’ai plusieurs Vlan dédiés, d’où mon intérêt pour le trunk.
    Il faut que j’arrive a régler ça avant le clustering.

    Pour le channel bonding c’est une étape futur, je voyais plutôt cela avec plus de carte réseaux sur le HE. Mais je suis quand même intéressé par les conf.

    Sinon pour mon soucis de l’arrêt du HE au moment de celui du VE. Je n’ai pas encore d’explication, mes conf sont identiques a ton tuto ormis mon fichier interface où le iface vzbr0 inet static n’a pas d’adresse.

    Ce soir c’est les vacances (mérités !) de Paques. Je reprendrais dans une semaine.

    Merci pour les réponses

  7. Pour le channel bonding, il faut effectivement plusieurs cartes réseau, sinon c’est plus difficile :)

    Sur chaque serveur j’ai deux cartes configurées en failover (actif / passif), elles mêmes branchées sur deux switches différents, eux mêmes raccordés au backbone par deux liens. Les liens entre switches sont maillés, pour cela j’active le spanning tree.

    Ca me permet d’avoir de la tolérance aux pannes sur une carte réseau ou un switch.

    Je t’envoie les confs par mail.

    Sinon, si tu ne mets pas d’adresse dans le fichier interface, mets plutot

    vzbr0 inet manual

    au lieu de

    vzbr0 inet static

    Ca permettra de dire clairement aux scripts qui interpretent le fichier interface que la configuration réseau de cette interface n’est pas dans le fichier et qu’il ne faut pas y chercher les attributs habituels.

    Bonnes vacances !

  8. bonjour, je viens de suivre le tuto, mais j’ai un problème de réseau, impossible de faire des pings entre Hn et le VE et inversement

    en plus,si j’exécute la commande : brctl show ça montre toujours :

    bridge name bridge id STP enabled interfaces
    vz1 8000.90e2ba00a9ba no eth2

    je ne vois pas le pont sur veth153.0

    le 153 est le ID de mon VPS

    pourquoi?

  9. Pour une vm bridgée, brctl doit te montrer quelque chose comme ceci :

    # brctl show
    bridge name  bridge id          STP enabled  interfaces
    vzbr0        8000.0018519acd7d  no           bond0
                                                 veth117.0
    

    Dans ton cas, on ne voit pas l’interface veth, c’est que la configuration pour bridger les interfaces virtuelles avec les physiques est incomplète. C’est un symptôme que je connais (ça m’arrive fréquemment :grin: ), tu as du rater une étape du tuto.

    Reprends le tuto et vérifie le fichier /etc/vz/vznet.conf

    et le fichier /usr/local/sbin/vznetaddbr, qui doit aussi être exécutable

    vérifie aussi que tu as bien ajouté une ligne telle que
    VZHOSTBR=vzbr0
    dans ton fichier de conf de la machine virtuelle.

    Bon courage, et tiens moi au courant !

Laisser un commentaire


NOTE - Vous pouvez utiliser les éléments et attributs HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>