User Tools

Site Tools


doc:appunti:linux:sa:qemu_kvm

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
doc:appunti:linux:sa:qemu_kvm [2018/03/01 18:47] niccolodoc:appunti:linux:sa:qemu_kvm [2022/11/09 10:14] (current) – [Virutalizzazione QEMU-KVM su Debian Stretch] niccolo
Line 1: Line 1:
-====== Virutalizzazione QEMU-KVM su Debian Stretch ======+====== Virtualizzazione QEMU-KVM su Debian Stretch ======
  
 Verificare con ''cat /proc/cpuinfo'' che il processore supporti la virtualizzazione: deve essere presente il flag **vmx** (per i processori Intel) oppure **svm** (per i processori AMD). Potrebbe essere necessario abilitarla da BIOS (identificata da qualcosa tipo "CPU protezione esecuzione" o "virtualizzazione"). Verificare con ''cat /proc/cpuinfo'' che il processore supporti la virtualizzazione: deve essere presente il flag **vmx** (per i processori Intel) oppure **svm** (per i processori AMD). Potrebbe essere necessario abilitarla da BIOS (identificata da qualcosa tipo "CPU protezione esecuzione" o "virtualizzazione").
Line 17: Line 17:
  
 È la configurazione necessaria per mettere la macchina **host e guest sulla stessa rete locale**. In pratica si configura una interfaccia **br0** che avrà l'indirizzo IP della macchina host. Tale interfaccia sarà messa in bridge con la porta fisica **eth0** e con la porta virtuale **tap0**, che a sua volta corrisponde all'interfaccia **eth0** della macchina guest. È la configurazione necessaria per mettere la macchina **host e guest sulla stessa rete locale**. In pratica si configura una interfaccia **br0** che avrà l'indirizzo IP della macchina host. Tale interfaccia sarà messa in bridge con la porta fisica **eth0** e con la porta virtuale **tap0**, che a sua volta corrisponde all'interfaccia **eth0** della macchina guest.
 +
 +Vediamo come si configura il file **/etc/network/interfaces** di una macchina Debian.
  
 <file> <file>
Line 31: Line 33:
         bridge_fd 0         bridge_fd 0
 </file> </file>
 +
 +In questo secondo esempio la scheda di rete **eth2** della macchina host non è configurata (non ha indirizzo IP). Il device **br2** viene quindi usato come bridge virtuale dalle macchine guest, che potranno raggiungere gli altri host fisicamente connessi a eth2:
 +
 +<file>
 +auto eth2
 +iface eth2 inet manual
 +        up   /sbin/ifconfig eth2 up   || true
 +        down /sbin/ifconfig eth2 down || true
 +
 +auto br2
 +iface br2 inet manual
 +        bridge_ports eth2
 +        bridge_stp off
 +        bridge_maxwait 10
 +        up   /sbin/ifconfig br2 up || true
 +        down /sbin/ifconfig br2 up || true
 +</file>
 +
 +Potrebbe tornare utile un **bridge senza alcuna scheda Ethernet connessa**, ad esempio per attivare una interfaccia di rete in una macchina virtuale, ma senza dover occupare per forza una porta Ethernet. Ecco come attivare **br10** senza impegnare porte fisiche:
 +
 +<file>
 +auto br10
 +iface br10 inet manual
 +        bridge_ports none
 +        bridge_stp off
 +        bridge_waitport 0
 +        bridge_maxwait 10
 +        up   /sbin/ifconfig br10 up   || true
 +        down /sbin/ifconfig br10 down || true
 +</file>
 +
 +Ecco la sintassi **da riga di comando** per fare configurazioni analoghe:
 +
 +<code>
 +brctl addbr br2
 +brctl addif br2 eth2
 +ifconfig br2 up
 +
 +ifconfig br2 down
 +brctl delif br2 eth2
 +brctl delbr br2
 +</code>
 +===== Creazione di una macchina virtuale =====
 +
 +Si può procedere in **modalità manuale** oppure preparando dei **file di configurazione XML** e lasciare il lavoro di basso livello al framework **libvirt**.
 +
 +==== Modo manuale con network in modo bridge ====
 +
 +La configurazione con **rete in modalità bridge** è la più complessa, perché richiede che la macchina ospitante sia predisposta opportunamente. In breve la macchina ospitante dovrà avere l'**interfaccia br0** invece di eth0. Nel file **/etc/network/interfaces** si imposta:
 +
 +<file>
 +auto br0
 +iface br0 inet static
 +        address 10.0.1.2
 +        netmask 255.255.255.0
 +        gateway 10.0.1.252
 +        bridge_ports eth0
 +        bridge_stp off
 +        bridge_maxwait 10
 +</file>
 +
 +quindi l'utente root predispone l'interfaccia **tap0**:
 +
 +<code>
 +tunctl -t tap0 -u root
 +ifconfig tap0 up
 +brctl addif br0 tap0
 +</code>
 +
 +A questo punto è possibile **avviare la macchina ospite** con qualcosa del tipo:
 +
 +<code>
 +qemu-system-x86_64 -m 1024 -machine accel=kvm \
 +        -netdev tap,id=mynet0,ifname=tap0,script=no,downscript=no \
 +        -device e1000,netdev=mynet0,mac=52:55:00:00:00:01 \
 +        -cdrom ../../iso/debian-10.0.0-amd64-netinst.iso \
 +        -hda rootfs.img -boot c
 +</code>
 +
 +==== Con libvirt ====
 +
 +Una macchina virtuale è definita da due file: il **file di configurazione** e il file **immagine del disco**. Ad esempio una macchina di nome **stretch-amd64** è definita da:
 +
 +  * **/etc/libvirt/qemu/stretch-amd64.xml**
 +  * **/var/lib/libvirt/images/stretch-amd64.qcow2**
 +
 +È possibile creare in maniera assistita tali file eseguento il tool **virt-install**. Ad esempio:
 +
 +<code>
 +virt-install \
 +    --virt-type kvm --name stretch-amd64 \
 +    --network bridge=br0 \
 +    --cdrom /home/kvm/iso/grml64-full_2017.05.iso \
 +    --graphics vnc,password=MySecret,listen=0.0.0.0, \
 +    -v --os-variant debian9 \
 +    --disk size=40 --memory 512
 +</code>
 +
 +dove i parametri sono il **nome** del guest (es. stretch-amd64), una immagine **ISO** da cui fare bootstrap, una **password** per connettersi via **VNC** alla console, la dimensione del **disco** (es. 40 GB) e la **memoria** da allocare (512 Mb). Il parametro **%%--os-variant%%** determina alcune ottimizzazioni alla configurazione, usare **osinfo-query os** per sapere le varianti supportate.
 +
 +**virt-install** crea i file necessari e avvia la macchina virtuale, la **console** è raggiungibile tramite **VNC sulla porta 5900** della macchina host. Nel file di configurazione il boot da CD-ROM e l'immagine relativa non viene messa. Ecco cosa cambiare per ripristinarlo quando serve:
 +
 +<code xml>
 +<!-- <boot dev='hd'/> -->
 +<boot dev='cdrom'/>
 +</code>
 +
 +<code xml>
 +<!-- <driver name='qemu' type='raw'/> -->
 +<source file='/home/kvm/iso/grml64-full_2017.05.iso'/>
 +</code>
 +
 +In alternativa a **virt-install** è possibile creare manualmente il **file .xml di configurazione** e creare l'**immagine disco** con il tool:
 +
 +<code>
 +qemu-img create -f qcow2 stretch-amd64.qcow2 40G
 +</code>
 +
 +Quando si cambiano i file di configurazione delle macchine guest è necessario riavviare il servizio (le macchine virtuali in esecuzione non sono toccate):
 +
 +<code>
 +systemctl restart libvirtd.service
 +</code>
 +
 +quindi da virsh è possibile distruggere e far ripartire una macchina virtuale, nonché abilitiare l'avvio atuomatico della stessa:
 +
 +<code>
 +destroy stretch-amd64
 +start stretch-amd64
 +autostart stretch-amd64
 +</code>
 +
 +L'avvio automatico è determinato semplicmente dall'esistenza di un link simbolico:
 +
 +<code>
 +/etc/libvirt/qemu/autostart/stretch-amd64.xml -> /etc/libvirt/qemu/stretch-amd64.xml
 +</code>
 +===== Immagine disco raw o qcow2 =====
 +
 +L'immagine di un disco virtuale si crea con **qemu-img**. È possibile utilizzare il formato **raw** (predefinito, facilmente portabile su altri emulatori) oppure il formato **qcow2** (predefinito di QEMU, più versatile per crittografia, compressione, ecc.) utilizzando l'opzione **-f qcow2** di qemu-img.
 +
 +Per scoprire il formato di un file immagine dovrebbe essere sufficiente il comando **file**, a prescindere dall'estensione:
 +
 +<code>
 +file disk_hda.img
 +disk_hda.img: QEMU QCOW Image (v2), 10737418240 bytes
 +
 +file disk_hdb.img
 +disk_hdb.img: DOS/MBR boot sector; ...
 +</code>
 +
 +Il file XML di configurazione differisce nei due casi: 
 +
 +<code xml>
 +<disk type='file' device='disk'>
 +  <driver name='qemu' type='qcow2'/>
 +  <source file='/var/lib/libvirt/images/rootfs.qcow2'/>
 +  <target dev='hda'/>
 +</disk>
 +</code>
 +
 +<code xml>
 +<disk type='file' device='disk'>
 +  <source file='/var/lib/libvirt/images/rootfs.img'/>
 +  <target dev='hdb'/>
 +</disk>
 +</code>
 +
 +===== Scheda di rete Virtio o RTL-8029(AS) =====
 +
 +La scelta predefinita per l'emulazione di una scheda Ethernet è il modello **Virtio**. Tale modello potrebbe non essere supportato ad esempio dalle versioni più vecchie dei sistemi operativi (Linux 2.6.18 non la supporta). In questi casi è possibile scegliere l'emulazione di una **Realtek RTL-8029(AS)** configurando opportunamente il file XML. Ecco i due esempi:
 +
 +<code xml>
 +<interface type='bridge'>
 +  <model type='virtio'/>
 +  <mac address='52:54:00:00:01:04'/>
 +  <source bridge='br0'/>
 +  <target dev='tap103'/>
 +</interface>
 +</code>
 +
 +Il tipo **virtio** offre alla macchina guest un device Ethernet PCI con ID **1af4:1000**.
 +
 +<code xml>
 +<interface type='bridge'>
 +  <model type='ne2k_pci'/>
 +  <mac address='52:54:00:00:01:04'/>
 +  <source bridge='br0'/>
 +  <target dev='tap103'/>
 +</interface>
 +</code>
 +
 +Il tipo **ne2k_pci** offre alla macchina guest una Ethernet PCI compatibile NE2000, per la precisione una **Realtek RTL-8029(AS)**. L'ID PCI in realtà è **1af4:1100**, sempre afferente al vendor QEMU.
 +
 +Per avere **due o più schede** Ethernet è sufficiente aggiungere altre sezioni **%%<interface>%%**. Ovviamente si impostano mac address e device tap diversi. Anche il bridge connesso è bene che sia diverso (per evitare i //bridge loop//), eventualmente usando un bridge fittizio, senza alcuna interfaccia Ethernet connessa (vedi sopra).
 +
 +===== Console VNC =====
 +
 +Nella sezione **%%<devices>%%** del file di configurazione:
 +
 +<code xml>
 +<graphics type='vnc' port='5908' passwd='MySecret' keymap='it'>
 +  <listen type='address' address='181.121.173.202'/>
 +</graphics>
 +</code>
 +
 +Nella configurazione si imposta la porta TCP in ascolto, la password e la mappatura della tastiera. Con address uguale a **0.0.0.0** si fa il bind su tutte le interfacce, non è possibile specificare due o più indirizzi di bind. Ovviamente se si imposta la password in chiaro, è opportuno proteggere il file almeno con **mode 0640**.
  
 ===== Troubleshooting ===== ===== Troubleshooting =====
Line 47: Line 256:
 Errore durante il tentativo di avviare una macchina virtuale in modalità network NAT (modalità predefinita). Non era stata avviata la configurazione di rete //default// di libvirt. Dalla shell **virsh** si deve eseguire **net-start default**. Errore durante il tentativo di avviare una macchina virtuale in modalità network NAT (modalità predefinita). Non era stata avviata la configurazione di rete //default// di libvirt. Dalla shell **virsh** si deve eseguire **net-start default**.
  
 +===== Web References =====
 +
 +  * **[[https://wiki.debian.org/KVM|KVM in Debian]]**
 +  * **[[https://libvirt.org/formatdomain.html|Libvirt Domain XML format]]**
doc/appunti/linux/sa/qemu_kvm.txt · Last modified: 2022/11/09 10:14 by niccolo