QEMU/KVM
3.2 - Réduction de taille fichier qcwo2
3.3 - Conversion entre formats
4.1 - Commande de base qemu-system
4.3 - Périphériques de stockage
5.1 - Test de l'installateur debian
5.2 - Installation de debian dans un disque virtuel
5.3 - Utilisation de l'image debian
5.4 - Démarrer à partir d'une image ISO en utilisant qemu
4.1 - Test d'amorçage UEFI et de mémorisation des variables EFI
4.2 - Test de l'entrée par défaut /boot/bootx64.efi
5 - Menu uefi de la plateforme
5.2 - Modification de l'ordre d'amorçage
5.3 - Lancement d'un OS par sélection du fichier
6.1 - Test d'une distribution debian live
6.2 - Installation d'un système debian
8 - Partage de dossier entre l'hôte et l'invité
•.qemu est un émulateur permettant de lancer et installer une distribution sur une architecture identique ou différente de celle de l'hôte.
•.kvm est un module du noyau qui utilise les capacités de virtualisation des processeurs (intel ou amd)
•.qemu utilise le module kvm lorsque l'architecture processeur de l'invité et de l'hôte sont identiques, il en résulte une accélération très sensible des performances
•.qemu s'installe depuis les dépôts Debian
$ sudo aptitude install qemu
•.Par défaut, les émulations de toutes les plate-formes sont installées, ce que l'on peut vérifier avec la completion
$ qemu-system-
qemu-system-aarch64 qemu-system-mips64 qemu-system-s390x
qemu-system-alpha qemu-system-mips64el qemu-system-sh4
qemu-system-arm qemu-system-mipsel qemu-system-sh4eb
......
•.Dans ce document, la version de qemu est
$ qemu-system-x86_64 --version
QEMU emulator version 3.1.0 (Debian 1:3.1+dfsg-5)
Copyright (c) 2003-2018 Fabrice Bellard and the QEMU Project developers
•.Lorsque le processeur supporte la virtualisation, qemu utilise les modules kvm, ce qui accélère considérablement la vitesse de l'émulation.
•.Pour un processeur intel, la virtualisation est signalée par la présence du flag vmx
$ grep --color vmx /proc/cpuinfo
•.Pour un processeur amd, la virtualisation est signalée par la présence du flag svm
$ grep --color svm /proc/cpuinfo
•.Les modules kvm, kvm-intel ou kvm-amd sont chargés
$ lsmod |grep kvm
kvm_intel 200704 3
kvm 598016 1 kvm_intel
irqbypass 16384 1 kvm
•.Les disques et cdrom virtuels sont des fichiers "image" utilisés comme périphérique disque. Deux formats de fichier sont disponibles
•.le format brut de taille fixe correspondant à un fichier image ordinaire, non compressé
•.le format qcwo2 dont la taille variera en fonction du besoin, jusqu'à une taille maximale
•.Création d'un disque virtuel de 20GiB au format brut
$ qemu-img create debian.img 20G
équivalent à
$ dd if=/dev/zero of=debian.img bs=1M count=20000 # Equivalent à
$ fallocate -l 20G debian.img
•.Création d'un disque virtuel de taille variable (max 20GiB)
$ qemu-img create -f qcow2 debian.qcow2 20G
La taille du fichier "vide" est très faible vis à vis de sa taille maximale
$ du -h debian.qcow2
196K debian.qcow2
•.Réduction taille fichier qcwo2 (celle-ci pouvant augmenter à l'occasion des manipulations du fichier, recopie, ...), l'opération est assez lente
•.Fichier de départ
$ du -h --apparent-size demo.qcow2
5,6G demo.qcow2
•.Conversion
$ qemu-img convert -f qcow2 -O qcow2 -c demo.qcow2 demo3.qcow2 -p
$ du -h --apparent-size demo3.qcow2
2,0G demo3.qcow2
Signification des options :
-f format de départ
-O format de sortie
-c compression
-p indication de la compression
•.Conversion qcwo2 vers raw
$ qemu-img convert -f qcow2 -O raw demo.qcow2 demo.raw -p
$ du -h --apparent-size demo.raw
20G demo.raw
•.Conversion raw vers qcwo2
$ qemu-img convert -f raw -O qcow2 demo.raw demo2.qcow2 -p
$ du -h --apparent-size demo2.qcow2
5,3G demo2.qcow2
•.Conversion raw vers qcow2 avec compression simultanée (plus lent)
$ qemu-img convert -f raw -O qcow2 -c demo.raw demo3.qcow2 -p
$ du -h --apparent-size demo3.qcow2
2,0G demo3.qcow2
Le lancement d'une émulation s'effectue au moyen
•.d'une commande spécifiant l'architecture à émuler : qemu-system-<architecture_émulée>
•.suivie d'une liste d'options, telles que
•.caractéristiques de l'émulation (taille mémoire, nombre de cpus, type d'affichage...)
•.liste de périphériques de stockage réels ou virtuels avec leurs priorités
•.des options d'amorçage du système (priorités, écran de bios, uefi, ...)
•......
•.Dans ce qui suit on suppose que le système émulé est du type x64_64, la commande de lancement de l'émulation sera donc
$ qemu-system-x86_64
•.La commande doit-être lancée avec les droits administrateurs si les périphériques de stockage sont externes (du type /dev/sdb, ...) ou s'ils sont virtuels (fichiers) avec comme propriétaire root
$ sudo qemu-system-x86_64
•.Il est recommandé d'abandonner les droits root aussitôt que la commande d'émulation est lancée, pour cela utiliser l'option -runas <nom_utilisateur>
$ sudo qemu-system-x86_64 -runas <nom_utilisateur>
Attention : Les options par défaut correspondent à une configuration minimale et peuvent ne pas convenir, il est donc préférable de les redéfinir
•.Le fonctionnement sans l'émulation kvm est très lente. L'option -accel kvm (remplace l'option -enable-kvm) lorsqu'elle est supportée est donc très recommandée
-accel kvm
•.La taille mémoire attribuée par défaut à l'émulation est de 512M, ce qui est généralement insuffisant et se traduit, en cours de fonctionnement, par une erreur du type Kernel panic - not syncing: No working init found. Utiliser l'option -m suivie de la taille mémoire en MiB pour changer la valeur par défaut, si dessous 2048 MiB (sur les 8GiB disponibles)
-m 2048
•.Par défaut, un seul processeur est attribué à l'émulation. Utiliser l'option -smp suivie du nombre de processeurs attribué à l'émulation, ci-dessous 4 processeurs (sur les 8 disponilbles)
-smp 4
•.Par défaut, la carte graphique émulée est de type haute résolution (Bochs VBE). Autres modes possibles "cirrus" (moindre résolution), "virtio", "non" (désactivation de la carte VGA). En cas de problème d'affichage, essayer les différents modes ...
-vga virtio
•.Désactiver la sortie graphique et rediriger les entrées sorties série vers la console
-nographic
•.Réseau
•.Désactiver l'accès réseau par défaut (SLIRP) (afin par exemple qu'au cours de l'amorçage, il ne prenne la main ou ne retarde la recherche du périphérique amorçable et n'empêche par exemple, l'accès au shell uefi)
-net none
•.qemu accepte les périphériques de stockage réél et virtuels avec au maximum un cdrom, deux disquette et 4 disques. De façon générique, un périphérique de stockage est désigné sous la forme
-drive file=<nom_du_périphérique>,media=xxxx,format=xxxx,index=xxxx,if=xxxx
•.l'ordre des options, séparées par des virgules est indifférent
•.le media est soit disk, soit cdrom
•.le format est soit raw, soit qcwo2
•.l’interface (if), par défaut ide, valable pour les disques et les cdrom, autre format : pflash, floppy, ....
•.l'index spécifie l'ordre de priorité sur un bus donné (premier disque, deuxième disque, etc...)
Exemples : les noms et extensions des fichiers sont arbitraires
•.Disque dur réél
-drive file=/dev/sdb
•.CD ROM réél
-drive file=/dev/sr0
•.Disque dur virtuel, format brut, si plusieurs disques sont présents, ils sont priorisés dans l'ordre d'apparition, à moins qu'un index soit utilisé (index=0 ou 1 ou 2 ou 3)
-drive media=disk,format=raw,file=file.img
•.Disque dur virtuel, format qcwo2
-drive media=disk,format=qcwo2,file=file.qcwo2
•.CD ROM virtuel
-drive media=cdrom,file=file.iso
•.Mémoire flash
-drive if=pflash,format=raw,file=var.fd
•.Mémoire flash à lecture seulement
-drive if=pflash,format=raw,readonly,file=code.fd
•.Les options de boot sont listées à la suite séparées par des virgules
-boot option1,option2,option3,....
•.Ordre d'amorçage : Si un seul périphérique de stockage est indiqué, l'amorçage s'effectuera sur ce périphérique, et l'option n'est pas nécessaire. Si un disque et un cdrom sont présents, l'amorçage s'effectuera sur le disque. Il est possible de "forcer" l'ordre avec
•.Amorçage sur le premier disque dur
-boot order=c
•.Amorçage sur le cdrom
-boot order=d
•.Amorçage la première fois sur le cdrom, les fois suivantes sur le disque
-boot order=c,once=d
•.Par défaut, le menu de boot de la machine (bios ou uefi voir plus loin) n'est pas proposé. Utiliser l'option menu=on et taper sur Esc lorsque le menu de boot apparaît
-boot menu=on
•.On suppose ssh présent et activé sur l'hôte et l'invité
$ sudo aptitude install ssh
$ sudo systemctl start ssh
•.Depuis l'invité, l'hôte est accessible via
$ ssh 10.0.2.2
•.Pour que l'hôte soit accessible depuis l'invité, lancer qemu avec les options
-net nic -net user,hostfwd=tcp::5022-:22
Ces options redirigent le port SSH 22 sur le port 5022 de l'invité. Pour joindre l'invité
$ ssh <nom_utilisateur_invité>@localhost -p 5022
•.Dans ce qui suit, la variable qemu est égale à la commande qemu-system de base suivie des options d'émulation souhaitées
$ qemu="qemu-system-x86_64 -accel kvm -m 2048 -smp 4 -vga virtio"
pour raccourcir l'écriture des commandes
•.On appelle debian.iso le fichier d'un installateur (ou d'une version live) debian. Le lancement de l'installateur s'effectue avec la commande
$ $qemu \
-drive media=cdrom,format=raw,file=debian.iso
•.La fenêtre de qemu s'ouvre sur l'installateur
•. Créer une image de taille variable (format qcow2), par exemple 20GiB
$ qemu-img create -f qcow2 debian.img 20G
•.Introduire le disque sur lequel aura lieu l'installation dans la commande d'émulation
$ $qemu \
-drive media=cdrom,format=raw,file=debian.iso \
-drive media=disk,format=qcwo2,file=debian.img \
-boot order=c,once=d
•.Installer debian sur le disque virtuel comme lors d'une installation classique
•.Lancer le système émulé en démarrant sur le disque virtuel debian.img
$ $qemu \
-drive media=disk,format=qcwo2,file=debian.img
Qemu a deux modes de fonctionnement nommés émulation du système complet et émulation du mode utilisateur. Si vous voulez simuler le système entier et pas seulement le processeur (comme un PC), vous devez utiliser le mode d'émulation du système complet.
Les distributions les plus récentes ont des binaires séparés pour ces deux modes de fonctionnement différents. Par exemple, si vous voulez juste l'émulation du cpu en mode utilisateur pour l'architecture X86-64, vous devez utiliser le binaire qemu-x86_64 et si vous voulez l'émulation du système complet X86-64 bit (comme votre PC), le binaire qemu-system-x86_64 doit être utilisé dans les commandes ci-dessous.
Vous avez une image iso et vous voulez démarrer à partir de celle-ci sans redémarrer le système, utilisez simplement la machine virtuelle qemu comme ci-dessous (-m 512 indique que qemu utilisera 512 Mb de RAM du système) :
qemu-system-x86_64 -boot d -cdrom image.iso -m 512
Il est également possible d'utiliser votre périphérique cdrom habituel. Si le périphérique est /dev/cdrom vous pouvez démarrer un cd dans le périphérique comme ceci :
qemu-system-x86_64 -boot d -cdrom /dev/cdrom -m 512
Les exemples ci-dessus n'utilisent pas de disque dur, ils sont donc adaptés aux images de cd en direct.
Si vous voulez installer une distribution sur un fichier image de disque dur, vous devez d'abord créer un fichier image de disque dur :
qemu-img create mydisk.img 10G
Dans cet exemple, nous avons créé une image de 10 Go. Maintenant nous pouvons utiliser ce fichier comme disque dur dans notre boot qemu :
qemu-system-x86_64 -boot d -cdrom image.iso -m 512 -hda mydisk.img
La fenêtre Qemu comprend une barre de menu, affichée par défaut. La faire apparaître, disparaître avec Ctrl Alt M
•.Le menu Machine permet de Mettre en pause, redémarrer (reset), arrêter la machine ou terminer la commande
•.Le menu View permet de contrôler l'affichage de la fenêtre
•.Ctrl Alt F : Passage plein écran
•.Ctrl Atl G : Capture de l'entrée (clavier, souris)
•.Ctrl Alt 1 : xxx -vga : Affichage de la fenêtre d'émulation "run time"
•.Ctrl Alt 2 : Compatmonitor0 : Affichage de la fenêtre "console qemu"
•.Show Tab : Affichage des fenêtres d'émulation et de console sous forme d'onglets
•.Detach : Détacher la fenêtre, pour par exemple
afficher simultanément la fenêtre d'émulation et la console qemu
•.Depuis la fenêtre d'émulation, les combinaisons de touches habituelles pour ouvrir une console linux ou revenir au mode graphique (Ctrol+Altr+F1, .., Alt F7) ne sont pas utilisables, celles-ci étant interceptées par l'hôte. Il est nécessaire de passer par la console qemu pour envoyer les codes : voir ci-après
•.Lorsque la console qemu est ouverte (Ctrl Alt 2), le message suivant s'affiche
Qemu 2.8.2 monitor - type 'help' for more information
(qemu)
•.Taper help pour obtenir la liste des commandes
•.Voir https://en.wikibooks.org/wiki/QEMU/Monito pour plus de détails sur les commandes
•.Exemple 1 : Vérification de la prise en compte de kvm
(qemu) info kvm
kvm support: enabled
•.Exemple 2 : La console qemu peut-être utilisée pour envoyer à l'invité des touches ou combinaison de touches qui ne peuvent pas être émises depuis l'invité, par exemple les combinaisons de touche Ctrl Alt F1, Alt F7. Utiliser la commande sendkey suivie de la liste des touches, par exeple,
(qemu) sendkey ctrl-alt-f1
suivi de Enter. Retourner à la fenêtre d'émulation pour vérifier la prise en compte. Effectuer de même pour envoyer le code Alt-f7
On s'intéresse ici à l'amorçage présent par défaut (SeaBios) BIOS / MBR.
•.Par défaut, le menu du Bios n'est pas accessible et le programme à émuler est immédiatement lancé.
•.Pour accéder au menu de la plateforme, lancer la commande d'émulation avec l'option
-boot menu=on
puis, lorsque l'invite s'affiche, taper Esc
•.Dans le cas de l'amorçage par défaut (SeaBIOS), le menu se limite au choix numéroté des périphériques d'amorçage
•.Pour lancer l'amorçage sur un périphérique
•.Le sélectionner en tapant le numéro associé. Noter que le clavier est en mode qwerty, ne pas utiliser la touche Maj pour taper les chiffres.
•.Si le périphérique sélectionné ne peut pas être amorcé, le périphérique suivant dans la liste est scruté.
•.Par défaut, qemu émule un amorçage de type BIOS/MBR. L'émulation de l'amorçage UEFI fait appel à OVMF, un portage du projet Tianocore (implémentation open source de l'UEFI) pour les machines virtuelles.
•.ovmf est proposé en plusieurs versions. Dans la version retenue ici, ovmf se présente sous la forme d'un fichier unique (regroupant le code UEFI, le registre des variables, un shell uefi, ...) et Secure Boot est désactivé par défaut.
•.Ce fichiers est à intégrer dans la commande qemu finale comme une "mémoire flash virtuelle"
•.La version un fichier est disponible dans le paquet ovmf installable depuis les dépôts Debian
$ sudo aptitude install ovmf
•.Le fichier à utiliser est OVMF.fd qui se situe en
/usr/share/ovmf/OVMF.fd
•.Dans les cas où il n'est pas nécessaire de modifier les variables efi, le fichier OVMF.fd est directement utilisable depuis le répertoire /usr/share/ovmf/OVMF. Pour amorcer en mode uefi, utiliser l'option
-bios /usr/share/ovmf/OVMF/OVMF.fd
•.Pour que les modifications apportées aux variables efi soient mémorisables, copier le fichier dans un répertoire local
$ mkdir debian-uefi && cd debian-uefi
$ cp /usr/share/ovmf/OVMF.fd ./
et utiliser l'option
-drive if=pflash,format=raw,file=./OVMF.fd
•.Remarques :
•.En cas de problème d'affichage (ce qui semble courant en mode uefi), tester différentes options, telles que
-vga virtio
•.Par défaut, plusieurs entrées réseaux sont inclues dans le menu d'amorçage uefi. Pour éviter qu'elles ne soient explorées et les temps d'attente correspondant, si on ne les utilise pas
•.soit modifier l'ordre d'exploration (voir plus loin)
•.soit supprimer l'accès réseau avec l'option
-net none
•.Lancer un système minimum avec
$ qemu-system-x86_64 -bios -drive if=pflash,format=raw,file=./OVMF.fd -net none
•.Le logo TianoCore, puis le shell UEFI interne à ovmf doivent apparaître
•.Afficher les entrées d'amorçage
Shell> bcfg boot dump
•.et par exemple échanger les entrées 2 (UEFI DVD-ROM) et 3 (EFI Internal Shell)
Shell> bcfg boot mv 3 2
•.Fermer et relancer l'émulation avec le même fichier OVMF.fd
$ qemu-system-x86_64 -bios ./OVMF.fd -net none
•.Lorsque le shell est ouvert, vérifier que la modification de l'ordre a été conservée.
Lorsqu'un système à émuler est équipé d'une entrée par défaut dans la partition ESP (cas des installateurs et distributions "live" debian par exemple), son amorçage est automatique. Pour le vérifier,
•.Lancer l'émulation d'un installateur ou d'une distribution live debian
$ qemu-system-x86_64 -drive if=pflash,format=raw,file=./OVMF.fd debian.iso
•.Peu après l'affichage du logo Tianacore, le menu de l'installateur doit s'afficher.
•.Pour accéder au menu uefi de la plateforme
•.Soit lancer la commande
$ qemu-system-x86_64 -bios -drive if=pflash,format=raw,file=./OVMF.fd -net none
et taper rapidement à plusieurs reprises sur la touche ESC jusqu'à ce que le menu apparaisse
•.Soit lancer la commande avec l'option -boot menu=on
$ qemu-system-x86_64 -drive if=pflash,format=raw,file=./OVMF.fd -boot menu=on
et taper sur la touche ESC pendant l'affichage du logo Tianocore et du message Boot options
•.Le menu uefi ovmf doit s'aficher
•.A titre d'exemple, lancer l'émulation minimum d'un installateur ou d'une distribution live debian
$ qemu-system-x86_64 -bios -drive if=pflash,format=raw,file=./OVMF.fd debian.iso -boot menu=on
•.Et ouvrir le menu uefi de la plateforme.
•.Le menu permet de modifier l'ordre d'exploration des périphériques à l'amorçage. Pour y accéder, sélectionner successivement les choix suivants
Boot Maintenance Manager >>
Boot Options >>
Change Boot Order
Si les périphériques réseau ne sont pas utilisés, il est intéressant de les placer en dernier dans la liste, afin que le temps de leur exploration ne soit pas pénalisant pour la découverte des périphériques de stockage
•.Le menu permet également de lancer un OS en le sélectionnant au moyen d'un explorateur de fichier. Sélectionner successivement les choix suivants (exemple d'un cd d'installation linux)
Boot Maintenance Manager >>
Boot From File >>
Sélectionner le volume dans la liste >> CDROM >>
Sélectionner la partition >> efi
Sélectionner le répertoire >> <boot>
Sélectionner le fichier >> Grubx64.efi
•.Utiliser la commande suivante en adaptant la configuration mémoire, processeur, carte graphique, en fonction de l'hôte. Il n'est pas nécessaire que le fichier OVMF.d soit modifiable, on peut donc utiliser directement la version disponible en /usr/share/ovmf
$ qemu-system-x86_64 -m 2048 -smp 4 -enable-kvm -cpu host \
-drive file=debian.iso,format=raw,media=cdrom -boot d \
-bios /usr/share/ovmf/OVMF.fd -vga virtio
Note : L'option -vga virtio a été ajoutée pour prendre en compte des problèmes d'affichage
•.Créer le disque sur lequel aura lieu l'installation
$ qemu-img create -f qcow2 debian.qcow2 20G
•.Lancer la commande d'installation, adapter la configuration mémoire, processeur, graphique, en fonction de l'hôte. Utiliser une copie dédiée du fichier OVMF.d en espace utilisateur afin que les modifications effectuées par Grub lors de l'installation soient conservées en mémoire
$ qemu-system-x86_64 -m 2048 -smp 4 -enable-kvm -cpu host -vga virtio \
-drive file=debian.iso,format=raw,media=cdrom -boot d \
-drive media=disk,format=qcow2,file=debian.qcow2 \
-drive if=pflash,format=raw,file=./OVMF.fd
Note : L'option -vga virtio a été ajoutée pour prendre en compte des problèmes d'affichage
•.L'installation se déroule comme dans une installation "réelle"
•.Redémarrer en utilisant le même fichier ./OVMF.fd que celui utilisé pour l'installation. Le démarrage du système installé doit-être immédiat
$ qemu-system-x86_64 -m 2048 -smp 4 -enable-kvm -cpu host -vga virtio \
-drive media=disk,format=qcow2,file=debian.qcow2 -boot c\
-drive if=pflash,format=raw,file=./OVMF.fd
Le partage de dossier décrit ici est basé sur le serveur Samba inclus dans qemu et le système de fichier CIFS
•.Dans l'hôte,
•.Installer samba :
$ sudo aptitude install samba
•.Créer un dossier à partager
$ mkdir dossier_commun
•.Lancer le système à émuler avec les options
-net nic -net user,smb=/chemin_absolu_dossier_commun_dans l'hôte/
•. Dans l'invité
•.Installer les utilitaires du système de fichier cifs
$ sudo aptitude install cifs-utils
•.Créer le point de montage
$ mkdir dossier_commun
•.Monter le dossier partagé, avec les options souhaitées
$ sudo mount -t cifs //10.0.2.4/qemu/ dossier_commun -o uid=1000,gid=1000
•.Démontage
$ sudo umount -a -t cifs -l
•.Pour un montage automatique au démarrage, modifier fstab
//10.0.2.4/qemu /chemin_dossier_commun_dans l'invité/ cifs password=,uid=1000,gid=1000 0 0