« Qemu » : différence entre les versions

De Wiki doc

(→‎Passer un périphérique bloc : Ajout de la méthode "VirtIO".)
 
(52 versions intermédiaires par 2 utilisateurs non affichées)
Ligne 1 : Ligne 1 :
[[Category:virtualisation]]
[[Category:virtualisation]]
==Prérequis==
=Prérequis=


* [[Open vSwitch|L'installation d'Open vSwitch et création d'un  commutateur virtuel]]
* [[Open vSwitch|L'installation d'Open vSwitch et création d'un  commutateur virtuel]]
* Vérifier que les instructions de virtualisations sont supportés et activés : <source lang="bash" inline>egrep '^flags.*(vmx|svm)' /proc/cpuinfo</source>. Si un résultat s'affiche, c'est que c'est bon.


==Installation==
=Installation=


Qemu est dispnible dans les dépots Debian
Qemu est disponible dans les dépôts Debian


  # apt install qemu-system
  apt install qemu-system-x86-64 openvswitch-switch


==Script réseau==
Création de l’arborescence de travail (c'est un choix personnel, l’intérêt de cette solution est justement qu'elle n'impose rien)
mkdir -p /etc/qemu/{iso,disques,machines}
 
=Script réseau=
Pour que la machine virtuelle puise se connecter sur Open vSwitch, des scripts sont a créer.
Pour que la machine virtuelle puise se connecter sur Open vSwitch, des scripts sont a créer.


{{attention|Chaque vlan doit avoir un script de démarrage de l’interface. le script d’arrêt est commun a tous les vlans}}
{{Info|Ce script met dynamiquement les interfaces réseaux dans le VLAN indiqué dans la variable <source lang="bash" inline>ifname</source> de la [[#D.C3.A9marrage_classique|commande de démarrage]] d'une machine virtuelle. Il suffit de mettre l'id du VLAN après un trait de soulignement pour que le script puisse le gérer. [[#D.C3.A9marrage_classique|Dans l'exemple]], ma machine sera dans le VLAN 180.}}


{{astuce|Les scripts peuvent être dans l'arborescence que vous voulez}}
{{astuce|Les scripts peuvent être dans l'arborescence que vous voulez puisque vous spécifiez leur chemin dans la [[#D.C3.A9marrage_classique|commande de démarrage]] de la machine virtuelle.}}
 
==Script de démarrage de l’interface==
vim /etc/qemu/qemu-ifup
<source lang="sh">
#!/bin/sh
#Séparation du nom de l'interface de l'id du VLAN utilisé
#nomIface=`echo $1 | cut -f 1 -d '_'`
idVlan=`echo $1 | cut -f 2 -d '_'`


===Script de démarrage de l’interface===
<source lang="bash">
#!/bin/bash
OVSCOMMUT=br0
OVSCOMMUT=br0
TAG=100
OVSTAG=$idVlan
echo "Execution de /etc/qemu/qemu-ifup"
echo "Allumage de $1 pour l'ajout au pont OVS..."
ip link set $1 up promisc on
echo "Ajout de $1 à ${OVSCOMMUT}..."
ovs-vsctl --may-exist add-br ${OVSCOMMUT}
ovs-vsctl --may-exist add-br ${OVSCOMMUT}
ovs-vsctl --if-exists del-port ${OVSCOMMUT} $1
ovs-vsctl --if-exists del-port ${OVSCOMMUT} $1
ovs-vsctl --may-exist add-port ${OVSCOMMUT} $1
ovs-vsctl --may-exist add-port ${OVSCOMMUT} $1
ovs-vsctl --if-exists set port $1 tag=${TAG}
ovs-vsctl --if-exists set port $1 tag=${OVSTAG}
ip link set $1 up
sleep 2
</source>
</source>


Variables:
Variables:
* OVSCOMMUT : interface de votre commutateur virtuel
* '''OVSCOMMUT''' : interface de votre commutateur virtuel
* TAG : numéro du Vlan
* '''OVSTAG''' : numéro du Vlan


===Script de d'arrêt de l’interface===
==Script de d'arrêt de l’interface==
<source lang="bash">
vim /etc/qemu/qemu-ifdown
#!/bin/bash
<source lang="sh">
#!/bin/sh
OVSCOMMUT=br0
OVSCOMMUT=br0
echo "Execution de /etc/qemu/qemu-ifdown"
echo "Arrêt de $1 pour la suppression au pont OVS..."
ip link set $1 down
echo "Suppression de $1 à ${OVSCOMMUT}..."
ovs-vsctl --if-exists del-port ${OVSCOMMUT} $1
ovs-vsctl --if-exists del-port ${OVSCOMMUT} $1
echo "Suppression de $1..."
ip link delete dev $1
</source>
</source>


Variable:
Variable:
* OVSCOMMUT : interface de votre commutateur virtuel
* '''OVSCOMMUT''' : interface de votre commutateur virtuel


==Création d'une machine virtuelle==
==Modifier les droits==
Ajouter les droits d’exécutions aux scripts
chmod +x /etc/qemu/qemu-if*
 
=Création d'une machine virtuelle=


Création d'un disque virtuel
Création d'un disque virtuel


  # qemu-img create -f qcow2 hdd.qcow2 10G
  qemu-img create -f qcow2 /etc/qemu/disques/hdd.qcow2 10G


Paramètres:
Paramètres:
Ligne 54 : Ligne 78 :
* '''10G''' : taille attribué au disque
* '''10G''' : taille attribué au disque


==Démarrage de la machine virtuelle==
=Démarrage de la machine virtuelle=


  # qemu-system-x86_64 -m 1024 -name host1 -net nic,macaddr=52:54:00:00:01:00 -net tap,ifname=r1-eth0,script=/root/qemu-ifup,downscript=/root/qemu-ifdown --cdrom /srv/iso/debian-live-8.7.1-amd64-lxde-desktop.iso -vnc :6 --enable-kvm
==Démarrage classique==
 
  qemu-system-x86_64 -m 1024 -name host1 -vnc :6 --enable-kvm -cpu host -smp cores=2,threads=1,sockets=1 -net nic,macaddr=52:54:00:12:34:56 -net tap,ifname=host1_180,script=/etc/qemu/qemu-ifup,downscript=/etc/qemu/qemu-ifdown -boot c --cdrom /etc/qemu/iso/debian-live-8.7.1-amd64-lxde-bureau.iso -hda /etc/qemu/disques/hdd.qcow2


Paramètres:
Paramètres:
* '''-m 1024''' : mémoire attribué a la machine virtuelle
* '''-m 1024''' : mémoire attribué a la machine virtuelle (en octets)
* '''-name''' : nom de la machine virtuelle
* '''-name''' : nom de la machine virtuelle
* '''-net  nic,macaddr=52:54:00:00:01:00''' : l'adresse MAC de la machine virtuelle
* '''-vnc :6''' : Utilisation de [https://fr.wikipedia.org/wiki/Virtual_Network_Computing VNC] sur le port 5906
* '''-net tap,ifname=r1-eth0,script=/root/qemu-ifup,downscript=/root/qemu-ifdown''' : nom de l'interface réseau sur la machine maître suivie des scripts précédemment créé
* '''--enable-kvm''' : Permet la prise en charge des instructions de virtualisation du processeur
* '''--cdrom /srv/iso/debian-live-8.7.1-amd64-lxde-desktop.iso''' : lien vers l'ISO du CD-ROM
* '''-cpu host''' : Émule un processeur KVM avec théoriquement les mêmes fonctionnalités que l'hôte (ne fonctionne qu'avec le paramètre ''--enable-kvm''). Voir le paramètre ''-cpu help'' pour la liste des possibilités. Il est possible d'ajouter des [https://blog.wikichoon.com/2014/07/enabling-hyper-v-enlightenments-with-kvm.html éclaircissements de para-virtualisation Hyper-V] pour optimiser les performance de la virtualisation avec des invités Windows: '''-cpu host,hv_relaxed,hv_spinlocks=0x1fff,hv_vapic,hv_time'''
* '''-vnc :6''' : Utilisation de vnc sur le port 6
* '''-smp cores=2,threads=1,sockets=1''' : Émule un [https://fr.wikipedia.org/wiki/Symmetric_multiprocessing multiprocesseur symétrique à mémoire partagée] (on peut mettre plusieurs cœurs et plusieurs processeurs sur une machine)
* '''--enable-kvm''' : Permet la prise en charge des la virtualisation du processeur
* '''-net  nic,macaddr=52:54:00:12:34:57''' : l'adresse MAC de la machine virtuelle ([[Lxc#Script_de_g.C3.A9n.C3.A9ration_d.27adresse_MAC|voir]])
* '''-net tap,ifname=host1_180,script=/etc/qemu/qemu-ifup,downscript=/etc/qemu/qemu-ifdown''' : nom de l'interface réseau sur la machine maître (limité à 15 caractères) suivie des scripts précédemment créés. Le ''_180'' permet de remplir la variable ''$idVlan'' du [[#Script_de_d.C3.A9marrage_de_l.E2.80.99interface|script de démarrage de l'interface réseau]]. Les directives '''-net''' peuvent être remplacées par ''-device virtio-net-pci,netdev=network0,mac=$tap_mac -netdev tap,id=network0,ifname=$int_tap,script=no,downscript=no''
* '''-boot c''' : Démarre sur le disque dur. Le disque étant vierge, il démarre le cdrom pour l'installation et redémarrera sur le disque dur la prochaine fois ([https://wiki.gentoo.org/wiki/QEMU/Options#Boot_order valeurs possible] : c|d|n - disque principal|cdrom|réseau)
* '''--cdrom /srv/iso/debian-live-8.7.1-amd64-lxde-bureau.iso''' : lien vers l'ISO du CD-ROM
* '''-hda /root/hdd.qcow2''' : lien vers le disque virtuel précédemment créé. Peut être remplacer par '''-drive file=/root/hdd.qcow2,if=virtio''' pour utiliser le [https://www.linux-kvm.org/page/Boot_from_virtio_block_device pilote Virtio] et avoir de meilleurs performances (non compatible nativement avec Windows)
 
==Démarrage sur squashfs==
===En lecture seule===
qemu-system-x86_64 -m 1024 -name pxe-doc -vnc :3 --enable-kvm -cpu host -smp cores=1,threads=1,sockets=1 -net nic,macaddr=52:54:00:12:34:53 -net tap,ifname=pxe-doc_182,script=/etc/qemu/qemu-ifup,downscript=/etc/qemu/qemu-ifdown -boot c -append 'root=/dev/sda net.ifnames=0' -kernel /var/lib/lxc/lxc-pxe/rootfs/srv/tftp/noyaux/stretch/vmlinuz-4.13.0-custom -initrd /var/lib/lxc/lxc-pxe/rootfs/srv/tftp/noyaux/stretch/initrd.img-4.13.0-custom -hda /var/lib/lxc/lxc-pxe/rootfs/srv/tftp/images/stretch-pxe.squashfs
 
Les 3 éléments importants sont:
* '''-append''': définit les paramètres du noyau. Le pré-requis indispensable est la valeur '''root=/dev/sda''' qui va indiquer au noyau d'utiliser ce périphérique comme '''/''' (il est émulé. Il n'existe pas réellement).
* '''-kernel''': Indique le chemin du noyau
* '''-initrd''': Indique le chemin de l'image initrd
 
===En lecture/écriture===
La lecture seule ne convient qu'à certains cas et devient vite limitante. Pour passer en lecture/écriture, il faut préciser le paramètre <source lang="bash" inline>boot=live</source> au noyau et ajouter un périphérique bloc contenant <source lang="bash" inline>/live/<IMAGE_SQUASHFS></source>.
 
{{info|Pour utiliser le paramètre <source lang="bash" inline>boot=live</source>, un module "live" doit être présent dans l'initrd. Ce module est installé par le paquet ''live-boot'' sous Debian (expliqué [[Squashfs#Installation_2|ici]]) et ''casper'' sous Ubuntu. C'est lui qui scanne les périphériques au démarrage pour trouver un ''/live'' contenant le disque système.}}
 
Vous pouvez soit utiliser un vrai périphérique soit utiliser [[losetup]] afin d'en faire un virtuel (j'ai fait le test en le formatant en vFAT avec un <source lang="bash" inline>mkfs.vfat /dev/loop0</source>), mais la méthode que je préfère est la [[#Disque_FAT_virtuel|méthode VVFAT décrite plus bas]].
 
Dans tout les cas, il convient de préciser un second disque à votre machine virtuelle. Voici la ligne que j'ai utilisé et qui fonctionne:
qemu-system-x86_64 -m 1024 -name pxe-doc --enable-kvm -vnc :3 -cpu host -smp cores=1,threads=1,sockets=1 -net nic,macaddr=52:5e:0a:12:34:53 -boot c -append 'root=/dev/sda net.ifnames=0 boot=live' -kernel vmlinuz-2 -initrd live/initrd.img-2 -drive format=raw,media=cdrom,file=/tmp/live/live/stretch-pxe.squashfs,readonly -drive format=raw,file=fat:rw:/tmp/live
 
''Note: Je n'ai pas trouvé comment mettre VVFAT en lecture seule dans le cas présent. En effet, le <source lang="bash" inline>file=fat:rw</source> ne peut pas être mis en <source lang="bash" inline>ro</source> avec le paramètre <source lang="bash" inline>format=raw</source>. Le paramètre <source lang="bash" inline>media=cdrom</source> existe mais il n'est pas scanné par le module live du noyau. Je le laisse donc en rw, ce n'est pas génant en soit.''
 
{{astuce|Dans le cas d'un périphérique loop (créé avec losetup), on peut utiliser le traditionnel ''-hdb''. À noter qu'il est tout à fait possible simuler une clé USB en utilisant la [[#Passer_un_p.C3.A9riph.C3.A9rique_bloc|méthode décrite plus bas]].}}
 
J'ai constaté que certains mettaient le paramètre <source lang="bash" inline>union=aufs</source> au noyau. Cela peut peut-être utile pour les vieux systèmes si la méthode d'union n'est pas automatique ([[Aufs]] a été remplacé par [[Overlayfs]] dans Linux 3.18).
 
===Source de la section===
* https://manpages.debian.org/testing/live-boot-doc/live-boot.7.fr.html
 
=Raccourcis clavier=
Un ensemble de séquences clavier sont passables à ''Qemu'' depuis le terminal ayant servis à le lancer. Elles permettent diverses actions :
 
* arrêt de la machine virtuelle : <source lang="bash" inline><crtl> + a x</source>
* passer en [[#Console de commandes|mode commandes]] : <source lang="bash" inline><crtl> + a c</source> (refaire la séquence revient sur la machine virtuelle)
 
 
Sources :
* https://stackoverflow.com/questions/14165158/how-to-switch-to-qemu-monitor-console-when-running-with-curses
* https://superuser.com/questions/1087859/how-to-quit-the-qemu-monitor-when-not-using-a-gui
 
=Console de commandes=
''Qemu'' dispose d'une console permettant d’interagir avec la machine en fonctionnement.
 
==Console via terminal courant==
Avec cette option, la console vient s'attacher au terminal exécutant la MV. c'est une bonne façon de rationaliser un shell inutilisable.
-monitor stdio
 
==Console via terminal externe==
L'outil donne également la possibilité de créer un TTY d'écoute sur lequel on vient s'attacher pour contrôler la liaison série de la machine virtuelle.
-monitor pty
 
''Note: Qemu précise quel TTY il a créé (/dev/pts/9 dans mon exemple) dans le terminal d'exécution. Il est bien sûr possible d'exécuter autant de MV avec ce paramètre que l'on veut, Qemu créera autant de TTY que nécessaire.''
 
==Console via telnet==
De la même manière, il est possible de faire écouter cette console sur le réseau.
-monitor tcp:127.0.0.1:41127,server,nowait
 
On s'y connectera via la traditionnelle commande <source lang="bash" inline>telnet</source>:
telnet 127.0.0.1 41127
 
==Source de la section==
* https://qemu.weilnetz.de/doc/qemu-doc.html#Debug_002fExpert-options
 
=Modes d'affichage=
Qemu supporte divers modes d'affichage. En l'absence de précisions, il utilisera le gestionnaire de fenêtre de l'interface graphique si présente, sinon, il se terminera en erreur. Il est également possible d'exécuter une machine virtuelle sans affichage ou via le réseau.
 
==Affichage classique==
Comme précisé, l'affichage classique s'effectuera en l'absence de paramètre d'affichage. Dans ce mode, une fenêtre du compositeur graphique (Xorg, Wayland, Mir...) s'ouvrira et le fait de la fermer, terminera le processus de la machine virtuelle (extinction électrique).
qemu-system-x86_64 -m 512 --boot n --enable-kvm
 
==Affichage GTK==
Si ''Qemu'' a été compilé avec le support de ''GTK'' et que Linux est au moins en version 4.4, il est possible d'utiliser l'accélération ''OpenGL'' (''Virgl'') avec l'argument suivant:
-vga virtio -display gtk,gl=on
 
''Note: le support de l'accélération graphique est vérifiable via la commande <source lang="bash" inline>dmesg | grep '\[drm\]'</source>.''
 
===Sources de la section===
* https://nixos.wiki/wiki/IGVT-g
* https://bbs.archlinux.org/viewtopic.php?id=219219
* https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/Virtualization_Deployment_and_Administration_Guide/sect-KVM_Para_virtualized_virtio_Drivers-Using_KVM_virtio_drivers_for_GPU_devices.html
 
==Affichage liaison série==
===Liaison série via terminal courant===
Lors de l'exécution d'une machine virtuelle, ''Qemu'' ne rend pas la main (à moins d'utiliser le paramètre <source lang="bash" inline>-daemonize</source>). Il est possible d'utiliser le terminal ainsi occupé pour y afficher un TTY série attaché à la MV (il faudra bien sûr [[Paramètres_linux#Activer_un_shell_sur_un_port_s.C3.A9rie|passer un paramètre au noyau]] de l'invité pour l'activer) avec ce peramètre:
-serial mon:stdio -nographic
''Note: Le paramètre <source lang="bash" inline>-nographic</source> peut être retiré si vous voulez afficher une fenêtre graphique en plus.''
 
===Liaison série via terminal externe===
De même que pour l'affichage de la console, il est possible de rediriger la liaison série vers un TTY créé à la volée.
-serial pty
 
Il est également possible de préciser un terminal spécifique (ça n'a toutefois pas l'air bien stable d'après mes tests...)
-serial /dev/pts/9
 
===Liaison série via telnet===
Cette configuration peut s'avérer utile lorsque vous désirez administrer une machine virtuelle qui est isolé dans un VLAN ou simplement inaccessible depuis votre machine d'administration. Il suffit d'initier une connexion telnet à l'hyperviseur qui va renvoyer le retour du TTY de l'invité via une liaison série (configuré via un [[Paramètres_linux#Activer_un_shell_sur_un_port_s.C3.A9rie|paramètre passé au noyau]] de l'invité). On a ainsi un contrôle textuel (copier/coller possible) de la MV sans pour autant avoir un accès réseau à celle-ci.
-nographic -serial telnet:0.0.0.0:5001,server,nowait -monitor none
 
Les 3 éléments importants sont:
* '''-nographic''': permet l'utilisation de l'affichage telnet en désactivant tout les autres types d'affichage
* '''-serial''': définit le port d'écoute du serveur telnet de l'hyperviseur
* '''-monitor none''': désactive la console qemu. Si vous la voulez, vous pouvez soit supprimer ce paramètre pour entrer directement dedans à l'exécution de la commande, soit la faire écouter sur un socket réseau avec les options suivantes: '''-monitor tcp:127.0.0.1:41127,server,nowait'''
Une fois exécuté, la MV est accessible via la traditionnelle commande <source lang="bash" inline>telnet</source> en pointant vers l'adresse IP de votre hyperviseur suivi du port d'écoute définit dans la commande.
 
===Sources de la section===
* https://qemu.weilnetz.de/doc/qemu-doc.html#Character-device-options
* https://qemu.weilnetz.de/doc/qemu-doc.html#Debug_002fExpert-options
 
==Affichage réseau==
===Via VNC===
C'est l'affichage que j'ai utilisé pour mon exemple dans le démarrage d'une machine virtuelle. Il est possible de sécuriser l'accès à cet affichage via mot de passe et TLS.
qemu-system-x86_64 -m 512 --boot n --enable-kvm -vnc :0
''Le ''':0''' est en fait le numéro de port en omettant le début qui est standard à VNC. Lire 5900. Si cela avais été ''':6''', le port aurai été 5906.''
 
Pour la partie cliente, on peut utiliser ''virt-viewer'', ''Vinagre'' ou ''gvncviewer''
gvncviewer 127.0.0.1:0
 
====Accès par mot de passe====
J'ai testé mais n'ai été convaincu par cette possibilité. D'apprès la [https://qemu.weilnetz.de/doc/qemu-doc.html#vnc_005fsec_005fpassword documentation], l'ajout du paramètre '''password''' aurai pour effet de demandé un mot de passe (limité à 8 caractères maximums) à l'exécution de la machine (ce qui n'arrive pas). Donc j'en déduis que ça ne fonctionne pas et de toute façon la sécurité est jugé merdique par les dévelopeurs eux même donc aucun intéret. Si vous voulez de la sécurité, utilisez SPICE ou passé par de la tunnellisation (SSH ou VPN) qui elle est sécurisé.
 
Pour la partie cliente, on peut utiliser ''virt-viewer'', ''Vinagre'' ou ''spice-client-gtk'' (qui s'utilise via la commande ''spicy'').
 
====Accès via TLS====
Usant de VNC uniquement dans mon réseau local ou via un VPN, je n'ai pas besoin de cette fonctionnalité et je ne l'ai pas testé. Si le cœur vous en dit, vous trouverez les explications [https://qemu.weilnetz.de/doc/qemu-doc.html#vnc_005fsec_005fcertificate ici].
 
===Via SPICE===
SPICE est le protocole d'affichage historique de KVM. Il a été développé par la société Qumranet (qui a également créé KVM) et libéré par Red Hat qui a racheté l'entreprise le 4 septembre 2008.
 
====Accès sans mot de passe====
'''Partie serveur'''
qemu-system-x86_64 -m 512 --boot n --enable-kvm -spice port=5905,addr=0.0.0.0,disable-ticketing
''Avec '''addr=0.0.0.0''', on autorise les connexions de n'importe quelle adresse cliente.''
 
'''Partie cliente'''
spicy -h 127.0.0.1 -p 5905
 
====Accès par mot de passe====
'''Partie serveur'''
qemu-system-x86_64 -m 512 --boot n --enable-kvm -spice port=5905,addr=0.0.0.0,password=secret123
 
'''Partie cliente'''
spicy -h 127.0.0.1 -p 5905 -w secret123
 
====Accès via TLS====
Non testé mais peut être intéressante.
 
====Accès via socket UNIX====
'''Partie serveur'''
-spice disable-ticketing,unix,addr=/tmp/toto.sock,gl=on
 
'''Partie cliente'''
remote-viewer spice+unix:///tmp/toto.sock
 
====Source de la section====
* https://fedoraproject.org/wiki/Features/Spice
* https://www.linuxquestions.org/questions/linux-virtualization-and-cloud-90/remote-viewer-spice-qemu-and-unix-domain-socket-how-to-connect-4175571914/
 
=Partage de fichiers=
Il est possible d'établir un partage de fichiers entre l'hôte et les invités en utilisant les fonctionnalités de ''VirtIO''.
 
==9P2000==
[https://en.wikipedia.org/wiki/9P_(protocol) 9P] (appelé [https://en.wikipedia.org/wiki/Plan_9_from_Bell_Labs#9P_protocol 9P2000] depuis la version 4 de [https://fr.wikipedia.org/wiki/Plan_9_from_Bell_Labs Plan 9]) est un protocole développé à l’origine pour le système d'exploitation Plan 9 des [https://fr.wikipedia.org/wiki/Laboratoires_Bell laboratoires Bell] (''Bell Labs'') permettant l'échange d'informations entre processus. Il est était autrefois utilisé pour permettre le transfert de données entre les programmes d'un client et d'un serveur. Il est aujourd'hui tout indiqué pour établir un système de fichiers entre un hyperviseur et des machines virtuelles. Le pilote ''VirtIO'' du [[Paramètres linux|noyau Linux]] gérant ce protocole, il n'y a aucun additif logiciel à apporter pour mettre en place ''9P''.
 
===Partie hôte===
Création du répertoire à partager
mkdir /tmp/partage
 
Paramètre à utiliser avec ''Qemu'' au moment de lancer la machine virtuelle
-fsdev local,security_model=passthrough,id=fsdev0,path=/tmp/partage -device virtio-9p-pci,id=fs0,fsdev=fsdev0,mount_tag=partage
 
le raccourci [https://qemu.weilnetz.de/doc/5.2/system/invocation.html?highlight=-virtfs suivant] peut aussi être utilisé
-virtfs local,path=/tmp/partage,mount_tag=partage,security_model=passthrough
 
===Partie invité===
Création du point de montage
mkdir /tmp/partage_hôte
 
Montage du volume ''9P2000''
mount -t 9p -o trans=virtio,version=9p2000.L partage /tmp/partage_hôte/
 
===Sources de la section===
* https://www.linux-kvm.org/page/9p_virtio
* https://wiki.qemu.org/Documentation/9psetup
 
==VirtIO-fs==
Partie à faire. Source d'information: https://virtio-fs.gitlab.io/howto-qemu.html
 
=Passer un périphérique à une machine=
==Passer un périphérique bloc==
Dans le cas d'une installation sans réseau ou d'une machine Windows (ce qui revient un peu au même...), pouvoir transférer des fichiers via un périphérique bloc branché à la machine invité peut s’avérer intéressant.
 
En tant qu{{'}}'USB Mass Storage'' :
 
<source lang="bash">
-drive if=none,id=stick,file=/dev/sda  \
      -device nec-usb-xhci,id=xhci      \
      -device usb-storage,bus=xhci.0,drive=stick
</source>
 
En tant que ''VirtIO'' :
 
<source lang="bash">
-device virtio-scsi-pci,id=scsi0 \
      -drive file=/dev/sda,if=none,format=raw,discard=unmap,aio=native,cache=none,id=someid \
      -device scsi-hd,drive=someid,bus=scsi0.0
</source>
 
===Source de la section===
* https://git.qemu.org/?p=qemu.git;a=blob_plain;f=docs/usb-storage.txt
** Via https://qemu.weilnetz.de/doc/qemu-doc.html#usb_005fdevices
* https://wiki.gentoo.org/wiki/QEMU/Options#Hard_drive
 
==Passer un clavier et une souris==
Avec certains systèmes, la gestion de la souris au survole de Qemu est catastrophique. Il est donc utile de pouvoir donner des périphériques d'entrés/sorties directement à l'invité.
 
Il existe deux méthodes:
* Avec l'identifiant du bus (simple mais variable à chaque branchement - pratique pour faire un test)
* Avec l'identifiant du vendeur/produit (un peu plus chiant à écrire mais invariable)
 
Les périphériques s'identifient avec la commande:
lsusb
 
qui donne comme résultat (j'ai branché un clavier Dell RT7D50 et une souris Logitech M115 USB sur un PC portable):
 
<source lang="bash">
Bus 002 Device 003: ID 0bda:8153 Realtek Semiconductor Corp.
Bus 002 Device 002: ID 2109:0813 VIA Labs, Inc.
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 004: ID 04f3:21d5 Elan Microelectronics Corp.
Bus 001 Device 003: ID 0cf3:e300 Atheros Communications, Inc.
Bus 001 Device 009: ID 413c:2005 Dell Computer Corp. RT7D50 Keyboard
Bus 001 Device 002: ID 2109:2813 VIA Labs, Inc.
Bus 001 Device 005: ID 1bcf:2b95 Sunplus Innovation Technology Inc.
Bus 001 Device 008: ID 046d:c058 Logitech, Inc. M115 Mouse
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
</source>
 
Il est à noter que l'adresse du bus n'a aucun rapport avec tel ou tel port USB physique du PC. Après un débranchement/rebranchement, les valeurs changent...
 
Pour un usage avec un utilisateur standard, il faut donner les droits au périphérique. Ceci peut ce faire soit via un:
chmod 666 /dev/bus/usb/001/08
 
soit via une règle Udev:
vim /etc/udev/rules.d/70-persistent-net.rules
 
SUBSYSTEM=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c058", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVendor}=="413c", ATTR{idProduct}=="2005", MODE="0666"
 
Il faut ensuite recharger les règles udev (sinon un redémarrage s'en chargera)
udevadm control --reload-rules && udevadm trigger
 
===Avec l'identifiant du bus===
-usb -device usb-host,hostbus=1,hostaddr=8 \
-usb -device usb-host,hostbus=1,hostaddr=9
 
===Avec l'identifiant du produit===
-usb -device usb-host,vendorid=0x046d,productid=0xc058 \
-usb -device usb-host,vendorid=0x413c,productid=0x2005
 
===Sources de la section===
* https://qemu.weilnetz.de/doc/qemu-doc.html#usb_005fdevices
* https://askubuntu.com/questions/15570/configure-udev-to-change-permissions-on-usb-hid-device
* https://askubuntu.com/questions/978552/how-to-make-libusb-work-as-non-root
* https://unix.stackexchange.com/questions/39370/how-to-reload-udev-rules-without-reboot
* http://www.linux-kvm.org/page/USB_Host_Device_Assigned_to_Guest
 
==Passer un USB à une machine==
{{attention|Méthode à peaufiner...}}
 
Il peut être utile d'envoyer un périphérique USB dans une machine virtuelle (une caméra dans mon exemple). Pour ce faire, il faut identifier le numéro du bus sur lequel est branché l'équipement avec un
lsusb
Ce qui dans mon cas, me donne: <source lang="bash" inline>Bus 003 Device 005: ID 0bda:58b0 Realtek Semiconductor Corp.</source>
 
Il suffit ensuite de passer les paramètres suivants à '''Qemu'''
-device usb-ehci,id=ehci -device usb-host,bus=ehci.0,vendorid=0x0bda,productid=0x58b0
 
Je retrouve bien un <source lang="bash" inline>/dev/video0</source> dans ma machine virtuelle.
 
===Source de la section===
* '''Commentaire numéro 5''': https://bugs.launchpad.net/qemu/+bug/1385934
 
=RAM à chaud=
Il est possible d'ajouter et de retirer de la RAM à chaud dans une machine virtuelle. Cette fonction s'appelle ''virtio-balloon'' et un pilote doit être installé sur les machines invitées (avec Windows, ce pilote est accessible dans [https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/latest-virtio/virtio-win.iso cet ISO] - je n'ai pas réussi à le faire fonctionner). Sous Linux, ce pilote est intégré au noyau (comme d'habitude j'ai envi de dire). Il suffi donc de passer l'argument suivant à ''Qemu'':
-device virtio-balloon
 
La machine va démarrer avec la quantité de RAM définie avec l'argument <source lang="bash" inline>-m</source> et il sera possible de changer cette valeur dynamiquement via la console Qemu en y tapant la commande suivante:
balloon 2048
''pour passer la machine à 2 Go de RAM.''
 
On peut voir la RAM allouée via la commande suivante:
info balloon
 
==Source de la section==
* https://www.youtube.com/watch?v=gDYJ6XlVyvc
 
=Images disque=
==Attacher un disque==
===Disque RAW===
-drive format=raw,media=$1,file=$2
* '''$1''': ''disk'' ou ''cdrom'' (le paramètre '',readonly'' peut être définit pour ''cdrom'')
* '''$2''': Chemin de l'image disque ou du disque physique
 
====Sources de la section====
* https://en.wikibooks.org/wiki/QEMU/Devices/Storage
* https://qemu.weilnetz.de/doc/qemu-doc.html#index-_002ddrive
 
===Disque FAT virtuel===
Cette fonctionnalité(abrégé VVFAT) déchire tout simplement sa race. Elle permet de présenter un répertoire de l'hôte sous forme de périphérique bloc à la machine virtuelle ! Ainsi, dans une configuration sans réseau, il est possible de donner des fichiers à la machine invité. Un autre usage possible (celui que je préfère) lors de la combinaison avec le module ''live'' du noyau Linux est d'activer le démarrage en lecture/écriture via un ''unionfs'' d'un disque [[Squashfs]]. Cette fonctionnalité est exploité un peu plus haut.
-drive format=raw,file=fat:rw:/tmp/live
 
{{attention|La documentation officielle donne 3 choses à ne jamais faire avec cette fonction:
* Utiliser des noms de fichier non-ASCII
* Utiliser l'option <source lang="bash" inline>-snapshot</source> en même temps que le paramètre <source lang="bash" inline>rw</source> (sauf avec la fonction ''loadvm'')
* Écrire dans le répertoire servant de FAT à l'invité lorsque celui-ci est en fonctionnement (j'ai testé et ça corrompt tout le contenu du système FAT... - il faut re-copier/coller les fichiers voulus dedans à l'issue pour remettre ça en ordre)
}}
 
====Source de la section====
* https://lists.gnu.org/archive/html/qemu-devel/2009-03/msg01276.html
* https://qemu.weilnetz.de/doc/qemu-doc.html#disk_005fimages_005ffat_005fimages
 
==Changer de CD-ROM==
Il est possible de changer de fichier ''ISO'' lorsque la machine virtuelle est sous tension via la [[#Console_de_commandes|console Qemu]].
 
Identifier le lecteur
info block
 
''Note: on peut voir l'ISO qui est actuellement inséré dans le lecteur.''
 
Changer d'ISO
change ide1-cd0 /tmp/dsl-4.4.10.iso
 
===Source de la section===
* https://www.linux-kvm.org/page/Change_cdrom
 
==Convertir une image disque==
{{info|La conversion semble impossible d'un disque à l'autre. Il faut être sur le même système de fichier pour la totalité de l'opération.}}
 
===Image OVA===
Une image OVA est une exportation de machine virtuelle VMWare. Elle se présente sous la forme d'une archive ''tar'' avec comme extension ''.ova'' contenant un descriptif de la machine virtuelle (RAM, CPU, emplacement disque...) au format ''XML'' avec une extension ''.ovf'', un disque virtuel en ''.vmdk'' et une empreinte ''SHA1'' des deux fichiers mentionnés dans un document texte en ''.mf''.
 
Bien que Qemu sache gérer les VMDK, il est conseillé de travailler avec du Qcow2.
 
'''Désarchivage du ''.ova'''''
tar xvf archive.ova
 
'''Conversion du VMDK en Qcow2'''
qemu-img convert -O qcow2 image_source.vmdk image_destination.qcow2
 
'''Source'''
* https://edoceo.com/notabene/ova-to-vmdk-to-qcow2
 
===Réduire une image Qcow2===
Un disque virtuel Qcow2 étant un fichier creux, il se rempli au fur et à mesure de son utilisation jusqu'à atteindre la limite fixée lors de sa création (même après suppression des fichiers de l'invité, ces derniers sont remplacés par des zéros). Les zéros qui remplissent ses espaces sont alors ré-écrits à mesures des modifications du système de fichier invité. Afin de les purger, il faut reconvertir l'image dans son même format. Il est également possible d'appliquer une compression aux données déjà existantes (cette compression ne s'applique pas aux nouvelles données ajoutées après la conversion). Il est à noter que la conversion n'alter en rien les données. Si vous convertissez deux fois de suite une image et que vous faites un hash du résultat vous vous apercevrez qu'il est identique.
 
{{attention|Faites bien attention à ne pas donner la même ''destination+nom'' au fichier de sorti, sinon vous allez écraser le disque virtuel que vous tentez de réduire et donc tout niquer !}}
 
'''Récupérer les zéros'''
qemu-img convert -f qcow2 /tmp/image-src.qcow2 -O qcow2 /tmp/image-dst.qcow2
 
'''Compresser l'image'''
qemu-img convert -c -f qcow2 /tmp/image-src.qcow2 -O qcow2 /tmp/image-dst.qcow2
 
''Note: Ajout du paramètre <source lang="bash" inline>-c</source>.''
 
'''Source'''
* https://doc.ubuntu-fr.org/kvm
 
==Monter une image disque==
Il est possible de monter l'image disque Qcow2 d'une machine virtuelle sur l'hôte afin de récupérer ce qui se trouve à l'intérieur ou d'y déposer des fichiers. Cette opération utilise le module noyau ''ndb'' non activé par défaut dans Debian.
 
===Montage===
modprobe nbd max_part=63
qemu-nbd -c /dev/nbd0 /tmp/ramdisk/windows.qcow2
mount /dev/nbd0p2 /mnt
 
===Dé-montage===
umount /mnt
qemu-nbd -d /dev/nbd0
rmmod nbd
 
===Source de la section===
* https://www.linuxunbound.com/2016/07/mounting-raw-and-qcow2-images/
 
=Virtualisation imbriquée=
La virtualisation imbriquée ([https://www.linux-kvm.org/page/Nested_Guests nested KVM]) permet de virtualiser (en utilisant l'accélération matérielle via les instructions CPU) dans une machine virtuelle (c'est de la virtualisation dans la virtualisation). Cette fonctionnalité est déclarée fonctionnelle mais expérimentale depuis février 2018. Pour l'activée, il suffit de passer au noyau Linux [[Paramètres linux|le paramètre]] suivant:
kvm-intel.nested=1
et de redémarrer.
 
Il est possible de vérifier l'activation de cette fonction via un:
cat /sys/module/kvm_intel/parameters/nested
''Note: Au retour de cette commande, le "N" correspond à "désactivée" et le "Y" à "activée".''
 
{{info|Il est recommandé de démarrer le premier niveau de virtualisation avec le paramètre <source lang="bash" inline>-cpu host</source>.}}
 
==Sources de la section==
* https://www.linux-kvm.org/page/Nested_Guests
* https://www.rdoxenham.com/?p=275
 
=Émuler un Raspberry Pi=
Dans cette section, nous allons utiliser un autre aspect de Qemu: l'émulation, pour créer un Raspberry Pi virtuel, ce qui peut être pratique pour faire des simulations en s'affranchissant de la lourdeur du monde physique ou pour lancer des compilations sur une machine distante.
 
Le système utilisé dans cette procédure est un Raspian stretch version ''2017-11-29-lite''.
 
Pour ma part, j'ajoute un répertoire dans mon arborescence afin d'accueillir le noyau que nous téléchargerons plus loin.
mkdir -p /etc/qemu/noyaux/rpi/
 
'''Installation de Qemu ARM'''
 
Le Raspberry Pi utilisant un processeur ARM, il nous faut une autre version de Qemu pour l'émuler.
apt install qemu-system-arm
 
'''Téléchargement du noyau'''
 
Il va nous falloir un noyau adapté à Qemu, à ce stade on peut soit le compiler nous même en allant chercher ses sources et en suivant  [https://github.com/dhruvvyas90/qemu-rpi-kernel cette procédure] (je documenterai ça si je le fait un jour), soit télécharger directement un noyau pré-compilé.
wget https://github.com/dhruvvyas90/qemu-rpi-kernel/raw/master/kernel-qemu-4.4.34-jessie -P /etc/qemu/noyaux/rpi/
''J'ai mis ce noyau à l’abri des erreurs 404 [https://{{SERVERNAME}}/fichiers/virtualisation/qemu/arm/rpi/kernel-qemu-4.4.34-jessie ici].''
 
'''Téléchargement de l'image disque'''
 
Pour télécharger Raspbian c'est par [https://www.raspberrypi.org/downloads/raspbian/ ici] et comme on ne peut pas télécharger les anciennes images sur ce site, j'ai mis en cache l'[https://{{SERVERNAME}}/fichiers/images/rpi/2017-11-29-raspbian-stretch-lite.zip image] que j'ai utilisé si vous n'avez pas de temps à perdre avec une adaptation sur de nouvelles version futures et qu'il faut un truck qui marche dans le quart d'heure (bon quand vous verrez ma bande passante en téléversement vous allez vous dire que le quart d'heure c'est gentil mais vous pouvez pousser si ça vous fait plaisir).
 
'''Décompression de l'image disque'''
apt install unzip
 
unzip /tmp/2017-11-29-raspbian-stretch-lite.zip -d /tmp/
 
'''Conversion de l'image disque'''
 
Afin de ne pas forcer Qemu à passer le montage du disque en mode RAW (ce qui à fortement tendance à foutre la merde de façon générale), on va convertir notre ''.img''.
qemu-img convert -f raw -O qcow2 2017-11-29-raspbian-stretch-lite.img /etc/qemu/disques/raspbian-stretch-lite.qcow
 
'''Agrandissement du disque'''
qemu-img resize /etc/qemu/disques/raspbian-stretch-lite.qcow +6G
On peut vérifier les informations sur le disque (notamment sa taille max puisqu'un ''qcow'' est un fichier creux) avec cette commande:
qemu-img info /etc/qemu/disques/raspbian-stretch-lite.qcow
 
'''Exécution de la machine virtuelle'''
qemu-system-arm -kernel /etc/qemu/noyaux/rpi/kernel-qemu-4.4.34-jessie -append "root=/dev/sda2 panic=1 rootfstype=ext4 rw" -hda /etc/qemu/disques/raspbian-stretch-lite.qcow -cpu arm1176 -m 256 -machine versatilepb -no-reboot -serial stdio -net nic -net user -net tap,ifname=vnet0,script=no,downscript=no -vnc :0
''Note pour plus tard: le réseau ne fonctionne pas mais il me semble que c'est expliqué dans la source. Je n'ai pas le temps de m'en occuper pour l'instant.''


==Arrêt de la machine virtuelle==
==Sources de la section==
* '''Unique:''' https://blog.agchapman.com/using-qemu-to-emulate-a-raspberry-pi/
2 autres sources qui ne m'ont pas servis mais m'ont amenés à effectuer des essais avec des éléments intéressants:
* http://www.jdhp.org/docs/tutoriel_rpi_qemu/tutoriel_rpi_qemu.html
* https://azeria-labs.com/emulate-raspberry-pi-with-qemu/ avec une [https://lists.gnu.org/archive/html/qemu-devel/2015-03/msg02783.html solution] au problème lié à l'option ''-serial stdio'' avec ''-nographic''


Effectuer un <code>CTRL+C</code> pour arrêter la machine virtuel
=Sources=
* http://www.innercoder.com/blog/installing-and-configuring-openvswitch-with-qemu-kvm/
* https://wiki.archlinux.org/index.php/QEMU#Creating_bridge_manually
* Documentation officielle en ligne: https://qemu.weilnetz.de/doc/qemu-doc.html ou en cache dans [https://{{SERVERNAME}}/fichiers/virtualisation/qemu/documentation/ nos fichiers]:
** [https://{{SERVERNAME}}/fichiers/virtualisation/qemu/documentation/qemu-doc-2.10.95.html Version 2.10.95]
** [https://{{SERVERNAME}}/fichiers/virtualisation/qemu/documentation/qemu-doc-3.1.0.html Version 3.1.0]

Dernière version du 7 mars 2021 à 12:11

Prérequis

Installation

Qemu est disponible dans les dépôts Debian

apt install qemu-system-x86-64 openvswitch-switch

Création de l’arborescence de travail (c'est un choix personnel, l’intérêt de cette solution est justement qu'elle n'impose rien)

mkdir -p /etc/qemu/{iso,disques,machines}

Script réseau

Pour que la machine virtuelle puise se connecter sur Open vSwitch, des scripts sont a créer.

INFORMATION

Ce script met dynamiquement les interfaces réseaux dans le VLAN indiqué dans la variable ifname de la commande de démarrage d'une machine virtuelle. Il suffit de mettre l'id du VLAN après un trait de soulignement pour que le script puisse le gérer. Dans l'exemple, ma machine sera dans le VLAN 180.

ASTUCE

Les scripts peuvent être dans l'arborescence que vous voulez puisque vous spécifiez leur chemin dans la commande de démarrage de la machine virtuelle.

Script de démarrage de l’interface

vim /etc/qemu/qemu-ifup
#!/bin/sh
#Séparation du nom de l'interface de l'id du VLAN utilisé
#nomIface=`echo $1 | cut -f 1 -d '_'`
idVlan=`echo $1 | cut -f 2 -d '_'`

OVSCOMMUT=br0
OVSTAG=$idVlan
echo "Execution de /etc/qemu/qemu-ifup"
echo "Allumage de $1 pour l'ajout au pont OVS..."
ip link set $1 up promisc on
echo "Ajout de $1 à ${OVSCOMMUT}..."
ovs-vsctl --may-exist add-br ${OVSCOMMUT}
ovs-vsctl --if-exists del-port ${OVSCOMMUT} $1
ovs-vsctl --may-exist add-port ${OVSCOMMUT} $1
ovs-vsctl --if-exists set port $1 tag=${OVSTAG}
sleep 2

Variables:

  • OVSCOMMUT : interface de votre commutateur virtuel
  • OVSTAG : numéro du Vlan

Script de d'arrêt de l’interface

vim /etc/qemu/qemu-ifdown
#!/bin/sh
OVSCOMMUT=br0
echo "Execution de /etc/qemu/qemu-ifdown"
echo "Arrêt de $1 pour la suppression au pont OVS..."
ip link set $1 down
echo "Suppression de $1 à ${OVSCOMMUT}..."
ovs-vsctl --if-exists del-port ${OVSCOMMUT} $1
echo "Suppression de $1..."
ip link delete dev $1

Variable:

  • OVSCOMMUT : interface de votre commutateur virtuel

Modifier les droits

Ajouter les droits d’exécutions aux scripts

chmod +x /etc/qemu/qemu-if*

Création d'une machine virtuelle

Création d'un disque virtuel

qemu-img create -f qcow2 /etc/qemu/disques/hdd.qcow2 10G

Paramètres:

  • -f qcow2 : type du disque vituel
  • hdd.qcow2 : nom de l'image disque
  • 10G : taille attribué au disque

Démarrage de la machine virtuelle

Démarrage classique

qemu-system-x86_64 -m 1024 -name host1 -vnc :6 --enable-kvm -cpu host -smp cores=2,threads=1,sockets=1 -net nic,macaddr=52:54:00:12:34:56 -net tap,ifname=host1_180,script=/etc/qemu/qemu-ifup,downscript=/etc/qemu/qemu-ifdown -boot c --cdrom /etc/qemu/iso/debian-live-8.7.1-amd64-lxde-bureau.iso -hda /etc/qemu/disques/hdd.qcow2

Paramètres:

  • -m 1024 : mémoire attribué a la machine virtuelle (en octets)
  • -name : nom de la machine virtuelle
  • -vnc :6 : Utilisation de VNC sur le port 5906
  • --enable-kvm : Permet la prise en charge des instructions de virtualisation du processeur
  • -cpu host : Émule un processeur KVM avec théoriquement les mêmes fonctionnalités que l'hôte (ne fonctionne qu'avec le paramètre --enable-kvm). Voir le paramètre -cpu help pour la liste des possibilités. Il est possible d'ajouter des éclaircissements de para-virtualisation Hyper-V pour optimiser les performance de la virtualisation avec des invités Windows: -cpu host,hv_relaxed,hv_spinlocks=0x1fff,hv_vapic,hv_time
  • -smp cores=2,threads=1,sockets=1 : Émule un multiprocesseur symétrique à mémoire partagée (on peut mettre plusieurs cœurs et plusieurs processeurs sur une machine)
  • -net nic,macaddr=52:54:00:12:34:57 : l'adresse MAC de la machine virtuelle (voir)
  • -net tap,ifname=host1_180,script=/etc/qemu/qemu-ifup,downscript=/etc/qemu/qemu-ifdown : nom de l'interface réseau sur la machine maître (limité à 15 caractères) suivie des scripts précédemment créés. Le _180 permet de remplir la variable $idVlan du script de démarrage de l'interface réseau. Les directives -net peuvent être remplacées par -device virtio-net-pci,netdev=network0,mac=$tap_mac -netdev tap,id=network0,ifname=$int_tap,script=no,downscript=no
  • -boot c : Démarre sur le disque dur. Le disque étant vierge, il démarre le cdrom pour l'installation et redémarrera sur le disque dur la prochaine fois (valeurs possible : c|d|n - disque principal|cdrom|réseau)
  • --cdrom /srv/iso/debian-live-8.7.1-amd64-lxde-bureau.iso : lien vers l'ISO du CD-ROM
  • -hda /root/hdd.qcow2 : lien vers le disque virtuel précédemment créé. Peut être remplacer par -drive file=/root/hdd.qcow2,if=virtio pour utiliser le pilote Virtio et avoir de meilleurs performances (non compatible nativement avec Windows)

Démarrage sur squashfs

En lecture seule

qemu-system-x86_64 -m 1024 -name pxe-doc -vnc :3 --enable-kvm -cpu host -smp cores=1,threads=1,sockets=1 -net nic,macaddr=52:54:00:12:34:53 -net tap,ifname=pxe-doc_182,script=/etc/qemu/qemu-ifup,downscript=/etc/qemu/qemu-ifdown -boot c -append 'root=/dev/sda net.ifnames=0' -kernel /var/lib/lxc/lxc-pxe/rootfs/srv/tftp/noyaux/stretch/vmlinuz-4.13.0-custom -initrd /var/lib/lxc/lxc-pxe/rootfs/srv/tftp/noyaux/stretch/initrd.img-4.13.0-custom -hda /var/lib/lxc/lxc-pxe/rootfs/srv/tftp/images/stretch-pxe.squashfs

Les 3 éléments importants sont:

  • -append: définit les paramètres du noyau. Le pré-requis indispensable est la valeur root=/dev/sda qui va indiquer au noyau d'utiliser ce périphérique comme / (il est émulé. Il n'existe pas réellement).
  • -kernel: Indique le chemin du noyau
  • -initrd: Indique le chemin de l'image initrd

En lecture/écriture

La lecture seule ne convient qu'à certains cas et devient vite limitante. Pour passer en lecture/écriture, il faut préciser le paramètre boot=live au noyau et ajouter un périphérique bloc contenant /live/<IMAGE_SQUASHFS>.

INFORMATION

Pour utiliser le paramètre boot=live, un module "live" doit être présent dans l'initrd. Ce module est installé par le paquet live-boot sous Debian (expliqué ici) et casper sous Ubuntu. C'est lui qui scanne les périphériques au démarrage pour trouver un /live contenant le disque système.

Vous pouvez soit utiliser un vrai périphérique soit utiliser losetup afin d'en faire un virtuel (j'ai fait le test en le formatant en vFAT avec un mkfs.vfat /dev/loop0), mais la méthode que je préfère est la méthode VVFAT décrite plus bas.

Dans tout les cas, il convient de préciser un second disque à votre machine virtuelle. Voici la ligne que j'ai utilisé et qui fonctionne:

qemu-system-x86_64 -m 1024 -name pxe-doc --enable-kvm -vnc :3 -cpu host -smp cores=1,threads=1,sockets=1 -net nic,macaddr=52:5e:0a:12:34:53 -boot c -append 'root=/dev/sda net.ifnames=0 boot=live' -kernel vmlinuz-2 -initrd live/initrd.img-2 -drive format=raw,media=cdrom,file=/tmp/live/live/stretch-pxe.squashfs,readonly -drive format=raw,file=fat:rw:/tmp/live

Note: Je n'ai pas trouvé comment mettre VVFAT en lecture seule dans le cas présent. En effet, le file=fat:rw ne peut pas être mis en ro avec le paramètre format=raw. Le paramètre media=cdrom existe mais il n'est pas scanné par le module live du noyau. Je le laisse donc en rw, ce n'est pas génant en soit.

ASTUCE

Dans le cas d'un périphérique loop (créé avec losetup), on peut utiliser le traditionnel -hdb. À noter qu'il est tout à fait possible simuler une clé USB en utilisant la méthode décrite plus bas.

J'ai constaté que certains mettaient le paramètre union=aufs au noyau. Cela peut peut-être utile pour les vieux systèmes si la méthode d'union n'est pas automatique (Aufs a été remplacé par Overlayfs dans Linux 3.18).

Source de la section

Raccourcis clavier

Un ensemble de séquences clavier sont passables à Qemu depuis le terminal ayant servis à le lancer. Elles permettent diverses actions :

  • arrêt de la machine virtuelle : <crtl> + a x
  • passer en mode commandes : <crtl> + a c (refaire la séquence revient sur la machine virtuelle)


Sources :

Console de commandes

Qemu dispose d'une console permettant d’interagir avec la machine en fonctionnement.

Console via terminal courant

Avec cette option, la console vient s'attacher au terminal exécutant la MV. c'est une bonne façon de rationaliser un shell inutilisable.

-monitor stdio

Console via terminal externe

L'outil donne également la possibilité de créer un TTY d'écoute sur lequel on vient s'attacher pour contrôler la liaison série de la machine virtuelle.

-monitor pty

Note: Qemu précise quel TTY il a créé (/dev/pts/9 dans mon exemple) dans le terminal d'exécution. Il est bien sûr possible d'exécuter autant de MV avec ce paramètre que l'on veut, Qemu créera autant de TTY que nécessaire.

Console via telnet

De la même manière, il est possible de faire écouter cette console sur le réseau.

-monitor tcp:127.0.0.1:41127,server,nowait

On s'y connectera via la traditionnelle commande telnet:

telnet 127.0.0.1 41127

Source de la section

Modes d'affichage

Qemu supporte divers modes d'affichage. En l'absence de précisions, il utilisera le gestionnaire de fenêtre de l'interface graphique si présente, sinon, il se terminera en erreur. Il est également possible d'exécuter une machine virtuelle sans affichage ou via le réseau.

Affichage classique

Comme précisé, l'affichage classique s'effectuera en l'absence de paramètre d'affichage. Dans ce mode, une fenêtre du compositeur graphique (Xorg, Wayland, Mir...) s'ouvrira et le fait de la fermer, terminera le processus de la machine virtuelle (extinction électrique).

qemu-system-x86_64 -m 512 --boot n --enable-kvm

Affichage GTK

Si Qemu a été compilé avec le support de GTK et que Linux est au moins en version 4.4, il est possible d'utiliser l'accélération OpenGL (Virgl) avec l'argument suivant:

-vga virtio -display gtk,gl=on

Note: le support de l'accélération graphique est vérifiable via la commande dmesg | grep '\[drm\]'.

Sources de la section

Affichage liaison série

Liaison série via terminal courant

Lors de l'exécution d'une machine virtuelle, Qemu ne rend pas la main (à moins d'utiliser le paramètre -daemonize). Il est possible d'utiliser le terminal ainsi occupé pour y afficher un TTY série attaché à la MV (il faudra bien sûr passer un paramètre au noyau de l'invité pour l'activer) avec ce peramètre:

-serial mon:stdio -nographic

Note: Le paramètre -nographic peut être retiré si vous voulez afficher une fenêtre graphique en plus.

Liaison série via terminal externe

De même que pour l'affichage de la console, il est possible de rediriger la liaison série vers un TTY créé à la volée.

-serial pty

Il est également possible de préciser un terminal spécifique (ça n'a toutefois pas l'air bien stable d'après mes tests...)

-serial /dev/pts/9

Liaison série via telnet

Cette configuration peut s'avérer utile lorsque vous désirez administrer une machine virtuelle qui est isolé dans un VLAN ou simplement inaccessible depuis votre machine d'administration. Il suffit d'initier une connexion telnet à l'hyperviseur qui va renvoyer le retour du TTY de l'invité via une liaison série (configuré via un paramètre passé au noyau de l'invité). On a ainsi un contrôle textuel (copier/coller possible) de la MV sans pour autant avoir un accès réseau à celle-ci.

-nographic -serial telnet:0.0.0.0:5001,server,nowait -monitor none

Les 3 éléments importants sont:

  • -nographic: permet l'utilisation de l'affichage telnet en désactivant tout les autres types d'affichage
  • -serial: définit le port d'écoute du serveur telnet de l'hyperviseur
  • -monitor none: désactive la console qemu. Si vous la voulez, vous pouvez soit supprimer ce paramètre pour entrer directement dedans à l'exécution de la commande, soit la faire écouter sur un socket réseau avec les options suivantes: -monitor tcp:127.0.0.1:41127,server,nowait

Une fois exécuté, la MV est accessible via la traditionnelle commande telnet en pointant vers l'adresse IP de votre hyperviseur suivi du port d'écoute définit dans la commande.

Sources de la section

Affichage réseau

Via VNC

C'est l'affichage que j'ai utilisé pour mon exemple dans le démarrage d'une machine virtuelle. Il est possible de sécuriser l'accès à cet affichage via mot de passe et TLS.

qemu-system-x86_64 -m 512 --boot n --enable-kvm -vnc :0

Le :0 est en fait le numéro de port en omettant le début qui est standard à VNC. Lire 5900. Si cela avais été :6, le port aurai été 5906.

Pour la partie cliente, on peut utiliser virt-viewer, Vinagre ou gvncviewer

gvncviewer 127.0.0.1:0

Accès par mot de passe

J'ai testé mais n'ai été convaincu par cette possibilité. D'apprès la documentation, l'ajout du paramètre password aurai pour effet de demandé un mot de passe (limité à 8 caractères maximums) à l'exécution de la machine (ce qui n'arrive pas). Donc j'en déduis que ça ne fonctionne pas et de toute façon la sécurité est jugé merdique par les dévelopeurs eux même donc aucun intéret. Si vous voulez de la sécurité, utilisez SPICE ou passé par de la tunnellisation (SSH ou VPN) qui elle est sécurisé.

Pour la partie cliente, on peut utiliser virt-viewer, Vinagre ou spice-client-gtk (qui s'utilise via la commande spicy).

Accès via TLS

Usant de VNC uniquement dans mon réseau local ou via un VPN, je n'ai pas besoin de cette fonctionnalité et je ne l'ai pas testé. Si le cœur vous en dit, vous trouverez les explications ici.

Via SPICE

SPICE est le protocole d'affichage historique de KVM. Il a été développé par la société Qumranet (qui a également créé KVM) et libéré par Red Hat qui a racheté l'entreprise le 4 septembre 2008.

Accès sans mot de passe

Partie serveur

qemu-system-x86_64 -m 512 --boot n --enable-kvm -spice port=5905,addr=0.0.0.0,disable-ticketing

Avec addr=0.0.0.0, on autorise les connexions de n'importe quelle adresse cliente.

Partie cliente

spicy -h 127.0.0.1 -p 5905

Accès par mot de passe

Partie serveur

qemu-system-x86_64 -m 512 --boot n --enable-kvm -spice port=5905,addr=0.0.0.0,password=secret123

Partie cliente

spicy -h 127.0.0.1 -p 5905 -w secret123

Accès via TLS

Non testé mais peut être intéressante.

Accès via socket UNIX

Partie serveur

-spice disable-ticketing,unix,addr=/tmp/toto.sock,gl=on

Partie cliente

remote-viewer spice+unix:///tmp/toto.sock

Source de la section

Partage de fichiers

Il est possible d'établir un partage de fichiers entre l'hôte et les invités en utilisant les fonctionnalités de VirtIO.

9P2000

9P (appelé 9P2000 depuis la version 4 de Plan 9) est un protocole développé à l’origine pour le système d'exploitation Plan 9 des laboratoires Bell (Bell Labs) permettant l'échange d'informations entre processus. Il est était autrefois utilisé pour permettre le transfert de données entre les programmes d'un client et d'un serveur. Il est aujourd'hui tout indiqué pour établir un système de fichiers entre un hyperviseur et des machines virtuelles. Le pilote VirtIO du noyau Linux gérant ce protocole, il n'y a aucun additif logiciel à apporter pour mettre en place 9P.

Partie hôte

Création du répertoire à partager

mkdir /tmp/partage

Paramètre à utiliser avec Qemu au moment de lancer la machine virtuelle

-fsdev local,security_model=passthrough,id=fsdev0,path=/tmp/partage -device virtio-9p-pci,id=fs0,fsdev=fsdev0,mount_tag=partage

le raccourci suivant peut aussi être utilisé

-virtfs local,path=/tmp/partage,mount_tag=partage,security_model=passthrough

Partie invité

Création du point de montage

mkdir /tmp/partage_hôte

Montage du volume 9P2000

mount -t 9p -o trans=virtio,version=9p2000.L partage /tmp/partage_hôte/

Sources de la section

VirtIO-fs

Partie à faire. Source d'information: https://virtio-fs.gitlab.io/howto-qemu.html

Passer un périphérique à une machine

Passer un périphérique bloc

Dans le cas d'une installation sans réseau ou d'une machine Windows (ce qui revient un peu au même...), pouvoir transférer des fichiers via un périphérique bloc branché à la machine invité peut s’avérer intéressant.

En tant qu''USB Mass Storage :

-drive if=none,id=stick,file=/dev/sda  \
       -device nec-usb-xhci,id=xhci      \
       -device usb-storage,bus=xhci.0,drive=stick

En tant que VirtIO :

-device virtio-scsi-pci,id=scsi0 \
       -drive file=/dev/sda,if=none,format=raw,discard=unmap,aio=native,cache=none,id=someid \
       -device scsi-hd,drive=someid,bus=scsi0.0

Source de la section

Passer un clavier et une souris

Avec certains systèmes, la gestion de la souris au survole de Qemu est catastrophique. Il est donc utile de pouvoir donner des périphériques d'entrés/sorties directement à l'invité.

Il existe deux méthodes:

  • Avec l'identifiant du bus (simple mais variable à chaque branchement - pratique pour faire un test)
  • Avec l'identifiant du vendeur/produit (un peu plus chiant à écrire mais invariable)

Les périphériques s'identifient avec la commande:

lsusb

qui donne comme résultat (j'ai branché un clavier Dell RT7D50 et une souris Logitech M115 USB sur un PC portable):

Bus 002 Device 003: ID 0bda:8153 Realtek Semiconductor Corp. 
Bus 002 Device 002: ID 2109:0813 VIA Labs, Inc. 
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 004: ID 04f3:21d5 Elan Microelectronics Corp. 
Bus 001 Device 003: ID 0cf3:e300 Atheros Communications, Inc. 
Bus 001 Device 009: ID 413c:2005 Dell Computer Corp. RT7D50 Keyboard
Bus 001 Device 002: ID 2109:2813 VIA Labs, Inc. 
Bus 001 Device 005: ID 1bcf:2b95 Sunplus Innovation Technology Inc. 
Bus 001 Device 008: ID 046d:c058 Logitech, Inc. M115 Mouse
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

Il est à noter que l'adresse du bus n'a aucun rapport avec tel ou tel port USB physique du PC. Après un débranchement/rebranchement, les valeurs changent...

Pour un usage avec un utilisateur standard, il faut donner les droits au périphérique. Ceci peut ce faire soit via un:

chmod 666 /dev/bus/usb/001/08

soit via une règle Udev:

vim /etc/udev/rules.d/70-persistent-net.rules
SUBSYSTEM=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c058", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVendor}=="413c", ATTR{idProduct}=="2005", MODE="0666"

Il faut ensuite recharger les règles udev (sinon un redémarrage s'en chargera)

udevadm control --reload-rules && udevadm trigger

Avec l'identifiant du bus

-usb -device usb-host,hostbus=1,hostaddr=8 \
-usb -device usb-host,hostbus=1,hostaddr=9

Avec l'identifiant du produit

-usb -device usb-host,vendorid=0x046d,productid=0xc058 \
-usb -device usb-host,vendorid=0x413c,productid=0x2005

Sources de la section

Passer un USB à une machine

ATTENTION

Méthode à peaufiner...

Il peut être utile d'envoyer un périphérique USB dans une machine virtuelle (une caméra dans mon exemple). Pour ce faire, il faut identifier le numéro du bus sur lequel est branché l'équipement avec un

lsusb

Ce qui dans mon cas, me donne: Bus 003 Device 005: ID 0bda:58b0 Realtek Semiconductor Corp.

Il suffit ensuite de passer les paramètres suivants à Qemu

-device usb-ehci,id=ehci -device usb-host,bus=ehci.0,vendorid=0x0bda,productid=0x58b0

Je retrouve bien un /dev/video0 dans ma machine virtuelle.

Source de la section

RAM à chaud

Il est possible d'ajouter et de retirer de la RAM à chaud dans une machine virtuelle. Cette fonction s'appelle virtio-balloon et un pilote doit être installé sur les machines invitées (avec Windows, ce pilote est accessible dans cet ISO - je n'ai pas réussi à le faire fonctionner). Sous Linux, ce pilote est intégré au noyau (comme d'habitude j'ai envi de dire). Il suffi donc de passer l'argument suivant à Qemu:

-device virtio-balloon

La machine va démarrer avec la quantité de RAM définie avec l'argument -m et il sera possible de changer cette valeur dynamiquement via la console Qemu en y tapant la commande suivante:

balloon 2048

pour passer la machine à 2 Go de RAM.

On peut voir la RAM allouée via la commande suivante:

info balloon

Source de la section

Images disque

Attacher un disque

Disque RAW

-drive format=raw,media=$1,file=$2
  • $1: disk ou cdrom (le paramètre ,readonly peut être définit pour cdrom)
  • $2: Chemin de l'image disque ou du disque physique

Sources de la section

Disque FAT virtuel

Cette fonctionnalité(abrégé VVFAT) déchire tout simplement sa race. Elle permet de présenter un répertoire de l'hôte sous forme de périphérique bloc à la machine virtuelle ! Ainsi, dans une configuration sans réseau, il est possible de donner des fichiers à la machine invité. Un autre usage possible (celui que je préfère) lors de la combinaison avec le module live du noyau Linux est d'activer le démarrage en lecture/écriture via un unionfs d'un disque Squashfs. Cette fonctionnalité est exploité un peu plus haut.

-drive format=raw,file=fat:rw:/tmp/live

ATTENTION

La documentation officielle donne 3 choses à ne jamais faire avec cette fonction:
  • Utiliser des noms de fichier non-ASCII
  • Utiliser l'option -snapshot en même temps que le paramètre rw (sauf avec la fonction loadvm)
  • Écrire dans le répertoire servant de FAT à l'invité lorsque celui-ci est en fonctionnement (j'ai testé et ça corrompt tout le contenu du système FAT... - il faut re-copier/coller les fichiers voulus dedans à l'issue pour remettre ça en ordre)

Source de la section

Changer de CD-ROM

Il est possible de changer de fichier ISO lorsque la machine virtuelle est sous tension via la console Qemu.

Identifier le lecteur

info block

Note: on peut voir l'ISO qui est actuellement inséré dans le lecteur.

Changer d'ISO

change ide1-cd0 /tmp/dsl-4.4.10.iso

Source de la section

Convertir une image disque

INFORMATION

La conversion semble impossible d'un disque à l'autre. Il faut être sur le même système de fichier pour la totalité de l'opération.

Image OVA

Une image OVA est une exportation de machine virtuelle VMWare. Elle se présente sous la forme d'une archive tar avec comme extension .ova contenant un descriptif de la machine virtuelle (RAM, CPU, emplacement disque...) au format XML avec une extension .ovf, un disque virtuel en .vmdk et une empreinte SHA1 des deux fichiers mentionnés dans un document texte en .mf.

Bien que Qemu sache gérer les VMDK, il est conseillé de travailler avec du Qcow2.

Désarchivage du .ova

tar xvf archive.ova

Conversion du VMDK en Qcow2

qemu-img convert -O qcow2 image_source.vmdk image_destination.qcow2

Source

Réduire une image Qcow2

Un disque virtuel Qcow2 étant un fichier creux, il se rempli au fur et à mesure de son utilisation jusqu'à atteindre la limite fixée lors de sa création (même après suppression des fichiers de l'invité, ces derniers sont remplacés par des zéros). Les zéros qui remplissent ses espaces sont alors ré-écrits à mesures des modifications du système de fichier invité. Afin de les purger, il faut reconvertir l'image dans son même format. Il est également possible d'appliquer une compression aux données déjà existantes (cette compression ne s'applique pas aux nouvelles données ajoutées après la conversion). Il est à noter que la conversion n'alter en rien les données. Si vous convertissez deux fois de suite une image et que vous faites un hash du résultat vous vous apercevrez qu'il est identique.

ATTENTION

Faites bien attention à ne pas donner la même destination+nom au fichier de sorti, sinon vous allez écraser le disque virtuel que vous tentez de réduire et donc tout niquer !

Récupérer les zéros

qemu-img convert -f qcow2 /tmp/image-src.qcow2 -O qcow2 /tmp/image-dst.qcow2

Compresser l'image

qemu-img convert -c -f qcow2 /tmp/image-src.qcow2 -O qcow2 /tmp/image-dst.qcow2

Note: Ajout du paramètre -c.

Source

Monter une image disque

Il est possible de monter l'image disque Qcow2 d'une machine virtuelle sur l'hôte afin de récupérer ce qui se trouve à l'intérieur ou d'y déposer des fichiers. Cette opération utilise le module noyau ndb non activé par défaut dans Debian.

Montage

modprobe nbd max_part=63
qemu-nbd -c /dev/nbd0 /tmp/ramdisk/windows.qcow2
mount /dev/nbd0p2 /mnt

Dé-montage

umount /mnt
qemu-nbd -d /dev/nbd0
rmmod nbd

Source de la section

Virtualisation imbriquée

La virtualisation imbriquée (nested KVM) permet de virtualiser (en utilisant l'accélération matérielle via les instructions CPU) dans une machine virtuelle (c'est de la virtualisation dans la virtualisation). Cette fonctionnalité est déclarée fonctionnelle mais expérimentale depuis février 2018. Pour l'activée, il suffit de passer au noyau Linux le paramètre suivant:

kvm-intel.nested=1

et de redémarrer.

Il est possible de vérifier l'activation de cette fonction via un:

cat /sys/module/kvm_intel/parameters/nested

Note: Au retour de cette commande, le "N" correspond à "désactivée" et le "Y" à "activée".

INFORMATION

Il est recommandé de démarrer le premier niveau de virtualisation avec le paramètre -cpu host.

Sources de la section

Émuler un Raspberry Pi

Dans cette section, nous allons utiliser un autre aspect de Qemu: l'émulation, pour créer un Raspberry Pi virtuel, ce qui peut être pratique pour faire des simulations en s'affranchissant de la lourdeur du monde physique ou pour lancer des compilations sur une machine distante.

Le système utilisé dans cette procédure est un Raspian stretch version 2017-11-29-lite.

Pour ma part, j'ajoute un répertoire dans mon arborescence afin d'accueillir le noyau que nous téléchargerons plus loin.

mkdir -p /etc/qemu/noyaux/rpi/

Installation de Qemu ARM

Le Raspberry Pi utilisant un processeur ARM, il nous faut une autre version de Qemu pour l'émuler.

apt install qemu-system-arm

Téléchargement du noyau

Il va nous falloir un noyau adapté à Qemu, à ce stade on peut soit le compiler nous même en allant chercher ses sources et en suivant cette procédure (je documenterai ça si je le fait un jour), soit télécharger directement un noyau pré-compilé.

wget https://github.com/dhruvvyas90/qemu-rpi-kernel/raw/master/kernel-qemu-4.4.34-jessie -P /etc/qemu/noyaux/rpi/

J'ai mis ce noyau à l’abri des erreurs 404 ici.

Téléchargement de l'image disque

Pour télécharger Raspbian c'est par ici et comme on ne peut pas télécharger les anciennes images sur ce site, j'ai mis en cache l'image que j'ai utilisé si vous n'avez pas de temps à perdre avec une adaptation sur de nouvelles version futures et qu'il faut un truck qui marche dans le quart d'heure (bon quand vous verrez ma bande passante en téléversement vous allez vous dire que le quart d'heure c'est gentil mais vous pouvez pousser si ça vous fait plaisir).

Décompression de l'image disque

apt install unzip
unzip /tmp/2017-11-29-raspbian-stretch-lite.zip -d /tmp/

Conversion de l'image disque

Afin de ne pas forcer Qemu à passer le montage du disque en mode RAW (ce qui à fortement tendance à foutre la merde de façon générale), on va convertir notre .img.

qemu-img convert -f raw -O qcow2 2017-11-29-raspbian-stretch-lite.img /etc/qemu/disques/raspbian-stretch-lite.qcow

Agrandissement du disque

qemu-img resize /etc/qemu/disques/raspbian-stretch-lite.qcow +6G

On peut vérifier les informations sur le disque (notamment sa taille max puisqu'un qcow est un fichier creux) avec cette commande:

qemu-img info /etc/qemu/disques/raspbian-stretch-lite.qcow

Exécution de la machine virtuelle

qemu-system-arm -kernel /etc/qemu/noyaux/rpi/kernel-qemu-4.4.34-jessie -append "root=/dev/sda2 panic=1 rootfstype=ext4 rw" -hda /etc/qemu/disques/raspbian-stretch-lite.qcow -cpu arm1176 -m 256 -machine versatilepb -no-reboot -serial stdio -net nic -net user -net tap,ifname=vnet0,script=no,downscript=no -vnc :0

Note pour plus tard: le réseau ne fonctionne pas mais il me semble que c'est expliqué dans la source. Je n'ai pas le temps de m'en occuper pour l'instant.

Sources de la section

2 autres sources qui ne m'ont pas servis mais m'ont amenés à effectuer des essais avec des éléments intéressants:

Sources