1. Introduction

Le projet Webvirtcloud vous permettra de gérer facilement vos machines virtuelles (VM) sous hyperviseur KVM depuis une interface Web. Webvirtcloud pourra être installé aussi bien sur la machine hébergeant les VM que sur une autre machine. Il sera possible de gérer plusieurs hyperviseurs KVM depuis la même interface.

Webvirtcloud est le successeur de WebvirtManager, basé lui-même sur Virt-Manager.

Ce projet d'Anatoliy Guskov est disponible sur github.

Webvirtcloud s’appuie sur libvirt, qui permet de piloter les hyperviseurs KVM, Xen, VMWare, Hyper-V, VirtualBox, ainsi que les gestionnaires de conteneurs LXC et OpenVZ. Webvirtcloud est développé en Python et utilise le framework Django.

Image non disponible

2. Installation

Nos tests seront effectués depuis une machine exécutant la distribution Linux Debian 9 Stretch.

2-1. Installation des prérequis

Il nous faudra tout d'abord le logiciel git pour télécharger les sources.

Webvirtcloud repose sur les paquets libvirt-daemon-system, python-libvirt et novnc pour l'affichage des écrans des VM.

La procédure d’installation proposée sur github utilise nginx.

J'ai choisi de ne pas utiliser Nginx, car il est tout à fait possible d'utiliser directement Django sans serveur Web.

Je m’appuierai par contre sur Apache, que je connais mieux que Nginx afin de pouvoir appeler le serveur Django via un proxy, en paramétrant Django pour n'écouter que sur l'interface de boucle locale (127.0.0.1).

Installation des paquets :

 
Sélectionnez
apt-get install kvm libvirt-daemon-system git python-libvirt novnc

Afin de ne pas travailler avec les droits root, nous créons un compte utilisateur dédié :

 
Sélectionnez
root@Debian:~# adduser cloud
Ajout de l'utilisateur « cloud » ...
Ajout du nouveau groupe « cloud » (1000) ...
Ajout du nouvel utilisateur « cloud » (1000) avec le groupe « cloud » ...
Création du répertoire personnel « /home/cloud »...
Copie des fichiers depuis « /etc/skel »...
Entrez le nouveau mot de passe UNIX :
Retapez le nouveau mot de passe UNIX :
passwd: password updated successfully
Changing the user information for cloud
Enter the new value, or press ENTER for the default
        Full Name []:
        Room Number []:
        Work Phone []:
        Home Phone []:
        Other []:
Cette information est-elle correcte ? [O/n]o

Nous ajoutons ensuite le nouvel utilisateur aux groupes kvm, libvirt et libvirt-qemu :

 
Sélectionnez
usermod -aG kvm,libvirt,libvirt-qemu cloud

Nous modifions ensuite le fichier /etc/libvirt/libvirtd.conf. Nous dé-commentons la ligne unix_sock_goupr = "libvirt" et unix_sock_rw_perms = "770", puis remplaçons l'utilisateur libvirt par cloud. Finalement, pour prendre en compte ces changements, nous redémarrons le service libvirtd :

 
Sélectionnez
service libvirtd restart

Ensuite, nous nous connectons avec l’utilisateur souhaité (« cloud » dans notre exemple).

2-2. Installation de Webvirtcloud

Nous récupérons les sources grâce à git :

 
Sélectionnez
git clone git://github.com/retspen/webvirtcloud.git

Nous nous plaçons ensuite dans le dossier webvirtcloud :

 
Sélectionnez
cd webvirtcloud

Puis procédons à l'installation des prérequis python comme indiqué dans la documentation :

 
Sélectionnez
pip install -r conf/requirements.txt

La commande devrait afficher ceci :

 
Sélectionnez
Collecting Django==1.11.21 (from -r conf/requirements.txt (line 1))
  Downloading https://files.pythonhosted.org/packages/a2/84/9f66e359ba8e63cf9b54f6815ed55188dda43cd1cc951a8bb95542dee956/Django-1.11.21-py2.py3-none-any.whl (6.9MB)
    100% |████████████████████████████████| 7.0MB 67kB/s
Collecting websockify==0.8.0 (from -r conf/requirements.txt (line 2))
  Downloading https://files.pythonhosted.org/packages/66/48/2e35166c957639ddb4cb11ce9783ad3ee9bf96f220354ce2684ee95feeb7/websockify-0.8.0.tar.gz (234kB)
    100% |████████████████████████████████| 235kB 38kB/s
Collecting gunicorn==19.9.0 (from -r conf/requirements.txt (line 3))
  Downloading https://files.pythonhosted.org/packages/8c/da/b8dd8deb741bff556db53902d4706774c8e1e67265f69528c14c003644e6/gunicorn-19.9.0-py2.py3-none-any.whl (112kB)
    100% |████████████████████████████████| 122kB 164kB/s
Collecting lxml==4.2.5 (from -r conf/requirements.txt (line 4))
  Downloading https://files.pythonhosted.org/packages/e5/14/f4343239f955442da9da1919a99f7311bc5627522741bada61b2349c8def/lxml-4.2.5-cp27-cp27mu-manylinux1_x86_64.whl (5.8MB)
    100% |████████████████████████████████| 5.8MB 75kB/s
Collecting libvirt-python==5.3.0 (from -r conf/requirements.txt (line 5))
  Downloading https://files.pythonhosted.org/packages/77/85/552efa34812f9b7f18e35f9eac1b680df54bed302ddfd7d08915a8a75906/libvirt-python-5.3.0.tar.gz (193kB)
    100% |████████████████████████████████| 194kB 78kB/s
Collecting pytz (from -r conf/requirements.txt (line 6))
  Downloading https://files.pythonhosted.org/packages/87/76/46d697698a143e05f77bec5a526bf4e56a0be61d63425b68f4ba553b51f2/pytz-2019.2-py2.py3-none-any.whl (508kB)
    100% |████████████████████████████████| 512kB 169kB/s
Collecting rwlock (from -r conf/requirements.txt (line 7))
  Downloading https://files.pythonhosted.org/packages/4b/1b/333059f7a18180ded504e799b9fea96e9ad7ed6af74039adf542fb93e433/rwlock-0.0.7.tar.gz
Collecting numpy (from websockify==0.8.0->-r conf/requirements.txt (line 2))
  Downloading https://files.pythonhosted.org/packages/1f/c7/198496417c9c2f6226616cff7dedf2115a4f4d0276613bab842ec8ac1e23/numpy-1.16.4-cp27-cp27mu-manylinux1_x86_64.whl (17.0MB)
    100% |████████████████████████████████| 17.0MB 36kB/s
Building wheels for collected packages: websockify, libvirt-python, rwlock
  Running setup.py bdist_wheel for websockify ... done
  Stored in directory: /home/cloud/.cache/pip/wheels/67/ec/b2/08efd6524556d805fb2df3366bd2eb1e57490e015ab9835a0a
  Running setup.py bdist_wheel for libvirt-python ... error
  Complete output from command /usr/bin/python -u -c "import setuptools, tokenize;__file__='/tmp/pip-build-UPuuMF/libvirt-python/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" bdist_wheel -d /tmp/tmpsxy7vDpip-wheel- --python-tag cp27:
  running bdist_wheel
  running build
  Traceback (most recent call last):
    File "<string>", line 1, in <module>
    File "/tmp/pip-build-UPuuMF/libvirt-python/setup.py", line 366, in <module>
      "Programming Language :: Python :: 3",
    File "/usr/lib/python2.7/distutils/core.py", line 151, in setup
      dist.run_commands()
    File "/usr/lib/python2.7/distutils/dist.py", line 953, in run_commands
      self.run_command(cmd)
    File "/usr/lib/python2.7/distutils/dist.py", line 972, in run_command
      cmd_obj.run()
    File "/usr/lib/python2.7/dist-packages/wheel/bdist_wheel.py", line 179, in run
      self.run_command('build')
    File "/usr/lib/python2.7/distutils/cmd.py", line 326, in run_command
      self.distribution.run_command(command)
    File "/usr/lib/python2.7/distutils/dist.py", line 972, in run_command
      cmd_obj.run()
    File "/tmp/pip-build-UPuuMF/libvirt-python/setup.py", line 147, in run
      check_minimum_libvirt_version()
    File "/tmp/pip-build-UPuuMF/libvirt-python/setup.py", line 40, in check_minimum_libvirt_version
      spawn([get_pkgcfg(),
    File "/tmp/pip-build-UPuuMF/libvirt-python/setup.py", line 36, in get_pkgcfg
      raise Exception("pkg-config binary is required to compile libvirt-python")
  Exception: pkg-config binary is required to compile libvirt-python

Nous pouvons voir une erreur liée à libvirt-python. Ce paquet ayant déjà été installé via apt-get, je supprime l’entrée libvirt-python==5.3.0 dans le fichier conf/requirements.txt.

Je relance ensuite la commande :

 
Sélectionnez
pip install -r conf/requirements

Collecting Django==1.11.21 (from -r conf/requirements.txt (line 1))
  Using cached https://files.pythonhosted.org/packages/a2/84/9f66e359ba8e63cf9b54f6815ed55188dda43cd1cc951a8bb95542dee956/Django-1.11.21-py2.py3-none-any.whl
Collecting websockify==0.8.0 (from -r conf/requirements.txt (line 2))
Collecting gunicorn==19.9.0 (from -r conf/requirements.txt (line 3))
  Using cached https://files.pythonhosted.org/packages/8c/da/b8dd8deb741bff556db53902d4706774c8e1e67265f69528c14c003644e6/gunicorn-19.9.0-py2.py3-none-any.whl
Collecting lxml==4.2.5 (from -r conf/requirements.txt (line 4))
  Using cached https://files.pythonhosted.org/packages/e5/14/f4343239f955442da9da1919a99f7311bc5627522741bada61b2349c8def/lxml-4.2.5-cp27-cp27mu-manylinux1_x86_64.whl
Collecting pytz (from -r conf/requirements.txt (line 5))
  Using cached https://files.pythonhosted.org/packages/87/76/46d697698a143e05f77bec5a526bf4e56a0be61d63425b68f4ba553b51f2/pytz-2019.2-py2.py3-none-any.whl
Collecting rwlock (from -r conf/requirements.txt (line 6))
Collecting numpy (from websockify==0.8.0->-r conf/requirements.txt (line 2))
  Using cached https://files.pythonhosted.org/packages/1f/c7/198496417c9c2f6226616cff7dedf2115a4f4d0276613bab842ec8ac1e23/numpy-1.16.4-cp27-cp27mu-manylinux1_x86_64.whl
Installing collected packages: pytz, Django, numpy, websockify, gunicorn, lxml, rwlock
Successfully installed Django-1.11.21 gunicorn-19.9.0 lxml-4.2.5 numpy-1.16.4 pytz-2019.2 rwlock-0.0.7 websockify-0.8.0

Nous recopions ensuite le fichier de configuration par défaut :

 
Sélectionnez
cp webvirtcloud/settings.py.template webvirtcloud/settings.py

Il va être nécessaire de créer une « secret key » via le code python :

 
Sélectionnez
>>>
import random, string
haystack = string.ascii_letters + string.digits + string.punctuation
print(''.join([random.SystemRandom().choice(haystack) for _ in range(50)]))

la sortie console sera à mettre dans la ligne SECRET_KEY du fichier webvirtcloud/settings.py comme dans l’exemple ci-dessous :

 
Sélectionnez
SECRET_KEY = ‘isY~{v6T=Hx`QU;K781-[_RCPf^.t3M50RRrlym]ciJw8seby"’

Création de la base qui servira à stocker les données de Webvirtcloud :

 
Sélectionnez
./manage.py migrate

Sortie console :

 
Sélectionnez
Operations to perform:
  Apply all migrations: accounts, admin, auth, computes, contenttypes, create, instances, logs, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying computes.0001_initial... OK
  Applying instances.0001_initial... OK
  Applying accounts.0001_initial... OK
  Applying accounts.0002_auto_20150325_0846... OK
  Applying accounts.0003_usersshkey... OK
  Applying accounts.0004_userattributes... OK
  Applying accounts.0005_userattributes_can_clone_instances... OK
  Applying accounts.0006_userattributes_max_disk_size... OK
  Applying accounts.0007_auto_20160426_0635... OK
  Applying accounts.0004_userinstance_is_vnc... OK
  Applying accounts.0008_merge... OK
  Applying accounts.0009_auto_20171026_0805... OK
  Applying accounts.0010_auto_20180625_1236... OK
  Applying accounts.0011_auto_20180625_1313... OK
  Applying accounts.0012_auto_20180625_1331... OK
  Applying accounts.0013_auto_20180625_1358... OK
  Applying accounts.0014_auto_20180808_1436... OK
  Applying accounts.0015_auto_20180808_1449... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying computes.0002_compute_details... OK
  Applying create.0001_initial... OK
  Applying create.0002_auto_20150325_0921... OK
  Applying instances.0002_instance_is_template... OK
  Applying instances.0003_instance_created... OK
  Applying instances.0004_auto_20180724_1136... OK
  Applying logs.0001_initial... OK
  Applying logs.0002_auto_20150316_1420... OK
  Applying logs.0003_auto_20150518_1855... OK
  Applying sessions.0001_initial... OK

Ceci va créer une base de données SQLite dans le fichier db.sqlite3.

Nous pouvons maintenant lancer le serveur :

 
Sélectionnez
./manage.py runserver 0:8000

Sortie console :

 
Sélectionnez
Performing system checks...

System check identified no issues (0 silenced).
August 24, 2019 - 09:00:59
Django version 1.11.21, using settings 'webvirtcloud.settings'
Starting development server at http://192.168.1.200:8000/
Quit the server with CONTROL-C.

3. Lancement de l’interface graphique

L'interface graphique est maintenant accessible via l'adresse :http://votre_adresse_ip:8000.

Vous aurez l’écran suivant :

Image non disponible

Le login et le mot de passe par défaut sont admin:admin.

Vous aurez ensuite l’écran suivant :

Image non disponible

Le warning précise qu'il n'y a pas d'instance dans l'interface de gestion.

Nous avons une barre de menu principal contenant :

  • Instances : gestion des différentes VM ;
  • Computes : réglage de tous les hyperviseurs gérés ;
  • Users : gestion des utilisateurs ;
  • Logs : consultation des logs généraux.

Commençons par modifier le mot de passe par défaut en cliquant sur Users, présent dans la partie supérieure de l’interface :

Image non disponible

Ceci affichera l’écran suivant :

Image non disponible

Cliquer sur le nom d’utilisateur va afficher les instances auxquelles il a accès, ce qui nous sera inutile pour le moment.

La modification se fera en cliquant sur la roue dentée Image non disponible qui ouvrira la fenêtre suivante :

Image non disponible

Vous serez obligé de renseigner les champs « Max instances », « Max cpus » « Max memory » et « Max disk size » pour pouvoir valider les changements.

Une fois le mot de passe modifié, le clic sur Edit validera le nouveau mot de passe et procédera automatiquement à une déconnexion. Il faudra donc se reconnecter en renseignant le nouveau mot de passe. Vous pouvez bien entendu créer un utilisateur avec un autre nom, en cochant « is staff », « is supervisor », puis après connexion sur ce nouvel utilisateur, supprimer celui d’origine. Vous aurez alors un compte administrateur avec le nom de votre choix.

4. Computes

WebvirtCloud peut gérer plusieurs hyperviseurs, il vous faudra créer un connecteur par serveur, connecteur qui sera appelé Compute.

Dans le cas d’une gestion de plusieurs hyperviseurs, chaque Compute représentera un de ceux-ci.

Dans notre cas de figure, l’hyperviseur étant sur la même machine, nous créerons un connecteur local.

4-1. Création d'un connecteur local

Nous cliquons donc sur « Computes » dans la barre supérieure :

Image non disponible

L’écran des Computes nous affiche un avertissement indiquant qu’il n’y a aucun Compute. Nous cliquons sur le Image non disponible .

L’écran « Add Connection » s’affiche alors et nous cliquons sur l’onglet Local Socket :

Image non disponible

Nous donnons à notre connecteur le nom cnx_srv1 par exemple. Le champ « Details » doit être renseigné sous peine d’annulation de la procédure.

Après ajout, l’interface nous renvoie sur l’écran Compute dans lequel nous pouvons voir notre nouveau connecteur :

Image non disponible
 

Nous aurions pu également créer un Compute via une connexion SSH, comme nous le verrons dans le prochain chapitre.

Pour continuer, il va nous falloir cliquer sur cnx_srv1, ceci déclenchera l’affichage de l’écran suivant :

Image non disponible

Nous pouvons voir un résumé des spécifications de la machine, avec les versions Qemu et libvirt, ainsi que des graphiques sur les performances de la machine.

Pour continuer, nous nous intéressons à l’entrée « Overview » de la barre supérieure. C’est le menu permettant d’accéder aux réglages nécessaires :

Image non disponible

Nous aurons les options suivantes :

  • Instances (une instance est une machine virtuelle) ;
  • Storages ;
  • Networks ;
  • Interfaces ;
  • NWFilters ;
  • Secrets.

Nous reviendrons plus tard sur les différentes entrées du menu.

Nous ne pourrons pas créer de VM sans effectuer des réglages supplémentaires. Il faudra au minimum avoir un espace de stockage (storage) et un network (réglage réseau).

4-2. Connecteur compute via SSH

Créer un connecteur SSH est indispensable si l'hyperviseur est sur une autre machine, facultatif dans le cas contraire.

Il reste pertinent de faire une connexion SSH, ceci permettant de déplacer l'interface webvirtcloud sur une autre machine.

Depuis l'utilisateur utilisé pour Webvircloud, nous commençons par créer une paire clé publique/clé privée avec la commande ssh-keygen :

 
Sélectionnez
$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/cloud/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/cloud/.ssh/id_rsa.
Your public key has been saved in /home/cloud/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:RgvrHWfPnz6PiniTRaTL0AFHFoR6xWp/cRZb6Q1RJc8 cloud@Debian
The key's randomart image is:
+---[RSA 2048]----+
|        .**.  oo=|
|        .o+ . o=.|
|      ...+ +  .=E|
|      .+=.o o +..|
|      .oS+oo +   |
|     . o ++oo    |
|      . .  +o    |
|         .+. ..o |
|        .....o=o.|
+----[SHA256]-----+

Utiliser une passphrase empêchera la connexion depuis l'interface.

Nous copions ensuite la clef publique sur l'hyperviseur (dans notre exemple srv1.local) :

 
Sélectionnez
$ ssh-copy-id cloud@srv1.local
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/cloud/.ssh/id_rsa.pub"
The authenticity of host 'srv1.local (192.168.1.200)' can't be established.
ECDSA key fingerprint is SHA256:LLALxAyQlZLXlVtPSyTrOkUaTKKC+C0UCDAQKrWTuMI.
Are you sure you want to continue connecting (yes/no)? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
cloud@srv1.local's password:

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'cloud@srv1.local'"
and check to make sure that only the key(s) you wanted were added.

Il ne reste plus qu’à tester en effectuant une connexion :

 
Sélectionnez
$ ssh cloud@srv1.local

La connexion devrait s’établir sans nécessiter de mot de passe.

Dans mon exemple, j'ai utilisé la commande ssh-copy-id sur la même machine, de façon à rendre la configuration indépendante de celle-ci, en utilisant le FQDN. Il sera donc possible de déplacer Webvirtcloud sur une autre machine sans changer aucun réglage.

5. Storage

Il va nous falloir créer des storage, que nous appellerons aussi espace de stockage ou datastore. Nous en aurons un pour le stockage des disques de VM, et un autre pour le stockage des fichiers ISO.

Un storage est un point d'entrée vers un espace de stockage définissant le type de données et où les stocker.

Webvirtcloud propose les types de storage suivants :

  • DIR : point d'entrée vers un répertoire ou point de montage sur l'hyperviseur ;
  • LVM : accès à un volume logique LVM (utile pour faciliter la migration à chaud) ;
  • CEPH : espace de stockage réparti Ceph ;
  • NETFS : point de montage réseau (NFS, SMB/CIFS, GlusterFS) ;
  • ISO : point de montage réservé aux images disques ISO.

5-1. Création d'un storage/datastore

Entrons dans le menu Storage :

Image non disponible

Créons un datastore en cliquant sur le Image non disponible  :

Image non disponible

Nous utiliserons dans un premier temps les options DIR et ISO. Les autres options seront vues ultérieurement.

Nous commençons par créer un dossier pour les images que nous nommerons srv1_images dans le dossier de l’utilisateur webvirtcloud (dans notre cas utilisateur cloud) le dossier proposé par défaut est /var/lib/libvrt/images.

Écran après création de celui-ci :

Image non disponible

Une indication nous informe que le datastore ne contient aucun volume.

Nous créons également un datastore pour les fichiers ISO :

Image non disponible

Il n’est pas possible de choisir un nom différent.

En cliquant sur Storages, nous pourrons voir nos datastores nouvellement créés indiquant l’espace disque ainsi que le nombre de volumes qui leur sont alloués  :

Image non disponible

Cliquer sur le nom du datastore nous permettra de retourner dans l’écran de détail de celui-ci (comme sur l’image après création).

Webvirtcloud ne va pas créer de lui-même le dossier de destination, celui-ci devra être existant, sinon le datastore sera déclaré, mais désactivé.

Vous aurez un message d'erreur.

Exemple sur un dossier inexistant :

Image non disponible

Par contre, le datastore est créé, visible après rafraîchissement de la page :

Image non disponible

Nous voyons que le datastore est en rouge (ce qui signifie qu’il est suspendu).

Pour corriger le problème, il suffira de créer le dossier depuis la console, puis entrer dans le datastore et le démarrer en cliquant sur « start »  et « Enable » au niveau du champ Autostart pour que le datastore reste actif au prochain redémarrage :

Image non disponible

À ce stade, le datastore est utilisable et apparaîtra en vert dans le menu Storages.

La création d’un datastore sur un dossier existant ne posera pas de problèmes, l’affichage du contenu de celui-ci sera effectif après rafraîchissement de l'écran. Les éventuels sous-dossiers apparaîtront dans la liste avec « dir » spécifié dans la colonne Format, mais l’accès au contenu ne sera pas possible. Les éventuels fichiers n’étant pas des fichiers image seront également affichés et comptés dans la taille du volume au niveau de la liste des datastores mais ne seront pas exploitables. Vous pourrez par contre les effacer depuis l’icône suppression.

Image non disponible

Des fichiers ajoutés manuellement dans un datastore apparaîtront après un simple rafraîchissement de la page web.

Les fichiers de définition des datastores sont dans /etc/libvirt/qemu/storage.

5-2. Suppression d'un storage/datastore

Avant de supprimer un datastore, il faut le stopper :

Image non disponible

Après avoir stoppé le datastore, l’option delete apparaîtra :

Image non disponible

Vous aurez une demande de confirmation.

La suppression du datastore n’effacera pas son contenu. Si vous le recréez de la même façon, son contenu réapparaîtra. Il n'y aura pas non plus d'incidence sur des VM utilisant des données dans le datastore supprimé.

6. Gestion réseau

Le menu Interfaces va afficher les différentes cartes physiques, dans notre cas une seule :

Image non disponible

L’accès à la carte ne permet que de stopper l’interface, il ne permet pas de modifier les réglages de celle-ci :

Image non disponible

Une interface stoppée n’est pas modifiable. Il est possible de changer les réglages en la supprimant, puis en la recréant avec le Image non disponible.

Pensez que si vous arrêtez la carte réseau qui est utilisée pour l'interface Web, vous perdez l'accès à l'interface de Webvirtcloud.

Il sera au moins nécessaire d'activer un network (au moins celui par défaut) pour pouvoir utiliser le réseau dans une VM.

6-1. Menu networks

Il y a un réseau par défaut accessible depuis le menu Networks nommé « default » sur l’interface br0 (interface Bridge). Il est relié à la première carte réseau et désactivé (on voit qu'il est désactivé, car il apparaît en rouge) :

Image non disponible

Voici les réglages du réseau par défaut (réglages accessibles en cliquant sur le nom default) :

Image non disponible

Il faut au moins activer ce réglage pour avoir la possibilité d’accéder au réseau depuis les VM.

Nous pouvons voir qu’il s’agit d’un réglage NAT, c’est à dire d’un fonctionnement équivalent à un routeur ou une BOX, l'hôte faisant office de routeur.

Il est possible de modifier la plage du DHCP, mais pas de modifier son adresse.

Cliquer sur start va activer le réseau.

Une fois celui-ci activé, il sera possible d’indiquer une adresse fixe en cliquant sur le Image non disponible apparu au niveau de « Fixed Address ». Il faudra alors spécifier un nom, l’adresse IP à réserver et l’adresse MAC :

Image non disponible

6-2. Modes de fonctionnement réseau

La gestion réseau de Webvirtcloud permet les configurations suivantes :

  • NAT : mode précédemment expliqué ;
  • ROUTE : le routed mode est assimilable au NAT sans translation, les VM sont sur leur réseau, l’hôte servant de passerelle ;
  • ISOLATE : les VM peuvent communiquer entre elles, mais sont isolées du réseau physique ;
  • BRIDGE : le mode Bridge ou pont permet le partage de la carte physique entre l’hôte et les différentes VM, chaque machine ayant sa propre adresse IP sur le même réseau que l'hôte.

Le NAT est le mode par défaut.

Tous les modes sauf le mode BRIDGE vous demanderont le sous-réseau souhaité avec fourniture ou non de DHCP. Le mode BRIDGE vous proposera d’activer Open vSwitch : un switch virtuel pouvant être distribué.

Création d'un bridge br1 dans /etc/network/interface :

Ajout de br1 sur la ligne auto :

 
Sélectionnez
auto lo eth0 eth1 br1

Modification de la ligne iface correspondant à la carte réseau :

 
Sélectionnez
iface eth0 inet manual

Ajout de l'interface br1 :

 
Sélectionnez
iface br1 inet dhcp
bridge_ports eth0

Redémarrage ensuite du service réseau :

 
Sélectionnez
service networking restart
Image non disponible
Image non disponible

Le mode BRIDGE ne propose pas de DHCP, cela est logique, la VM se comportant comme n’importe quelle machine du réseau à ce niveau et pourra exploiter un DHCP présent sur le réseau si nécessaire.

Les fichiers de définition de réseau se trouvent dans /etc/libvirt/qemu/networks.

7. Création d'une VM

Prérequis : avoir lu le chapitre sur les datastores et le réseau et avoir mis ceci en place.

7-1. Ajout d'un ISO

Nous commençons par télécharger le fichier ISO que nous utiliserons pour l'installation de notre VM. Pour cela, nous nous rendons dans le datastore iso :

Image non disponible
Image non disponible
Image non disponible
 

Nous aurons alors un écran de sélection du fichier :

Image non disponible

Le clic sur « upload », après la sélection du fichier, va déclencher le chargement sans barre de progression. Il faut donc attendre que la fenêtre du navigateur rende la main. Il y a un risque de time out.

Le fichier apparaîtra ensuite dans la liste :

Image non disponible

7-2. Ajout d'une image disque dans le datastore

Image non disponible
Image non disponible

Vous aurez alors à définir le nom de l’image disque, son format, sa capacité (l’unité de mesure est le Gigaoctet). Vous pouvez ou non cocher la case « metadata », celle-ci servant à la pré-allocation ou non des métadonnées.

Image non disponible

Les formats possibles sont :

  • qcow2 : format image disque Qemu (Qemu Copy On Write) ;
  • qcow : ancien format image disque Qemu incompatible avec qcow2, utilisez plutôt qcow2 ;
  • raw : format image brute.

Si vous souhaitez un disque dynamique, il vous faudra utiliser le format qcow2.

7-2-1. Disque dynamique/disque fixe

Si vous souhaitez un disque à taille fixe, utilisez le format raw. Celui-ci créera un fichier image de la taille réelle de celle-ci. Le format qcow2 créera un disque dynamique, qui grossira au fur et à mesure de son utilisation jusqu'à hauteur de la taille qui lui a été allouée. Seul le format qcow2 vous permettra d’effectuer des snapshots que nous verrons ultérieurement.

Une fois le ficher image disque créé, il apparaît dans le datastore :

Image non disponible

L’extension est automatiquement ajoutée au fichier (.qcow2 pour un fichier Qcow2 .img pour un format raw).

Depuis la console, la commande file nous retournera le type de fichier.

Exemple de fichier .raw :

 
Sélectionnez
file test.img
test.img: data

Exemple de fichier qcow :

 
Sélectionnez
file test-VM-disk.qcow2
test-VM-disk.qcow2: QEMU QCOW Image (v3), 10737418240 bytes

La commande qemu-img permet d’obtenir des informations supplémentaires sur le fichier .qcow :

 
Sélectionnez
qemu-img info test-VM-disk.qcow2
image: test-VM-disk.qcow2
file format: qcow2
virtual size: 10G (10737418240 bytes)
disk size: 1.8M
cluster_size: 65536
Format specific information:
    compat: 1.1
    lazy refcounts: true
    refcount bits: 16
    corrupt: false

Maintenant que nous avons une image disque et que l'ISO d'installation est prêt, nous pouvons créer notre première machine virtuelle.

7-3. Première machine virtuelle

Image non disponible

Il nous sera demandé le compute (pour rappel l’hyperviseur) où créer la machine virtuelle. L'écran suivant sera affiché même dans le cas où un seul hyperviseur est présent :

Image non disponible


Vous aurez ensuite l’écran suivant :

Image non disponible

Vous aurez le choix entre :

  • Flavor : templates par défaut ;
  • Custom: l’option que nous utiliserons ;
  • TemplateTemplate de VM: pour créer un template plutôt qu’une VM ;
  • XML: pour intégrer un fichier XML de définition de VM préexistant.

La liste présente semble être une liste de templates que je n’ai pas réussi à faire fonctionner.

Pour créer une machine virtuelle sans template, cliquez sur l’onglet « Custom » :

Image non disponible

Il vous faudra :

  • donner un nom à votre machine virtuelle (pas d’espaces ni de caractères spéciaux) ;
  • choisir le nombre de VCPU (1 par défaut) ;
  • définir la capacité mémoire ;
  • sélectionner le disque dur dans le menu déroulant HDD

    • il faudra tout d’abord sélectionner le pool (le datastore),
    • puis l’image disque dans le pool sélectionné ;

      • Image non disponible
      • Image non disponible
  • changer éventuellement le mode de cache disque ;

  • choisir le réseau (sans sélection : pas de réseau, possibilité de sélectionner plusieurs réseaux sur plusieurs cartes virtuelles) ;

  • sélectionner le filtrage réseau NWFilter ;

  • choisir le type de carte vidéo (VGA, Cirrus, vmvga, qxi, virtio) ;

  • définir un mot de passe d’accès à la console ;

  • choisir le type d’accès console (localhost, ou toutes interfaces).

Vous pourrez affecter plusieurs images disques à la VM :

Image non disponible

Sur les écrans ci-dessus, nous pouvons voir qu’il y a deux menus déroulants, le premier affichant « disk ». Il est possible de sélectionner :

  • disk ;
  • cdrom ;
  • floppy ;
  • LUN (numéro d'identification d'une unité de stockage SAN).

Il n’est pas nécessaire d’utiliser cette fonctionnalité pour connecter un cd-rom, nous le verrons ultérieurement.

Le second sous-menu permet de sélectionner le type de pilote :

  • virtio (par défaut) ;
  • ide ;
  • fdc ;
  • scsi ;
  • usb.

Pour une utilisation standard, les réglages par défaut conviendront.

Il est également possible d’ajouter plusieurs interfaces réseau virtuelles :

Image non disponible

Nous pouvons voir que la carte réseau installée est sur l’interface physique eth0 de l’hôte dans le réseau nommé LAN en utilisant la même interface que le réseau par défaut mais en mode bridge. Une carte physique pourra être reliée à plusieurs VM en utilisant un Network. Plusieurs Network peuvent être utilisés avec une ou plusieurs cartes réseau physiques.

Le choix du type d’interface graphique dépendra de l’usage. En cas d’utilisation d’une GUI, l’utilisation de virtio avec les additions invitées (pour la paravirtualisation) dans la VM me paraît le plus pertinent.

Après validation, l’interface nous envoie directement sur l’écran de contrôle de notre VM :

Image non disponible

Le fichier de définition de la VM sera stocké dans /etc/libvirt/qemu.

Avant de démarrer notre VM, il va nous falloir y lier l’image ISO. Nous allons pour ceci dans l’onglet Settings→disks :

Image non disponible
 

Nous pouvons voir l’image disque liée à la VM. Dans CDROM1 apparaît Archlinux, l'ISO chargé précédemment, le menu déroulant permettant la sélection dans la liste disponible. Nous cliquons sur « Mount ». Cela aura pour effet de lier l’ISO à la VM, l’écran deviendra :

Image non disponible

En cliquant sur les Image non disponible , il est possible d’ajouter un lecteur de CDROM ou une image disque.

Pour les disques durs, cela servira à ajouter un disque supplémentaire à la VM. Il n’est pas possible de créer une VM sans avoir d’abord créé une image disque dans le datastore ou lié celle-ci à un disque déjà existant lors de la création de celle-ci.

Cliquer sur le Image non disponible au niveau du CDROM ajoutera un lecteur CDROM virtuel :

Image non disponible

7-4. Démarrage de la VM

Celui-ci se fera tout simplement depuis l’onglet Power, bouton «Power On» :

Image non disponible

Le statut « Off « visible en haut va passer en suspend, puis Running. Le bouton « Power On » va passer en « Power Off ».

Image non disponible

Pour avoir accès à l’écran de la VM, il nous faudra cliquer sur l’onglet « Access ». Nous pourrons alors cliquer sur « Console ». Ceci va ouvrir un écran NoVNC (NoVNC est un client VNC pour navigateur Web), non opérationnel dans l'immédiat.

Image non disponible

Pourquoi cela ne fonctionne-t-il pas ? Car WebvirtCloud est conçu pour dialoguer en VNC sur le port 6080. Il faut donc faire une redirection de ce port vers le port standard VNC 5900.

Ceci sera fait avec le logiciel websockify, fourni avec WebvirtCloud. Nous l'activerons de la façon suivante :

 
Sélectionnez
 websockify 6080 127.0.0.1:5900 -D

WebSocket server settings:
  - Listen on :6080
  - Flash security policy server
  - No SSL/TLS support (no cert file)
- Backgrounding (daemon)

Websockify attend le port source, l'adresse et le port de destination. L'option -D permet de démarrer en démon. Il est également possible de passer en SSL/TLS en fournissant en paramètre les fichiers de certificat.

Une fois websockify lancé, l’écran VNC fonctionnera :

Image non disponible

Il vous sera possible de passer en plein écran et d’envoyer le fameux ctrl-alt-suppr.

Le mode plein écran, dans une VM avec interface graphique, ne sera optimal qu'avec une résolution correctement paramétrée nécessitant en général les additions invitées.

Il est possible d’utiliser un logiciel VNC externe plutôt que le VNC fourni en interface Web et donc de ne pas utiliser Websockify si vous renseignez le port 6080 dans le client VNC.

Depuis l’écran principal (clic sur WebvirtCloud ou Instance), nous pouvons voir notre VM :

Image non disponible

Nous avons un accès rapide à l’état des VM (une seule dans notre exemple) ainsi qu’aux fonctionnalités principales :

  • démarrage

Image non disponible

  • suspension

Image non disponible

  • arrêt

Image non disponible

  • Power Cycle (un reboot)

Image non disponible

  • console

Image non disponible

Le clic sur le nom de la VM renvoie sur l’écran de réglage de celle-ci, l'écran affiché lors de la création. Le prochain chapitre Réglages VMRéglages VM va décrire les différentes possibilités de configuration.

7-5. Template de VM

Un template de VM est un modèle. Chaque VM créée depuis un template partagera, lors de sa déclaration, la définition ainsi que le disque. Celui-ci se créera comme une VM, il faudra ensuite activer l’option « is template ».

Un template apparaîtra comme ceci dans la liste des instances :

Image non disponible

Vous pouvez voir que le symbole Image non disponiblede démarrage a été remplacé par le symbole clone Image non disponible.

Si vous cliquez sur le titre de la VM pour entrer dans ses réglages, au niveau de « Power », vous verrez que vous ne pouvez pas démarrer celle-ci.

Image non disponible

Pour générer une instance de VM depuis le template, il faudra cliquer sur l’icône Image non disponible.

Ceci ouvrira l’écran du template sur la fonction clone que nous verrons plus en détail un peu plus tard :

Image non disponible

Vous pourrez choisir le nom de la VM et renommer le disque comme vous le souhaitez

8. Réglages VM

8-1. Menu Power

Ce menu donne accès aux fonctions :

  • Power Off : cliquer sur Power Off va envoyer une demande d’arrêt ACPI. Si l’OS ne le gère pas, cela n’aura aucun effet. Il faudra alors cliquer sur l’onglet « force Off ». Nous pouvons donc considérer que Power Off va correspondre à l’appui sur le bouton marche/arrêt d’un ordinateur, avec ce bouton paramétré pour arrêter proprement l’OS.
  • Power Cycle : correspond à un reboot.
  • Force Off : peut être comparé à une coupure de courant au niveau de la VM.
  • Suspend : met la VM en pause, le menu Power donnant alors accès soit à Resume pour réactiver la VM, soit à Force Off pour la redémarrer.

8-2. Menu Access

Celui-ci concerne l’accès à l'affichage de ce qui se passe dans la VM.

8-3. Menu resize

Celui-ci permet de modifier :

  • le nombre de CPU ;
  • la taille mémoire ;
  • la taille disque.

Ces opérations seront accessibles uniquement si la VM est à l’arrêt.

8-4. Snapshots

Un snapshot, ou instantané, est un cliché à l'instant T d'une VM. Ce cliché complet devra contenir :

  • le fichier d'image disque d'origine en lecture seule et un fichier d'image disque supplémentaire qui contiendra les modifications postcliché ;
  • un fichier contenant la mémoire de la VM au moment du cliché (pour les snapshots à chaud, c’est-à-dire VM en cours de fonctionnement) ;
  • le fichier de définition de la VM au moment de la prise du cliché (au cas ou les réglages sont modifiés par la suite).

Avec KVM, un snapshot ne peut être pris qu'avec un disque dynamique au format qcow2.

Avec Webvirtcloud, pour prendre un snapshot, il vous faudra arrêter la VM, comme précisé sur l’écran :

Image non disponible

La VM arrêtée vous permettra de prendre un snapshot en lui donnant un nom :

Image non disponible

Le snapshot sera ensuite visible dans l'onglet « Manage Snapshot » :

Image non disponible

Vous aurez deux options possibles :

  • Restaurer le snapshot (revert Image non disponible) ;
  • le supprimer (delete Image non disponible).

Restaurer un snapshot remet la VM dans l'état où elle était au moment de la prise de celui-ci. Supprimer un snapshot vous fera perdre l'état antérieur de la VM qu'il représente. Un snapshot va grossir au fur et à mesure des modifications effectuées, donc attention à ne pas conserver de snapshots inutiles.

Le fichier de définition de snapshot va se trouver dans /var/lib/libvirt/qemu/snapshot/[dossier nom VM]/[nom du snapshot].xml.

Le format de disque qcow2 supporte les snapshots internes et externes. Un snapshot interne est intégré à l’image disque qcow2 principale (jusqu’à 10). Un snapshot externe va générer un fichier qcow2 supplémentaire, lié au principal. Pas de choix possible via Webvirtcloud. Webvirtcloud ne crée que des snapshots internes.

Il sera possible de prendre un snapshot en ligne de commande avec la commande virsh.

Connexion à l'hyperviseur :

 
Sélectionnez
virsh -c qemu+ssh://cloud@192.168.1.200/system

Welcome to virsh, the virtualization interactive terminal.

Type:  'help' for help with commands
       'quit' to quit

virsh #
 
Sélectionnez
# snapshot-create-as –domain {nom de la VM} –name {nom du snapshot} –description  “description du snapshot”

La liste des snapshot d'une VM sera visible via la commande :

 
Sélectionnez
# snapshot-list nom_de_la_VM

Pour restaurer un snapshot :

 
Sélectionnez
# snapshot-revert nom_de_la_VM  nom_du_snapshot

Pour supprimer un snapshot :

 
Sélectionnez
# snapshot-delete --domain nom_de_la_VM --snapshotname nom_du_snapshot

Pour créer un snapshot externe :

 
Sélectionnez
#  snapshot-create-as test-VM --diskspec vda,file=/home/cloud/disk.qcow2,snapshot=external --disk-only
Domain snapshot 1567495182 created

L'option --diskspec permet de spécifier le nom du fichier de snapshot. L'option --disk-only permet de ne pas inclure les CD-ROM connectés.

Pour sauvegarder l’état mémoire, il aurait fallu ajouter l’option

--memspec file=/home/cloud/ram.qcow2,snapshot=external,

option incompatible avec --disk-only.

Un snapshot créé manuellement apparaîtra dans la liste des snapshots. Par contre, un snapshot externe ne peut pas être géré depuis l’interface graphique, vous aurez un message :

 
Sélectionnez
Error: unsupported configuration: deletion of 1 external disk snapshots not supported yet

Pour le gérer, il faudra passer par virsh :

La tentative de suppression de celui-ci générera le message suivant :

 
Sélectionnez
# virsh snapshot-list --domain test-VM
 Name                 Creation Time             State
------------------------------------------------------------
 1567495182           2019-09-03 09:19:42 +0200 disk-snapshot

root@Debian:~# virsh snapshot-delete test-VM 1567495182
error: Failed to delete snapshot 1567495182
error: unsupported configuration: deletion of 1 external disk snapshots not supported yet

Voici pourquoi ce n’est pas implémenté dans WebvirtCloud.

Pour supprimer le cliché à la main, j’ai remplacé la ligne dans le fichier de définition XML de ma VM (/etc/libvirt/qemu/test-VM.xml).

Remplacement de :

 
Sélectionnez
source file='/home/cloud/disk.qcow2'/>

Nom du fichier utilisé pour le snapshot, par :

 
Sélectionnez
<source file='/home/cloud/images/test-VM-disk.qcow2'/>

Nom du fichier original.

Nous récupérons le nom du fichier de définition du snapshot :

 
Sélectionnez
/var/lib/libvirt/qemu/snapshot/test-VM/1567495182.xml

Et le supprimons.

Nous redémarrons ensuite libvirt :

 
Sélectionnez
service libbvirtd restart

8-5. Settings

8-5-1. Boot

Cet onglet permet d’activer le boot automatique de la VM lors du démarrage de son hôte.

Il permet également de sélectionner l’ordre de démarrage des périphériques (cd-rom, disque dur, carte réseau) :

Image non disponible

8-5-2. Disk

Permet le montage d’un fichier ISO sur le lecteur CD virtuel, éventuellement d’en ajouter un supplémentaire en cliquant sur le Image non disponible au niveau du premier lecteur CD. Le montage/démontage de fichier ISO ayant été déjà vu dans la partie création d’une VMAjout d'un ISO.

Sur la seconde partie de l’écran apparaîssent les images disque liées à la VM (une seule sur l’image ci-dessous).

Cliquer sur le symbole Image non disponible détachera l’image de la VM tandis que le symbole Image non disponible la détachera et la supprimera. Ces deux options ne seront accessibles que si la VM est éteinte.

L’ajout à chaud d’un disque fonctionne.

Image non disponible

8-5-3. Console

L’onglet console va vous permettre de choisir :

  • le type d’accès distant : VNC, SPICE (SPICE non testé dans ce tutoriel) ;
  • le port d’écoute : localhost ou toutes les interfaces ;
  • le mot de passe d’accès à l’interface ;
  • le langage du clavier.

Pour modifier ces réglages, la VM devra être éteinte.

Image non disponible

Lors de mon test, l’utilisation d’un mot de passe n’a eu aucun effet.

8-5-4. Network

Cet onglet va permettre la modification des réglages réseau.

Vous pourrez :

  • modifier l’adresse MAC ;
  • choisir le réseau virtuel sur lequel est connectée la carte réseau virtuelle ;
  • positionner les filtres.

L’ajout d’une carte avec Image non disponible ou la suppression d’une carte peut se faire à chaud.

 

8-5-5. Clone

Cette option permet de faire un clone de la VM, c’est-à-dire une copie à l’identique.

Par défaut, le nom de la VM clonée sera le nom d’origine suivi de -clone, il en va de même pour les disques de ce clone.

Vous pourrez changer les noms de la VM et/ou du disque à votre convenance. L’adresse MAC est automatiquement modifiée, vous pourrez changer celle-ci.

Image non disponible

Image non disponible

Vous ne pourrez pas cloner une VM en cours d’exécution.

8-5-6. Migrate

Cette fonctionnalité permet de migrer, c'est-à-dire déplacer une VM d'un hyperviseur vers un autre.

Image non disponible

Live Migration/offline Migration : une « Live Migration » correspond à une migration à chaud c'est-à-dire, VM en fonction. C'est une opération transparente qui n'interrompt pas la VM. Une fois la VM copiée sur l'hôte de destination, elle est stoppée de l'hôte source et activée sur l'hôte de destination sans interruption de service. Il peut y avoir une perte de quelques ping le temps de la recopie de l'état mémoire. Si la case « Delete Original » est cochée (ce qui est le cas par défaut), la VM source est supprimée.

Safe/Unsafe migration : des tests vont être faits avant migration pour s'assurer que la migration ne présente pas de risques (exemple : l'utilisation de cache est considérée comme « unsafe » (non sécurisée) pour une migration). Cocher « unsafe migration » va forcer celle-ci.

Il n'est pas possible de migrer une VM ayant des snapshots.

8-5-7. XML

Cet onglet donne accès au fichier XML de définition de la VM. Ceci vous permettra de modifier les options non présentes dans l’interface graphique.

La modification dans le fichier XML ne pourra se faire que VM stoppée.

8-5-8. Options

Cet onglet va vous permettre de donner un titre, une description à votre VM et également de la déclarer comme un template en cochant la case y afférent :

Image non disponible

Ceci devra être effectué VM éteinte.

8-5-9. users

Ceci va permettre de donner un accès en gestion de la VM à un utilisateur :

Image non disponible

Vous pourrez sélectionner un ou plusieurs gestionnaires de l‘instance :

Image non disponible
Image non disponible

Vous pourrez modifier les droits (ou les supprimer en cliquant sur la corbeille) en cliquant sur le nom de l’utilisateur :

Image non disponible

Vous voyez qu’il n’y a aucun droit par défaut (tout à false). Pour modifier les droits, il faudra cliquer sur le crayon.

Les droits par défaut (si tout reste à false) seront donc :

  • le démarrage et l’arrêt ;
  • la possibilité de faire des snapshots ;
  • la possibilité de créer un clone (sauf si son compte ne permet pas de cloner) ;
  • l’accès aux statistiques.

Pas d’accès aux réglages, ni d’accès à VNC, ni à la destruction de VM. Le redimensionnement est soumis aux restrictions définies.

8-6. Stats

Comme le nom l’indique, cet onglet va afficher des statistiques sous forme de graphique avec :

  • l’usage du CPU ;
  • l’utilisation de la mémoire ;
  • la bande passante réseau ;
  • les accès disque.
Image non disponible

Le sous-onglet logs affiche les logs des actions effectuées comme le démarrage ou l’arrêt d’une VM.

En cas de problème sur la VM, vous aurez un message d’erreur à l’écran. Voici un exemple de tentative de démarrage depuis une VM invalide (modification du nom du fichier image disque à fin de démonstration) :

Image non disponible

Le message est assez clair et l’interface nous positionne sur le fichier XML. L’information d’erreur apparaîtra dans les logs :

Image non disponible

8-7. Destroy

La fonction est simple à comprendre, elle va supprimer la VM. La case à cocher « Remove instance’s data » va également supprimer les images disques et non pas seulement la définition de la VM.

Remove instance’s data est coché par défaut.

Il n’y aura pas de demande de confirmation de suppression. C’est la même chose si la VM est en fonctionnement.

9. Installation d'un second hyperviseur

9-1. Prérequis

Les prérequis seront les paquets kvm, libvirt et un serveur SSH.

Il faudra ensuite :

Après quoi il faudra ajouter un ou plusieurs datastores sur l'hyperviseur et gérer le réseau sur ce nouvel hyperviseur que nous nommerons srv2.local.

Il sera ensuite possible de créer une VM sur le second hyperviseur nommé srv2.local depuis srv1 qui possède l’interface graphique Webvirtcloud.

Chaque hyperviseur est indépendant, une VM ne pourra utiliser qu'une image disque ou un ISO présent sur l’hyperviseur concerné, sauf cas de datastore partagé de type NAS (NFS, Ceph, etc)

Voici un écran avec une VM par hyperviseur :

Image non disponible

Une VM créée par un autre moyen que l’interface graphique (exemple directement avec virsh depuis la console de l’hyperviseur) apparaîtra.

10. Fonctions avancées

10-1. Renommer une VM

Renommer une VM devra se faire celle-ci éteinte.

Il vous faudra le faire depuis virsh, rien n'étant prévu dans Webvirtcloud.

La liste des VM peut être obtenue comme ceci :

 
Sélectionnez
virsh list --all
 Id    Name                           State
----------------------------------------------------
 -     test-VM                        shut off

Nous exportons le fichier de définition :

 
Sélectionnez
virsh dumpxml test-VM > test-VM-newname.xml

Nous éditons le fichier exporté et modifions le nom dans la balise <name>

Nous supprimons ensuite la VM (ceci ne supprimera que sa définition, pas les disques)

 
Sélectionnez
root@Debian:~# virsh undefine test-VM
Domain test-VM has been undefined

Nous réenregistrons notre VM avec son nouveau nom depuis le fichier XML modifié :

 
Sélectionnez
virsh define test-VM-newname.xml
Domain test-VM-newname defined from test-VM-template.xml

La VM sous son nouveau nom sera alors visible :

 
Sélectionnez
virsh list --all
 Id    Name                           State
----------------------------------------------------
-     test-VM-newname               shut off

Un simple rafraîchissement de Webvirtcloud prendra en compte les modifications effectuées en ligne de commande. Il m'a quand même été nécessaire de redémarrer Webvirtcloud (pas l'hyperviseur) pour pouvoir refaire une connexion à la console de la VM.

10-2. Datastores LVM, Ceph, NETFS

Webvirtcloud permet la connexion directe à un volume LVM, un volume Ceph ou un volume réseau (NFS, GlusterFS, SMB).

Il reste possible d'utiliser un volume réseau non reconnu tant que celui-ci est monté dans un point de montage accessible par /etc/fstab. Ceci risque cependant d'avoir pour résultat des performances dégradées.

Pour y accéder, il faut créer un datastore y correspondant comme vu au chapitre 5Storage.

10-2-1. LVM pool

Prérequis : comprendre le fonctionnement de LVM.

Avec LVM, un ou plusieurs disques physiques(PV : Physical Volume) sont intégrés à un Volume Group. Un ou plusieurs volume(s) logique(s) (LV : Logical Volume) vont puiser dans l'espace disponible dans le Volume Group pour représenter le volume accessible. Chaque volume logique contiendra un ou plusieurs systèmes de fichiers.

Image non disponible

Avec l'utilisation de LVM conjointement à KVM, chaque image disque sera contenue dans un volume logique LV. Le contenu de l'image n'est pas stocké dans un fichier qcow2, mais directement dans le volume logique LVM.

Pour créer un datastore LVM, il vous faudra fournir le « device », Webvirtcloud créant alors le Volume Group.

Image non disponible

La création d'une image disque créera un volume logique au nom spécifié. L'interface vous permettra de supprimer l'image, ceci supprimant le volume logique.

10-2-2. Ceph pool

Les champs à remplir correspondent aux éléments nécessaires à Ceph et sont explicites pour les utilisateurs de Ceph. Nous ne nous étendrons pas sur ces aspects.

Image non disponible

10-2-3. NETFS pool

NETFS va permettre une connexion sur un volume :

  • NFS
  • GlusterFS
  • SMB/CIFS

Un volume NFS sera recherché par défaut.

Il vous faudra spécifier :

  • le nom du datastore ;
  • le nom d'hôte du serveur ;
  • le remote path (chemin NFS ou nom de partage SMB) ;
  • le local Path (le point de montage local) ;
  • le format (NFS, glusterFS, SMB).
Image non disponible

10-3. Démarrage automatique de Webvirtcloud

Avec l'utilisation de Nginx comme prévu par défaut, Webvirtcloud est directement actif. Les opérations suivantes seront inutiles.

Pour lancer automatiquement le serveur Django de Webvirtcloud, je crée un fichier webvirtcloud.service utilisable par systemd :

 
Sélectionnez
[Unit]
Description=WebvirtCloud
After=multi-user.target

[Service]
Type=simple
PIDFile=/var/run/webvirtcloud.pid
WorkingDirectory=/home/cloud/webvirtcloud
ExecStart=/usr/bin/python /home/cloud/webvirtcloud/manage.py runserver 0:8000
User=cloud
Restart=on-failure

[Install]
WantedBy=multi-user.target

Dans le fichier, j'indique le dossier de travail, le nom de l'exécutable avec chemin absolu, ainsi que le nom de l'utilisateur.

J'active ensuite le service avec systemctl :

 
Sélectionnez
systemctl enable webvirtcloud.service
Created symlink /etc/systemd/system/multi-user.target.wants/webvirtcloud .service → /etc/systemd/system/webvirtcloud .service.

Je démarre le service :

 
Sélectionnez
service webvirtcloud start

Et j’automatise le démarrage de websockify :

 
Sélectionnez
[Unit]
Description=websockify
After=multi-user.target

[Service]
Type=simple
ExecStart=/usr/bin/python /usr/bin/python2-websockify 6080 127.0.0.1:5900
Restart=on-failure

[Install]
WantedBy=multi-user.target

Il faudra également appliquer systemctl enable et démarrer le service.

Dans /etc/systemd/system/webvirtcloud, je remplace :

 
Sélectionnez
WantedBy=multi-user.target

Par :

 
Sélectionnez
WantedBy=websockify.service

Websockify devenant une dépendance de webvirtcloud, le service webvirtcloud démarrera automatiquement websockify.

10-4. Sécurité

Par défaut,Webvirtcloud est fourni avec un fichier de configuration Nginx. La modification de celui-ci permettra de sécuriser l'accès en passant en https et d'implémenter un certificat (autosigné ou d'une autorité de certification) via un reverse Proxy.

Voici le fichier de configuration disponible dans conf/nginx/webvirtcloud.conf :

 
Sélectionnez
upstream gunicorn_server {
    #server unix:/srv/webvirtcloud/venv/wvcloud.socket fail_timeout=0;
    server 127.0.0.1:8000 fail_timeout=0;
}
server {
    listen 80;

    server_name servername.domain.com;
    access_log /var/log/nginx/webvirtcloud-access_log; 

    location /static/ {
        root /srv/webvirtcloud;
        expires max;
    }

    location / {
        proxy_pass http://gunicorn_server;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-for $proxy_add_x_forwarded_for;
        proxy_set_header Host $host:$server_port;
        proxy_set_header X-Forwarded-Proto $remote_addr;
        proxy_connect_timeout 600;
        proxy_read_timeout 600;
        proxy_send_timeout 600;
        client_max_body_size 1024M;
    }
}

J'ai fait l'essai avec Apache.

Installation d'Apache :

 
Sélectionnez
apt-get install apache2

Activation du module reverse proxy :

 
Sélectionnez
a2enmod proxy_http
Considering dependency proxy for proxy_http:
Enabling module proxy.
Enabling module proxy_http.
To activate the new configuration, you need to run:
  systemctl restart apache2

Création du fichier virtualhost /etc/apache2/site-available/srv1.local.conf après redémarrage d'Apache :

 
Sélectionnez
<VirtualHost *:80>
        ServerName srv1.local
        ProxyPreserveHost On
        ProxyRequests On
        ProxyPass / http://127.0.0.1:8000/
        ProxyPassReverse / http:/127.0.0.1:8000/
</VirtualHost>

Activation du site :

 
Sélectionnez
a2ensite srv1.local

Enabling site srv1.local.
To activate the new configuration, you need to run:
  systemctl reload apache2

service apache2 restart

À ce stade, après redémarrage d'Apache, le site répondra sur http://srv1.local:8000 et sur http://srv1.local via le reverse proxy d’Apache.

Modification du service webvirtcloud pour forcer la réponse sur 127.0.0.1 :

remplacement de ./manage.py runserver 0:8000 par ./manage.py runserver 127.0.0.1:8000

Redémarrage de Webvirtcloud :

 
Sélectionnez
systemctl daemon-reload
service webvirtcloud restart

À ce stade, Webvirtcloud ne répondra que sur le port 80 si non appelé sur l’adresse de loopback.

Reste à passer en https.

Création d'un certificat autosigné :

 
Sélectionnez
cd /etc/ssl
mkdir srv1.local
cd srv1.local
openssl genrsa -out srv1.local.key 2048
Generating RSA private key, 2048 bit long modulus
.+++++
.........................................................+++++
e is 65537 (0x010001)

Création d’un fichier de demande de signature de certificat :

 
Sélectionnez
openssl req -new -key srv1.local.key -out srv1.local.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:FR
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:developpez.com
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:srv1.local
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

Création du certificat au format x509 :

 
Sélectionnez
openssl x509 -req -days 365 -in srv1.local.csr -signkey srv1.local.key -out srv1.local.crt
Signature ok
subject=C = FR, ST = Some-State, O = developpez.com, CN = srv1.local
Getting Private key

Concaténation des fichiers :

 
Sélectionnez
cat srv1.local.key srv1.local.crt > srv1.local.pem

Nous passons ensuite à la partie Apache.

Activation du module SSL apache :

 
Sélectionnez
a2enmod ssl

Modification du fichier virtualHost pour passer en https :

 
Sélectionnez
<ifModule mod_ssl.c>

<VirtualHost *:443>
        ServerName srv1.local
        ProxyPreserveHost On
        ProxyRequests On
        ProxyPass / http://127.0.0.1:8000/
        ProxyPassReverse / http:/127.0.0.1:8000/
        SSLEngine on
        SSLCertificateFile /etc/ssl/srv1.local/srv1.local.pem
</VirtualHost>

Modification de la commande d’appel à Websockify pour activer le SSL

Remplacement de la ligne :

 
Sélectionnez
ExecStart=/usr/bin/python /usr/bin/python2-websockify 6080 127.0.0.1:5900

Par :

 
Sélectionnez
ExecStart=/usr/bin/python /usr/bin/python2-websockify 6080 127.0.0.1:5900 --cert=/etc/ssl/srv1.local/srv1.local.pem --ssl-only

L'essai effectué a abouti à un fonctionnement partiel. L'accès au menu « Compute » ne fonctionne pas, l'URL appelée retournant http://srv1.local/Compute// au lieu de http://srv1.local/Compute/.

Le problème est peut-être facilement corrigible, mais hors de mes compétences.

À ce stade, mon exemple d'utilisation d'Apache ne permet pas d'utiliser Webvirtcloud. Il faut donc utiliser Nginx comme préconisé.

11. Maintenance

Pour pouvoir remonter la configuration de Webvirtcloud suite à une panne, il faudra sauvegarder le dossier webvirtcloud, les clefs ssh et les fichiers de certificat (dans notre cas /etc/ssl/srv1.local).

En cas de perte d'hyperviseur, il faudra pouvoir restaurer les VM.

11-1. Procédure de restauration en cas de perte

Pour pouvoir remettre Webvirtcloud en marche, il vous faudra :

  • installer les paquets libvirtd-daemon-system, python-libvirt, novnc et les paquets kvm si l'hôte de Webvirtcloud est un hyperviseur ;
  • recréer le compte utilisateur, cloud dans notre exemple ;
  • ajouter ce compte cloud dans les groupes (cf partie installationInstallation de Webvirtcloud proprement dit) et modifier le fichier libvirtd.conf ;
  • restaurer les dossiers webvirtcloud et .ssh, ainsi que les clefs de certificat ;
  • faire un chmod +x manage.py ;
  • relancer pip install -r conf/requirements.txt.

Une fois Webvirtcloud démarré et l'authentification effectuée, un message d’erreur apparaît :

 
Sélectionnez
Error: Cannot recv data: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY! Someone could be eavesdropping on you right now (man-in-the-middle attack)! It is also possible that a host key has just been changed. The fingerprint for the ECDSA key sent by the remote host is SHA256:bRayEOTlBrnGY2Jzx6Rgzwv+SoVC4PMCJBShe/Df7Is. Please contact your system administrator. Add correct host key in /home/cloud/.ssh/known_hosts to get rid of this message. Offending ECDSA key in /home/cloud/.ssh/known_hosts:1 remove with: ssh-keygen -f "/home/cloud/.ssh/known_hosts" -R srv1.local ECDSA host key for srv1.local has changed and you have requested strict checking. Host key verification failed.: Connection reset by peer

Le message est explicite, l’authentification SSH a changé du fait de la réinstallation.

Nous supprimons l’ancienne authentification :

 
Sélectionnez
ssh-keygen -f "/home/cloud/.ssh/known_hosts" -R srv1.local
# Host srv1.local found: line 1
//home/cloud/.ssh/known_hosts updated.
Original Contents retained as /home/cloud/.ssh/known_hosts.old

puis testons une nouvelle connexion :

 
Sélectionnez
ssh cloud@srv1.local
The authenticity of host 'srv1.local (192.168.1.200)' can't be established.
ECDSA key fingerprint is SHA256:LLALxAyQlZLXlVtPSyTrOkUaTKKC+C0UCDAQKrWTuMI.
Are you sure you want to continue connecting (yes/no)? Yes
Warning: Permanently added ‘srv1.local’ (ECDSA) to the list of known hosts.
Warning: the ECDSA host key for ‘srv1.local’ differs from the key to the IP address ‘192.168.1.200’
Offending key for IP in /home/cloud/.ssh/known_hosts:1
Are you sure you want to continue connecting (yes/no)? Yes

La deuxième question est due au changement d’empreinte suite à la suppression de l’entrée avec la commande ssh-keygen -f.

pour le message « Offending key », il va falloir supprimer l’entrée :

 
Sélectionnez
sed -i '1d' ~/.ssh/known_hosts

Remplacez la valeur devant d par la ligne affichée dans le message d’erreur ici : /home/cloud/.ssh/known_hosts:1

Une fois ceci fait, l’interface graphique restera bloquée tant que les mots de passe ne sont pas rentrés dans la console.

En allant dans l’écran storage, nous pouvons constater que plus aucun datastore n’est présent, il en va de même pour les réseaux.

Pour pallier ceci, il faudra avoir sauvegardé puis restauré les fichiers XML contenus dans /etc/libvirt/storage et /etc/libvirt/qemu/networks.

Restera ensuite à restaurer les VM en restaurant les fichiers images dans les datastores respectifs et les fichiers XML de définition des VM (dans le dossier /etc/ibvirt/qemu).

12. Haute disponibilité

Pour pouvoir bénéficier de la haute disponibilité, il vous faut être en mesure de relancer rapidement une VM sur un autre hyperviseur, ceci grâce à la réplication.

Webvircloud ne dispose pas de fonctionnalités de réplication.

Vous pouvez aussi envisager de stocker les VM et les fichiers de configuration dans un volume hautement disponible de type Ceph ou GlusterFS. Il faudra dans ce cas faire un point de montage du dossier /etc/libvirt vers un de ces volumes.

Il vous faudra ensuite installer un système à haute disponibilité comme heartbeat, Pacemaker ou Corosync qui permettront de gérer la récupération de l’IP devant répondre et de démarrer les services nécessaires (dans notre cas, libvirt, webvirtmgr proprement dit, les hyperviseurs).

13. Installation dans un conteneur docker

Webvirtcloud est fourni avec un dockerfile, que je n'ai pas réussi à faire fonctionner..

Docker installé, j'ai tenté d’exécuter le Dockerfile :

 
Sélectionnez
docker build .

qui finira par retourner l'erreur :

 
Sélectionnez
...
Step 9/19 : RUN cd /srv/webvirtcloud && . venv/bin/activate &&  python manage.py migrate &&     chown -R www-data:www-data /srv/webvirtcloud
 ---> Running in 8b9f21cf2d8f
Traceback (most recent call last):
  File "manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "/srv/webvirtcloud/venv/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 364, in execute_from_command_line
    utility.execute()
  File "/srv/webvirtcloud/venv/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 308, in execute
    settings.INSTALLED_APPS
  File "/srv/webvirtcloud/venv/local/lib/python2.7/site-packages/django/conf/__init__.py", line 56, in __getattr__
    self._setup(name)
  File "/srv/webvirtcloud/venv/local/lib/python2.7/site-packages/django/conf/__init__.py", line 41, in _setup
    self._wrapped = Settings(settings_module)
  File "/srv/webvirtcloud/venv/local/lib/python2.7/site-packages/django/conf/__init__.py", line 110, in __init__
    mod = importlib.import_module(self.SETTINGS_MODULE)
  File "/usr/lib/python2.7/importlib/__init__.py", line 37, in import_module
    __import__(name)
ImportError: No module named settings
The command '/bin/sh -c cd /srv/webvirtcloud && . venv/bin/activate &&  python manage.py migrate &&     chown -R www-data:www-data /srv/webvirtcloud' returned a non-zero code: 1

J’ai donc recherché un conteneur tout fait sur github et est utilisé celui de mplx.

On procède tout d’abord à l’installation de docker :

 
Sélectionnez
apt-get install apt-transport-https
wget https://download.docker.com/linux/debian/gpg
apt-key add gpg

et on ajoute la ligne suivante à /etc/apt/sources.list :

 
Sélectionnez
https://download.docker.com/linux/debian stretch stable

Installation de docker :

 
Sélectionnez
apt-get update
apt-get install docker-ce

Récupération de l'image Docker :

 
Sélectionnez
docker pull mplx/docker-webvirtcloud

Retour de la commande :

 
Sélectionnez
Using default tag: latest
latest: Pulling from mplx/docker-webvirtcloud
c64513b74145: Pull complete
01b8b12bad90: Pull complete
c5d85cf7a05f: Pull complete
b6b268720157: Pull complete
e12192999ff1: Pull complete
d39ece66b667: Pull complete
65599be66378: Pull complete
5afc64b9ec31: Pull complete
ebfde3c36cb7: Pull complete
6dfadbf7f9b2: Pull complete
9f389947c051: Pull complete
8288af150b9d: Pull complete
7323098ebd3c: Pull complete
Digest: sha256:f9e4ae21320313d11d7e7f7943e942185035a6264fa46f995dfec7d5c232c17b
Status: Downloaded newer image for mplx/docker-webvirtcloud:latest
docker.io/mplx/docker-webvirtcloud:latest

Nous pouvons voir l'image téléchargée avec la commande docker images :

 
Sélectionnez
# docker images
REPOSITORY                 TAG                 IMAGE ID            CREATED             SIZE
mplx/docker-webvirtcloud   latest              7351f092eb2d        7 months ago 799MB

Nous lançons un conteneur :

 
Sélectionnez
docker run -d -p 80:80 mplx/docker-webvirtcloud
bbdf3982f67fcb8c803ec67a2f9a221f6b72ef6a6d0057f5ea2addcf06edf134

Nous avons alors accès à l’interface web. Nous commençons par modifier le mot de passe de l’interface comme vu précédemment, puis effectuons les réglages souhaités.

Pour garder les modifications, il va falloir s'assurer de la persistance de notre conteneur

Nous récupérons l’id de celui-ci avec la commande docker ps :

 
Sélectionnez
docker ps
CONTAINER ID        IMAGE                      COMMAND             CREATED             STATUS              PORTS                NAMES
bbdf3982f67f        mplx/docker-webvirtcloud   "/sbin/my_init"     8 minutes ago Up 8 minutes        0.0.0.0:80->80/tcp   modest_moore

Nous déclinons notre instance en image que nous nommons ici webvirtcloud après avoir récupéré son id :

 
Sélectionnez
docker commit bbdf3982f67f webvirtcloud
sha256:7e0a0766a6f8ebabb406753099213cf7e59f2062ba47a6c9601133012c6eac46

Nous arrêtons celui-ci :

 
Sélectionnez
docker stop bbdf3982f67f
bbdf3982f67f

Nous supprimons l'image d'origine :

 
Sélectionnez
docker rmi mplx/docker-webvirtcloud -f

Puis relançons une instance depuis l’image :

 
Sélectionnez
docker run -d -p 80:80 --name tmp webvirtcloud

Ici, l’option -–name est ajoutée pour faciliter les manipulations et ne pas devoir utiliser l'id.

Nous allons générer des clefs SSH pour le serveur.

Nous ouvrons un shell dans le conteneur :

 
Sélectionnez
docker exec -ti tmp /bin/bash

Une fois connectés au conteneur, nous nous connectons ensuite avec le compte www-data, propriétaire des données Webvirtcloud :

 
Sélectionnez
root@3ac4826388f4:/srv/webvirtcloud# su s /bin/bash www-data

Nous créons ensuite nos clefs :

 
Sélectionnez
ssh-keygen -t rsa

Nous obtenons un message :

 
Sélectionnez
/var/www/.ssh/id_rsa already exists.
Overwrite (y/n)?

Une fois la clé recréée, nous lançons ssh-copy-id.

Une fois cette opération effectuée, nous pouvons créer un compute pour accéder à l’hyperviseur, puis ensuite les datastores, puis les VM.

Les dossiers pour les datastores font référence au système de fichiers de l’hyperviseur, pas au conteneur webvirtcloud.

13-1. Modifications fréquentes

Effectuer un commit sur un Docker Image va permettre de figer les modifications effectuées dans un conteneur.

En cas de modifications fréquentes, il sera pertinent de stocker la configuration hors du conteneur dans un dossier de l’hôte.

Vous devrez donc récupérer le contenu du dossier /srv/webvirtcloud/data et exposer un dossier de l’hôte vers ce chemin dans le conteneur. Exemple avec les données dans le dossier /partage_docker :

 
Sélectionnez
docker run -d -p 80:80 -v /partage_docker:/srv/webvirtcloud/data --name nom_conteneur webvirtcloud

Il faudra également gérer les clés SSH.

14. Conclusion

Les fonctions de Webvirtcloud sont moins avancées que celles de Proxmox, qui fonctionne de façon similaire, mais Webvirtcloud peut être pratique pour une configuration très simple ou en complément pour un administrateur habitué à l'utilisation de virsh. Sa légèreté et les possibilités de mise en conteneur permettent de faire une version portable d'interface d'administration KVM.

14-1. Remerciements

Je remercie LittleWhite pour sa relecture technique ainsi que escartefigue pour sa relecture orthographique.