Dans cet article, nous allons étudier la mise en place d’un réseau avec Openswitch. Ce réseau sera utilisé dans le cadre de la virtualisation de VMs avec l’aide de KVM.
Cet article s’intègre dans la série New Box 2022. Vous y trouverez le pourquoi du comment, les prérequis, paquets à installer, etc…
I – Explication
Voila un schéma réseau pour présenter succinctement ce que nous allons mettre en place :
NB : Pour le moment, je n’ai pas indiqué l’ensemble de l’architecture, le schéma sera complété au fur et a mesure du tuto.
Les carrés représentent les futurs VMs et les rectangles, des switchs.
On y trouve, de haut en bas :
- Deux routeurs de « bordure » : Un master, un backup, avec une IP Flottante 66.66.66.66, IP publique. C’est notre interco avec le grand internet.
- Ces routeurs ont un adressage privé en 10.10.1.0/24 et sont branchés sur un premier Switch appelé Vlan10.
- Nous trouvons ensuite, également connectés à ce Switch, nos VMS FrontWeb. Ces serveurs sont accessibles de l’extérieur pour y héberger nos frontaux Web par le biais du routeur et de DNAT. De manière identique aux routeurs, le service FrontWeb est loadbalancé avec une IP flottante en 10.10.1.10.
- Par la suite, dans cette couche, nous ajouterons d’autres VMs qui ont vocation à offrir un service sur Internet (mail, dns, etc…)
- Ces VMs de front auront chacune une interface sur un réseau 10.20.1.0/24. Sur ce réseau, nous allons trouver également deux routeurs (Master-Slave) qui vont faire le transit entre les VMs des services publics (Serveur Web, Messagerie, DNS, VPN) et les VMs ‘Infra’ (Stockage, SQL, etc…)
- Chacun de ces « pools », stockage, SQL, lDAP, sera isolé au niveau par le truchement de Switchs. Nous détaillerons tout cela plus tard…
Les plus pinailleurs des experts réseau me diront que j’aurais pu être plus économe en plage IP… Oui, je découpe large, tel un boucher « Y’en a un peu plus, je vous le mets avec ? »
On n’est pas la pour faire un TP réseau, on peut prendre le 10.0.0.0/8, alors roule pedro…
Pour les switchs, on est d’accord, on est sur du virtuel avec Openvswitch. Et on ne va pas faire un switch par sous réseau, mais utiliser les Vlans.
On aura donc, comme « switchs » :
- un switch br0, destiné a l’interco avec le monde extérieur par le biais de l’interface physique eno1 du serveur
- un switch brint, destiné à l’interconnexion entre les vms. Ce switch sera « découpé » en sous réseaux par l’utilisation de VLAN.
D’un point de vue hyperviseur, on a ce schéma :
Deux grands types de VMs :
- Celles avec une connexion vers le réseau externe
- Celles avec de simples lien en interne
Le lecteur curieux et surement un brin taquin me demandera : « Mais diantre, pourquoi deux switchs distincts ? »
Nous sommes d’accord, il serait tout a fait possible de n’en utiliser qu’un seul, avec un vlan associé pour le lien externe, et hop… Mais je suis chez Online et chez Online, si on a une VM qui s’annonce sur le réseau mais qui n’est pas déclaré côté Online, on se mange un blocage de port et c’est direction le support (et du coup, interruption plus ou moins longue…)
Si je fais tout bien, ça ne doit pas arriver, mais on le sait, en informatique, le risque zéro n’existe pas, il se peut que je puisse me louper, du coup, je ne prend pas de risques, un switch virtuel dédié aux VMS qui doivent avoir un lien direct avec le réseau externe, un autre pour le reste et on minimise alors le risque de foirage…
II – Mise en place
A – OpenvSwitch
Au cas ou vous arriviez sur cette page par une recherche Google sans avoir vu l’article racine (Tuto Virtualisation V 2022 : Debian 11, KVM et Openvswitch), il faut au préalable installer Openvswitch sur l’hyperviseur :
# apt install openvswitch-switch
On va ajouter nos deux switchs br0 et brint :
# ovs-vsctl add-br br0 # ovs-vsctl add-br brint
On peut vérifier avec :
# ovs-vsctl show
B – Connexion Hyperviseur sur le switch br0
Pour « connecter » ce switch a notre hyperviseur (en gros, l’intercaler entre le noyau et le port réseau physique), nous allons modifier le fichier interfaces /etc/network/interfaces de l’hyperviseur :
auto lo iface lo inet loopback auto br0 allow-ovs br0 allow-br0 eno1 iface br0 inet static address AAA.BBB.CCC.DDD netmask 255.255.255.0 gateway IP.GATEWAY ovs_type OVSBridge ovs_ports eno1 iface eno1 inet manual ovs_bridge br0 ovs_type OVSPort
Vous pensez à vérifier le nom de votre interface externe (qui sur la Dedibox en Debian11 est eno1).
Et on relance :
# service networking restart
Et si vous n’avez pas les doigts palmés, on doit toujours avoir la machine connectée au réseau. Sinon, on est bon pour un mode rescue 😉
Si on fait un :
# ip a
On voit que l’IP est désormais « attachée » à br0.
... 2: eno1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq master ovs-system state UP group default qlen 1000 link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff altname enp4s0f0 inet6 xxx::xxx:xxxx:xxxx:xxxx/64 scope link valid_lft forever preferred_lft forever 3: eno2: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000 link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff altname enp4s0f1 4: ovs-system: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000 link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff 5: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default qlen 1000 link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff inet YY.YY.YY.YY/24 brd YY.YY.YY.YY scope global br0 valid_lft forever preferred_lft forever inet6 xxx::xxx:xxxx:xxxx:xxxx/64 scope link valid_lft forever preferred_lft forever 6: brint: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000 link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
II – Definition network dans KVM
Maintenant, passons à la configuration du réseau côté KVM, d’une manière similaire à la gestion du stockage, à savoir, définition de pool, etc..
On liste ce qui est en place :
# virsh net-list --all
On supprime :
# virsh net-undefine default
En parallèle, on va se créer un petit répertoire pour stocker nos configurations, histoire de pas avoir des fichiers qui trainent partout :
# mkdir /root/conf_network && cd /root/conf_network
A – Switch br0
On va maintenant configurer KVM pour que le br0 soit pris en compte et utilisable par les VMs. Cela se fait en le définissant dans un fichier xml nommé, par exemple, front.xml :
<network> <name>ovs-front</name> <forward mode='bridge'/> <bridge name='br0'/> <virtualport type='openvswitch'/> </network>
Il faut ensuite l’insérer et l’activer :
# virsh net-define front.xml # virsh net-start ovs-front # virsh net-autostart ovs-front
Et si on liste :
# virsh net-list --all
On le voit !
B – Switch brint
Dans un fichier nommé intern.xml :
<network> <name>intern-vlans</name> <forward mode='bridge'/> <bridge name='brint'/> <virtualport type='openvswitch'/> <portgroup name='vlansadmin'> <vlan trunk='yes'> <tag id='99'/> <tag id='250'/> </vlan> </portgroup> <portgroup name='vlansext'> <vlan trunk='yes'> <tag id='10'/> <tag id='20'/> </vlan> </portgroup> <portgroup name='vlan10'> <vlan> <tag id='10'/> </vlan> </portgroup> <portgroup name='vlan20'> <vlan> <tag id='20'/> </vlan> </portgroup> <portgroup name='vlansint'> <vlan trunk='yes'> <tag id='100'/> <tag id='101'/> <tag id='102'/> <tag id='103'/> <tag id='104'/> <tag id='105'/> <tag id='106'/> <tag id='107'/> <tag id='108'/> <tag id='109'/> </vlan> </portgroup> <portgroup name='100'> <vlan> <tag id='100'/> </vlan> </portgroup> <portgroup name='101'> <vlan> <tag id='101'/> </vlan> </portgroup> <portgroup name='102'> <vlan> <tag id='102'/> </vlan> </portgroup> <portgroup name='103'> <vlan> <tag id='103'/> </vlan> </portgroup> <portgroup name='104'> <vlan> <tag id='104'/> </vlan> </portgroup> <portgroup name='105'> <vlan> <tag id='105'/> </vlan> </portgroup> <portgroup name='106'> <vlan> <tag id='106'/> </vlan> </portgroup> <portgroup name='107'> <vlan> <tag id='107'/> </vlan> </portgroup> <portgroup name='108'> <vlan> <tag id='108'/> </vlan> </portgroup> <portgroup name='109'> <vlan> <tag id='109'/> </vlan> </portgroup> </network>
La configuration demande une petite explication.
Au niveau des Vlans, j’ai ceci :
– 99 : utilisé pour les communications hyperviseur <-> VMs
– 250 : utilisé pour la supervision
Ces deux VLANs étant systématiquement utilisés et disponibles sur l’ensemble des VMs, ils sont regroupés au sein d’un trunk nommé vlansadmin, déclaré ainsi dans le fichier :
<portgroup name='vlansadmin'> <vlan trunk='yes'> <tag id='99'/> <tag id='250'/> </vlan> </portgroup>
Ensuite, j’ai les VLANs 10 et 20, utilisés dans les intercos routeurs externes <-> front et front <->routeurs internes.
Je peux avoir des machines avec uniquement le VLAN 10, d’autres avec uniquement le VLAN 20 et pour terminer certaines avec les deux.
Je déclare alors ainsi :
<portgroup name='vlansext'> <vlan trunk='yes'> <tag id='10'/> <tag id='20'/> </vlan> </portgroup> <portgroup name='vlan10'> <vlan> <tag id='10'/> </vlan> </portgroup> <portgroup name='vlan20'> <vlan> <tag id='20'/> </vlan> </portgroup>
avec un trunk nommé vlansext qui regroupe les deux VLANs.
Et pour terminer, les VLANs utilisés par les pools de services, web, stockage, etc.. Numérotés de 100 à 109 avec en supplément un trunk vlansint (regroupant l’ensemble des VLANS 100,101,102….109), utilisé entre le switch et les routeurs internes. Ce qui donne cela :
<portgroup name='vlansint'> <vlan trunk='yes'> <tag id='100'/> ... <tag id='109'/> </vlan> </portgroup> <portgroup name='100'> <vlan> <tag id='100'/> </vlan> </portgroup> ... <portgroup name='109'> <vlan> <tag id='109'/> </vlan> </portgroup> </network>
Et de la même manière que pour br0, pour utiliser tout ceci dans nos futurs VMs :
# virsh net-define intern.xml # virsh net-autostart intern-vlans # virsh net-start intern-vlans
On peut vérifier :
# virsh net-list --all
A y est, c’est prêt ! Il ne reste plus qu’un petit réglage…
C – Hyperviseur sur le VLAN 99
Comme je l’ai expliqué, le VLAN 99 sert à l’interconnexion entre l’hyperviseur et les VMs. On va donc connecter notre hyperviseur sur ce switch brint.
A savoir, quand on créé un switch à l’aide d’Openvswitch, un port de type particulier est créé automatiquement :
Bridge brint Port brint Interface brint type: internal ...
Port indiqué de type internal. On a le même également pour br0.
Sur ce port brint (côté Debian), on va associer une IP :
# ip addr add 10.99.1.250 dev brint # ip link set brint up # ip route add 10.99.1.0/24 dev brint
On affecte l’IP 10.99.1.250, on monte le lien et on ajoute la route vers 10.99.1.0/24 via ce nouveau port.
Ensuite, il ne reste plus qu’à indiquer le VLAN à utiliser sur le port. Et cela se fait ainsi :
# ovs-vsctl set port brint tag=99
On peut vérifier au niveau Openvswitch :
# ovs-vsctl show
Qui nous indique :
Bridge brint Port brint tag: 99 Interface brint type: internal Bridge br0 Port eno1 Interface eno1 Port br0 Interface br0 type: internal
Et histoire de maintenir la persistance au boot :
# nano /srv/boot.sh
Avec dedans :
#!/bin/bash ip addr add 10.99.1.250 dev brint ip link set brint up ip route add 10.99.1.0/24 dev brint ovs-vsctl set port brint tag=99
puis
# chmod +x boot.sh
Ensuite, on va créer le service qui va appeler le script :
# nano /etc/systemd/system/hypervisor-boot.service
Avec dedans :
[Unit] Description=HyperVisor Boot After=default.target [Service] ExecStart=/srv/boot.sh [Install] WantedBy=default.target
Et pour finir, on active avec :
# systemctl enable hypervisor-boot.service
Voila mis en place la couche réseau de notre future architecture.
Je vous propose donc de revenir à l’article initial et de poursuivre la feuille de route.