Base documentaire GNU/Linux et développement

Fiches techniques pour la configuration de machines GNU/Linux, de réseau et de développement logiciel

Outils pour utilisateurs

Outils du site


administration-systemes:gestion-de-parc-virt

Gestion d’un petit parc de machines virtuelles avec virt

Objectifs et topologie virtuelle

À des fins de tests, j’ai besoin de pouvoir disposer facilement d’un ensemble de machines virtuelles adressées comme je le désire. Pour la virtualisation, j’utilise le couple QEMU/KVM via Libvirt. Libvirt est installé par défaut sur Fedora. Pour CentOS, on installera le groupe de paquets dédié :

yum groupinstall virtualization-host-environment

Je désire notamment pouvoir disposer d’un réseau à la topologie telle que définie ci-dessous :

Il est important de noter que les différents commutateurs présentés dans ce schéma n’ont aucune existence physique. Il sont gérés par libvirt et présentés comme des interfaces réseau sur l’hôte : généralement, elles s’appellent virbr0, virbr1, etc. Ce que cela montre cependant, c’est qu’un réseau sera composé de différents clients, et obtiendront leur configuration IP du routeur qui fait également office de serveur DHCP. Le routage de ces clients devra être modifié en conséquence, car il peuvent naturellement communiquer avec l’hôte, mais il est possible de désactiver les diverses redirections forward de la configuration du réseau virtuel. Les adresses IPv4 de la machine orion (serveur DHCP et routeur du sous-réseau) sont gérées statiquement par le serveur DHCP de Libvirt.

Pour simuler un effet de sous-réseau, il suffira d’ignorer le lien entre le sous-réseau reliant les deux clients et le machine hôte. Il est également possible, à travers quelques règles de pare-feu, d’interdire les paquets entrants et sortant depuis ou à destination des machines du sous-réseau, laissant seulement transiter les paquets depuis et à destination du sous-réseau. Il est également évident que les paquets circulant entre les machines du sous-réseau seront routées par l’hôte, et que, nécessairement, lorsque l’hôte voudra communiquer avec les machines du sous-réseau, il pourra le faire directement, puisque connecté sur le commutateur virtuel virbrint. Ce comportement n’est pas celui qui est désiré, et des règles de routage seront définies pour forcer l’hôte à communiquer avec les machines du sous-réseau via le routeur orion.

Gestion de la topologie réseau

La documentation officielle de libvirt pour le réseau est d’un grand secours avant de commencer.

Création des réseaux virtuels

La configuration des réseaux pour libvirt se fait via des documents XML stockés dans le répertoire /etc/libvirt/qemu/networks. Il est possible de les configurer manuellement si le service libvirtd est éteint, sous peine de voir les changements manuels écrasés. Des commandes spécifiques existent pour manipuler ces fichiers, virsh net-edit.

Le démarrage automatique des réseaux se fait en ajoutant un lien vers les documents XML correspondants dans /etc/libvirt/qemu/networks/autostart. Les réseaux sont démarrés par libvirt. Si des routes spécifiques doivent être configurées par NetworkManager, un service systemd doit être ajouté pour redémarrer l’interface désirée via NetworkManager.

Gestion du réseau avec libvirt

À partir d’un fichier XML décrivant un réseau, l’import de ce réseau dans libvirt se fait avec :

virsh net-define --file fichier_reseau.xml

Avant de modifier un réseau avec net-edit, il est important de le détruire :

virsh net-destroy nom_reseau

Il peut également être nécessaire de supprimer complètement un configuration de réseau :

virsh net-undefine nom_reseau

Réseau pour accès extérieur

Ce réseau existe pour lier ensemble le routeur, qui est une machine virtuelle, et l’hôte. L’adresse de l’hôte est 172.18.0.1 et l’adresse du routeur est fixe, suivant l’adresse MAC de l’interface réseau de la machine : 172.18.0.2. Les balises <forward> permettent de pouvoir accéder au réseau extérieur à partir des machines virtuelles, via le moyen indiqué.

<network>
  <name>externe</name>
  <forward mode='nat'>
    <nat>
      <port start='1024' end='65535'/>
    </nat>
  </forward>
  <bridge name='virbrext' stp='on' delay='0'/>
  <mac address='52:54:00:fe:67:60'/>
  <ip address='172.18.0.254' netmask='255.255.255.0'>
    <dhcp>
      <host mac='52:54:00:00:01:01' name='orion' ip='172.18.0.253'/>
    </dhcp>
  </ip>
</network>

En sauvegardant ce contenu dans un fichier virbrext.xml, on peut ajouter le réseau avec :

virsh net-define --file virbrext.xml

Et le démarrer avec :

virsh net-start externe

Une nouvelle interface réseau apparaît alors sur l’hôte, c’est virbrext.

Réseau interne

Pour le réseau interne, un nouveau réseau est défini pour libvirt. Il va créer une nouvelle interface, virbrint sur le réseau 192.168.123.0/24.

<network>
  <name>interne</name>
  <bridge name='virbrint' stp='on' delay='0'/>
  <mac address='52:54:00:41:62:f4'/>
  <ip address='192.168.123.254' netmask='255.255.255.0'>
    <dhcp>
      <host mac='52:54:00:00:01:02' name='orion' ip='192.168.123.253'/>
    </dhcp>
  </ip>
</network>

En sauvegardant ce contenu dans un fichier virbrint.xml, on peut ajouter le réseau avec :

virsh net-define --file virbrint.xml

Et le démarrer avec :

virsh net-start interne

Une nouvelle interface réseau apparaît alors sur l’hôte, c’est virbrint.

Création des différents clients

Création des images disque

Pour la suite, on va admettre que l’on dispose d’une image disque de CentOS qui sera le système d’exploitation des deux machines. Cette image pourra être installée en utilisant les images conçues pour l’infonuagique. Pour plus de confort et économiser de l’espace disque, je prend l’habitude de créer des instantanés externes du disque contenant CentOS pour pouvoir créer de nouvelles machines.

En considérant que ce disque est ~/.local/share/libvirt/images/originales/centos7-server-base.qcow2, on peut créer trois nouveaux disques, un pour orion, et deux autres pour deux clients, cos1 et cos2. Les commandes ci-dessous sont exécutées depuis le répertoire par défaut contenant les images pour libvirt.

qemu-img create -f qcow2 -b originales/centos7-server-base.qcow2 orion.qcow2
qemu-img create -f qcow2 -b originales/centos7-server-base.qcow2 cos1.qcow2
qemu-img create -f qcow2 -b originales/centos7-server-base.qcow2 cos2.qcow2

Trois nouvelles images de taille réduite apparaissent dans ~/.local/share/libvirt/images : cos1.qcow2, cos2.qcow2 et orion.qcow2. Ces images de disque seront utilisées pour créer les machines virtuelles.

Autorisation des périphériques virtuels pour QEMU

Par défaut, QEMU a besoin d’une autorisation pour utiliser des périphériques de type pont. Il est possible de modifier le fichier /etc/qemu/bridge.conf pour prendre en compte les nouveaux périphériques. Dans notre cas, on ajoute virbrext et virbrint.

allow virbrext
allow virbrint

Création des machines

Le routeur : orion

Pour cette machine, il est important de connecter les interfaces réseaux avec les adresses MAC renseignées précédemment dans la configuration DHCP de libvirt. Ce sont ces éléments qui feront en sorte que la machine disposera de deux adresses IP valides sur le réseau.

virt-install -n orion --description "Routeur interne" \
             --os-type=Linux --os-variant=centos7.0 \
             --ram=512 --cpu=kvm64 --vcpus=1 \
             --disk path=/home/${USER}/.local/share/libvirt/images/orion.qcow2 \
             --network bridge=virbrext,model=virtio,mac=52:54:00:00:01:01 \
             --network bridge:virbrint,model=virtio,mac=52:54:00:00:01:02 \
             --import \
             --noautoconsole
Un premier client : cos1
virt-install -n cos1 --description "CentOS 1" \
             --os-type=Linux --os-variant=centos7.0 \
             --ram=512 --cpu=kvm64 --vcpus=1 \
             --disk path=/home/${USER}/.local/share/libvirt/images/cos1.qcow2 \
             --network bridge:virbrint,model=virtio,mac=52:54:00:00:00:01 \
             --import \
             --noautoconsole
Un second client : cos2
virt-install -n cos2 --description "CentOS 2" \
             --os-type=Linux --os-variant=centos7.0 \
             --ram=512 --cpu=kvm64 --vcpus=1 \
             --disk path=/home/${USER}/.local/share/libvirt/images/cos2.qcow2 \
             --network bridge:virbrint,model=virtio,mac=52:54:00:00:00:02 \
             --import \
             --noautoconsole

Vérification de la connectivité

Adressage IPv4

Pour tester la bonne connectivité réseau entre toutes ces machines, seul un test de ping sera utilisé. L’adressage IP sera également manuel puisque aucun serveur DHCP n’est configuré sur la machine orion. Sur le réseau interne, orion dispose d’une adresse IPv4 (192.168.123.2) fixée par le serveur DHCP de libvirt.

Dans notre cas, cos1 aura l’adresse IPv4 192.168.123.3/24 et cos2 l’adresse IPv4 192.168.123.4/24. Sur les machines fonctionnant avec CentOS, pour réaliser un adressage statique manuellement avec la commande ip, il est important de désactiver temporairement NetworkManager :

systemctl stop NetworkManager

On peut donc procéder à l’adressage :

  • Sur cos1 :
ip addr add 192.168.123.3/24 dev eth0
  • Sur cos2 :
ip addr add 192.168.123.4/24 dev eth0

Test des connexions

Dans notre configuration, les machines cos1, cos2 et orion peuvent lancer un ping entre elles. Aucune ne peut pas contre se connecter à la machine hôte via le réseau interne (donc communiquer avec l’adresse 192.168.123.1 autrement que via la chaîne FORWARD − généralement géré automatiquement par firewalld et libvirt).

Sur chaque machine, il est possible de procéder aux tests ci-dessous. Le message ICMP renvoyé par l’hôte est « Destination Host Prohibited ». La connexion entre ce sous-réseau et l’hôte est interdite, ce qui est parfaitement conforme à la topologie !

[root@localhost ~]# ping 192.168.123.1
PING 192.168.123.1 (192.168.123.1) 56(84) bytes of data.
From 192.168.123.1 icmp_seq=1 Destination Host Prohibited
^C
--- 192.168.123.1 ping statistics ---
1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0ms


[root@localhost ~]# ping 192.168.123.2
PING 192.168.123.2 (192.168.123.2) 56(84) bytes of data.
64 bytes from 192.168.123.2: icmp_seq=1 ttl=64 time=0.075 ms
^C
--- 192.168.123.2 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 999ms


[root@localhost ~]# ping 192.168.123.3
PING 192.168.123.3 (192.168.123.3) 56(84) bytes of data.
64 bytes from 192.168.123.3: icmp_seq=1 ttl=64 time=1.13 ms
^C
--- 192.168.123.3 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 1001ms

[root@localhost ~]# ping 192.168.123.4
PING 192.168.123.4 (192.168.123.4) 56(84) bytes of data.
64 bytes from 192.168.123.4: icmp_seq=1 ttl=64 time=1.09 ms
^C
--- 192.168.123.4 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 1001ms

Et encore…

Quelques modifications restent à faire pour se conformer pleinement au schéma décrit au début de ce document :

  • les paquets à destination des machines du sous-réseau doivent uniquement transiter par le routeur orion, et ne pas accéder aux machines via l’interface virbrint de la machine hôte. Cette situation détaillée dans la page dédiée au routage IP. Il s’agit de réaliser un routage basé sur l’origine des paquets ;
  • le routeur doit effectivement router les paquets depuis et à destination des machines du sous-réseau, et mettre en place de la translation d’adresses. On pourra utiliser directement firewalld ou IPTables ;
  • autoriser le routage de paquets dans le sens hôte → sous-réseau en ajoutant un règle dans le pare-feu avec firewalld ;
  • la machine hôte ne doit pas être accessible depuis les deux machines du sous-réseau. On utilisera pour cela firewalld qui est le logiciel de pare-feu par défaut sur le système d’exploitation. On l’utilisera pour bloquer les requêtes à destination de l’hôte depuis le sous-réseau ;
  • configurer un serveur DHCP ;
  • configurer un serveur DNS.
administration-systemes/gestion-de-parc-virt.txt · Dernière modification: 2018/04/17 13:22 par Guillaume Bernard