**KVM**
virtualizacion
Algunos conceptos:
* **KVM** es la parte del kernel de GNU/Linux que de forma nativa implementa virtualizacion en aquellas CPU que lo soporten (en 2014 no creo que se haya fabricado ninguna que no lo soporte)
* **QEMU** es un conjunto de herramientas que ofrecen emulacion y virtualizacion. En este manual solo vamos a utilizar la segunda parte, aunque casi siempre a traves de libvirt
* **Libvirt** es un conjunto de herramientas que actuan como //frontend// de distintas teconologias de virtualizacion: KVM, LXC, etc... En este manual vamos a usarlo intensivamente
* **Virtio** son un conjunto de modulos de kernel GNU/Linux que permiten paravirtualizar red y disco. De esa forma, cuando desde el host se usan esos drivers para un guest GNU/Linux, este es consciente de correr en un entorno virtualizado, y coopera con el hipervisor mejorando asi el rendimiento. Virtio es conceptualmente similar a las guest additions de VMWare.
====== Instalar ======
1. Entrar en la BIOS del sistema y asegurarse de que el soporte de virtualización está activado
2. Instalar un sistema GNU/Linux reciente (yo pruebo con Debian 6.x=
3. Comprobar que el sistema operativo soporta virtualizacion:
Una vez encontré un escenario en el que la prueba 3.1. era KO y la 3.2. OK, por lo que creo que la más exacta es la 3.1.
3.1. Ver si kvm está deshabilitado a nivel de BIOS
dmesg | grep bios
3.2 Ejecutar
sudo egrep '(vmx|svm)' --color=always /proc/cpuinfo
En caso de que SI soporte virtualizacion veremos lo siguiente:
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx lm constant_tsc arch_perfmon pebs bts rep_good aperfmperf pni dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm lahf_lm tpr_shadow vnmi flexpriority
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx lm constant_tsc arch_perfmon pebs bts rep_good aperfmperf pni dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm lahf_lm tpr_shadow vnmi flexpriority
Con la palabra 'vmx' o 'svm' en rojo
4. Instalar los siguientes paquetes:
sudo aptitude install qemu-kvm libvirt-bin virtinst qemu-utils
**Nota**: qemu-utils es necesario para exportar de discos raw a qcow2
5. Anyadir el usuario X al grupo:
sudo adduser USUARIO libvirt
6. Comprobar que el demonio libvirtd esta corriendo (necesario para poder administrar KVM desde un entorno grafico con virt-manager):
ps ax | grep libvirt
4149 ? Sl 0:00 /usr/sbin/libvirtd -d
====== Crear VM ======
===== Desde GUI =====
La principal diferencia es VNC. Configuracion:
test-1.dev.jj.com12b440aa-fee3-b6cc-31d1-4d2bde56e0df10485765242882hvmdestroyrestartrestart/usr/bin/kvm
===== Desde linea de comandos =====
Lanzar los comandos desde el hipervisor.
Debian estable desde red configurada con NAT, 1024B de RAM, y disco duro con algunas configuraciones para mejor rendimiento:
sudo virt-install \
-n template-1.dev.local.legido.com \
-r 1024 \
--vcpus=2 \
--os-variant=debianwheezy \
--disk /var/lib/libvirt/images/template-1.dev.local.legido.com,size=5,bus=virtio,cache=none,format=qcow2 \
--nographics \
--network network=default \
-l http://ftp.debian.org/debian/dists/wheezy/main/installer-amd64/ \
-x console=ttyS0,115200
Debian estable desde red configurada con bridge, 512MB de RAM y 2 GB de disco duro:
virt-install \
-n vm1 \
-r 512 \
--vcpus=2 \
--os-variant=debiansqueeze \
--disk /var/lib/libvirt/images/vm1.img,size=2 \
--nographics \
--bridge br0 \
-l http://ftp.debian.org/debian/dists/squeeze/main/installer-amd64/ \
-x console=ttyS0,115200
Ubuntu server, NAT conectado a red "default":
sudo virt-install \
-n template-2.dev.local.jamgo.org \
-r 512 \
--vcpus=2 \
--os-variant=ubuntuquantal \
--disk /var/lib/libvirt/images/template-2.dev.local.jamgo.org.qcow2,size=8,bus=virtio,cache=none \
--nographics \
--network network=default \
-l http://archive.ubuntu.com/ubuntu/dists/quantal/main/installer-amd64/ \
-x console=ttyS0,115200
Debian Jessie desde CD:
sudo virt-install \
-n template-1.dev.local.legido.com \
-r 512 \
--vcpus=2 \
--os-variant=debianwheezy \
--disk pool=template_1,sparse=false,size=8,cache=none,format=raw,bus=virtio \
--graphics vnc \
--bridge virbr0 \
--cdrom=/var/lib/libvirt/images/debian-jessie-amd64-netinst.iso
vmbuilder
http://www.howtoforge.com/virtualization-with-kvm-on-a-debian-squeeze-server
**TODO** Crear una VM desde linea de comandos con un VL como storage
====== Conectarse a KVM y VM ======
===== GUI =====
Escenario: NO quiero instalar las X en el hipervisor, y quiero administrar gráficamente el hipervisor y las máquinas virtuales desde otra máquina (cliente) con las X instaladas
1. (Hipervisor) Instalar los siguientes paquetes:
sudo aptitude update; sudo aptitude install netcat socat -R
2. (Hipervisor) Crear el siguiente archivo:
sudo vim /bin/netcatsocket
Con el siguiente contenido:
#!/bin/bash
socat - unix-client:$2
3. (Hipervisor) Darle permisos
sudo chmod +x /bin/netcatsocket
4. (Cliente) Instalar paquetes:
sudo aptitude update; sudo aptitude install virt-manager ssh-askpass -R
5. (Cliente) Conectarse al hipervisor:
virt-manager -c qemu+ssh://USUARIO@HIPERVISOR:PUERTO/system?netcat=netcatsocket
===== Conectarse a la consola de VM sin GUI =====
1. (VM) Editar
sudo vim /etc/inittab
Y anyadir:
T0:23:respawn:/sbin/getty -L ttyS0 9600 vt100
2. (VM) Editar
sudo vim /etc/default/grub
Y dejar la linea tal que asi:
GRUB_CMDLINE_LINUX="console=tty0"
3. (VM) Recargar grub:
sudo update-grub
4. (Hipervisor) Conectarse a la consla de la VM:
sudo virsh console template
Connected to domain template
Escape character is ^]
Toca un tecla (por ejemplo enter) y aparecera el prompt:
Debian GNU/Linux 6.0 template ttyS0
template login:
5. Para finalizar la conexion CTRL + ]
====== Comandos varios ======
* Listar todas las Maquinas Virtuales (VM):
virsh list --all
Id Name State
----------------------------------------------------
- name shut off
* Forzar apagado VM:
sudo virsh destroy vm2
* Eliminar por completo una VM:
virsh undefine vm2
Domain vm2 has been undefined
* Cambiar la memoria maxima. **IMPORTANTE**: requiere apagar la VM, mejor apagarla primero a traves del Sistema Operativo:
sudo virsh shutdown vm2
sudo virsh setmaxmem vm2 524288
sudo virsh start vm2
sudo virsh setmem vm2 524288
En este ejemplo se establece el valor en 524288 KB
* Arrancar la VM al arrancar el hipervisor:
sudo virsh autostart myvmname
====== Salir de la consola ======
* virt-manager
CTRL + ALT + F7
o
CTRL + ALT
====== Errores ======
* **Cannot recv data: Host key verification failed. : Connection reset by peer**
Sucede al lanzar:
virt-manager -c qemu+ssh://usuario@hipervisor/system
**Solucion**: iniciar una sesion SSH para almacenar las claves del hipervisor en el cliente:
ssh usuario@hipervisor
* **Error starting network 'default': internal error**
Suce al intentar activar o crear una nueva red virtual desde virt-manager debido a un bug de libvirt.
**Solucion**: actualizar los paquetes relacionados con libvirt
1. Editar:
sudo vim /etc/apt/sources.list
Y anyadir la siguiente linea:
deb http://backports.debian.org/debian-backports squeeze-backports main
2. Actualizar la cache de paquetes:
sudo aptitude update
3. Instalar la version de backports de los siguientes paquetes:
sudo aptitude -t squeeze-backports install libvirt-bin libvirt0 python-libvirt dnsmasq-base -R
4. Reiniciar el demonio libvirtd:
sudo /etc/init.d/libvirt-bin restart
====== Renombrar VM ======
===== VM destino no existe =====
Queremos renombrar de "test-2.example.com" a "test-1.example.com". Solo existe la primera, "test-2.example.com"
1. Volcar la configuración:
sudo su -
cd /etc/libvirt/qemu/
virsh dumpxml test-2.example.com.xml > test-1.example.com.xml
2. Apagar la VM si no lo está (a nivel de Sistema Operativo mejor).
Asegurarse de que **NO** tiene snapshot
3. Cepillarse la VM:
virsh undefine test-2.example.com
4. Editar el archivo de configuracion de la nueva VM:
sudo vim test-1.example.com.xml
Y asegurarse de que los siguientes valores son unicos y correctos:
* Name
test-1.example.com
* Almacenamiento (en este caso LVM)
* MAC address (importante, quiza hemos copiado la maquina y esta duplicada):
Script para generar MAC addresses:
#!/usr/bin/python
# macgen.py script to generate a MAC address for guests on Xen
#
import random
#
def randomMAC():
mac = [ 0x00, 0x16, 0x3e,
random.randint(0x00, 0x7f),
random.randint(0x00, 0xff),
random.randint(0x00, 0xff) ]
return ':'.join(map(lambda x: "%02x" % x, mac))
#
print randomMAC()
Ahora obtenemos el listado de VMS:
virsh list --all
Y para cada una de ellas obtenemos la MAC address:
virsh dumpxml vm-1.example.com | grep "mac address" | awk '{print $2}' | cut -d "'" -f2
TODO: hacer un script en bash que lo haga
Finalmente nos aseguramos que la nueva MAC generada es unica.
5. Definir la nueva VM:
virsh define test-1.example.com.xml
===== VM destino existe =====
1. Para VM destino
2. Eliminarla:
sudo virsh undefine test-1.example.com
Seguir los pasos de [[informatica:linux:virtualizacion:kvmvm_destino_no_existe]]
====== Dispositivos ======
===== CDROM =====
1. Dejar la imagen iso en el hipervisor:
/var/lib/libvirt/images/systemrescuecd-x86-3.4.2.iso
2. Editar la VM:
sudo virsh
edit vm_1
2.1. Anyadir el siguiente bloque dentro del bloque :
...
...
Al grabar libvirt le asignara una entrada con la direccion PCI dentro del bloque
2.2. (Opcional) Si se quiere arrancar desde CD anyadir el siguiente bloque dentro del bloque :
2.3. Grabar y salir
===== VNC =====
1. Editar la VM desde virsh:
sudo virsh
edit vm_1
1.1. Anyadir el siguiente bloque dentro del bloque :
...
...
Al grabar libvirt le asignara una entrada con la direccion PCI dentro del bloque
1.2. Grabar y salir
====== Almacenamiento ======
===== Archivo =====
==== Agrandar. Formato QCOW2 + LVM en VM ====
**NOTA** estas instrucciones sirven tambien cuando el almacenamiento de la VM se hace en un LV del host. Solo hay que cambiar el paso 2
La estrategia es extender el disco, crear una nueva particion en el nuevo espacio, crear un PV, anyadirlo al VG, extender el LV y redimensionar el sistema de archivos (EXT4...).
1. Para la VM, a ser posible desde el Sistema Operativo:
ssh test7
sudo shutdown -h now
2. Extender el disco:
sudo qemu-img resize /var/lib/libvirt/images/test7.qcow2 +8G
Image resized.
**NOTA** KVM todavia no muestra el nuevo tamano si hacemos 'ls -lath /var/lib/libvirt/images/test7.qcow2'
3. Arrancar la nueva VM:
sudo virsh start test7
Domain test7 started
4. Comprobar que el Sistema Operativa ve el nuevo espacio (10 GB):
ssh test7
sudo fdisk -l
Disk /dev/vda: 10.7 GB, 10737418240 bytes
16 heads, 63 sectors/track, 20805 cylinders
Units = cylinders of 1008 * 512 = 516096 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00031f27
Device Boot Start End Blocks Id System
/dev/vda1 * 3 496 248832 83 Linux
Partition 1 does not end on cylinder boundary.
/dev/vda2 498 4159 1845249 5 Extended
Partition 2 does not end on cylinder boundary.
/dev/vda5 498 4159 1845248 8e Linux LVM
Disk /dev/dm-0: 1753 MB, 1753219072 bytes
255 heads, 63 sectors/track, 213 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000
Disk /dev/dm-0 doesn't contain a valid partition table
Disk /dev/dm-1: 134 MB, 134217728 bytes
255 heads, 63 sectors/track, 16 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000
Disk /dev/dm-1 doesn't contain a valid partition table
**NOTA** Los mensajes "Partition 1 does not end on cylinder boundary." son ajenos a esta receta, pero deben evitarse con un correcto particionamiento.
5. Crear una nueva particion
sudo fdisk /dev/vda
n
p
[enter] (en mi caso particion 3)
Aqui introducir el sector final de la partición anterior más 1, o el **siguiente numero que sea divisible por 8 si el host tiene un tamanyo fisico de sector de 4096 bytes**.
Luego aceptar el valor propuesto (el último sector del disco menos 1)
w
6. Aqui hay que reiniciar para que la particion sea usable por el Sistema Operativo:
sudo shutdown -r now
7. Crear un PV con la nueva particion:
sudo pvcreate /dev/vda3
Physical volume "/dev/vda3" successfully created
8. Anyadir ese PV al VG. Primero obtener el nombre del VG y del PV:
sudo vgscan
Reading all physical volumes. This may take a while...
Found volume group "template" using metadata type lvm2
sudo pvscan
PV /dev/vda5 VG template lvm2 [1.76 GiB / 0 free]
PV /dev/vda3 lvm2 [8.00 GiB]
Total: 2 [9.76 GiB] / in use: 1 [1.76 GiB] / in no VG: 1 [8.00 GiB]
Anyadimos el PV '/dev/vda3' al VG 'template':
sudo vgextend template /dev/vda3
Volume group "template" successfully extended
9. Extendemos el VL. Primero los listamos:
sudo lvscan
ACTIVE '/dev/template/root' [1.63 GiB] inherit
ACTIVE '/dev/template/swap_1' [128.00 MiB] inherit
Vamos a extender el LV '/dev/template/root' todo lo que podamos:
sudo lvextend -l +100%FREE /dev/template/root
Extending logical volume root to 9.63 GiB
Logical volume root successfully resized
10. Extendemos el sistema de archivos. El proceso tarda 1 minuto para 8GB:
sudo resize2fs /dev/mapper/template-root
resize2fs 1.41.12 (17-May-2010)
Filesystem at /dev/mapper/template-root is mounted on /; on-line resizing required
old desc_blocks = 1, new_desc_blocks = 1
Performing an on-line resize of /dev/mapper/template-root to 2525184 (4k) blocks.
The filesystem on /dev/mapper/template-root is now 2525184 blocks long.
Comprobamos que todo ha ido bien:
df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/template-root
9.5G 565M 8.5G 7% /
tmpfs 249M 0 249M 0% /lib/init/rw
udev 244M 108K 244M 1% /dev
tmpfs 249M 0 249M 0% /dev/shm
/dev/vda1 228M 16M 201M 8% /boot
==== Montar disco qcow2 con LVM y cambio de contraaseña ====
Todas las operaciones se realizan desde el hipervisor. Este procedimiento es útil si por ejemplo queremos cambiar una contraseña que se nos ha olvidado.
1. Cargar módulo del kernel
sudo modprobe nbd max_part=63
2. Montar disco qcow2:
sudo qemu-nbd -c /dev/nbd0 /ruta/disco/vm_1.qcow2
sudo mkdir /mnt/vm_1
sudo mount /dev/nbd0p1 /mnt/vm_1
3. Si la VM tiene LVM:
3.1 (Opcional) Instalar LVM
sudo aptitude install lvm2 -R
3.2 Buscar Volume Group:
vgscan
Reading all physical volumes. This may take a while...
Found volume group "template-1" using metadata type lvm2
Encuentro el VG 'template-1'.
3.3 Activar Volume Group:
vgchange -ay
2 logical volume(s) in volume group "template-1" now active
3.4 Listar Logical Volumes:
lvdisplay
--- Logical volume ---
LV Path /dev/template-1/root
LV Name root
VG Name template-1
LV UUID Tvzd3L-24mZ-DJtf-3Rno-Inxv-r8et-fOAvpR
LV Write Access read/write
LV Creation host, time template-1, 2013-04-05 10:21:48 +0200
LV Status available
# open 0
LV Size 7.23 GiB
Current LE 1851
Segments 1
Allocation inherit
Read ahead sectors auto
- currently set to 256
Block device 252:0
--- Logical volume ---
LV Path /dev/template-1/swap_1
LV Name swap_1
VG Name template-1
LV UUID 4EY2TJ-Jcow-PFis-1VRJ-IWyE-NGwB-lSbNmd
LV Write Access read/write
LV Creation host, time template-1, 2013-04-05 10:21:48 +0200
LV Status available
# open 0
LV Size 508.00 MiB
Current LE 127
Segments 1
Allocation inherit
Read ahead sectors auto
- currently set to 256
Block device 252:1
En este caso me interesa el VL 'root', con el path '/dev/template-1/root'
3.5 Montar el LV deseado, en este caso "/":
sudo mkdir /mnt/vm_1_root
sudo mount /dev/template-1/root /mnt/vm_1_root
3.6 Entrar en esa particion:
sudo chroot /mnt/vm_1_root
3.7 Cambiar la contrasenya o realizar la operacion que se quiera:
passwd root
3.8 Salir
exit
4. Desmontar todo:
umount /mnt/vm_1_root
vgchange -an VolGroupName
umount /mnt/vm_1
killall qemu-nbd
Comprobar con "ps ax" si el proceso "qemu-nbd" ha finalizado
===== LVM =====
Acronimos:
| LVM | Logical Volume Manager |
| PV | Physical Volume |
| VG | Volume Group |
| LV | Logical Volume |
==== Alinear particiones VM con LVM ====
* VM tiene como almacenamiento un LV del host
* El host tiene 4096 bytes como tamanyo fisico de sector
* Cuando desde el host se lista los discos con "fdisk -l" se obtiene un error de alineamiento, que potencialmente puede impactar en el rendimiento, sobretodo de escritura
Device Boot Start End Blocks Id System
/dev/mapper/vg-lv_test_2p1 * 2048 499711 248832 83 Linux
/dev/mapper/vg-lv_test_2p2 501758 10483711 4990977 5 Extended
Partition 2 does not start on physical sector boundary.
/dev/mapper/vg-lv_test_2p5 501760 10483711 4990976 8e Linux LVM
1. Determinar el tamanyo del LV de origen:
sudo lvs | grep test_2
2. Crear un LV de backup con el mismo tamanyo:
sudo lvcreate vg --name lv_test_2_clone --size=8G
3. Determinar el Path del nuevo LV:
sudo lvdisplay | grep Path | grep test_2_clone
4. Determinar el Path del LV origen:
sudo lvdisplay | grep Path | grep test_2
5. Apagar la VM (mejor desde dentro de la propia VM)
6. Copiar bit a bit el LV. El Path origen se toma del paso 4 y el destino del paso 3:
time sudo dd if=/dev/vg/lv_test_2 of=/dev/vg/lv_test_2_clone bs=4096
La velocidad ronda los 60 MB/s
7. Editar la VM y anyadirle:
* Arranque por cdrom como opcion 1
* CDROM con ruta a un lice CD. Yo recomiendo [[http://www.sysresccd.org/Download|systemrescuecd]]
* Segundo disco, que apunte al LV creado en el paso 2
* VNC
sudo virsh edit test_2
Ejemplo de los bloques a anyadir en el XML de la VM (ajustar por ejemplo el nombre del disco 2, etc...):
...
...
...
...
8. Arrancar la VM y conectarse a VNC con "virt-manager":
sudo virsh start test_2
9. (VM arrancada con live CD) Con parted eliminar las particiones 2 y 5 y recrearlas. Recomiendo ejecutarlo asi:
parted -a optimal /dev/vda
Cambiamos a sectores como unidad:
u
s
Eliminamos particiones:
rm 5
rm 2
Creo la primera, extendida:
mkpart extended 501760 10483711
mkpart logical 503808 10483711
En la segunda he dejado 2048 sectores, que a 512 bytes cada uno hacen 1 MB, que parece ser que es buena practica, ya que de otra forma parted se queja de que las particiones no estan alineadas.
Le quito el flag lba a la particion extendida:
toggle 2 lba
Salgo:
quit
10. (VM arrancada con live CD) Copiar con dd de la particion destino a la origan, una vez recreada:
time dd if=/dev/vdb5 of=/dev/vda5 bs=512
Creo que el proceso de nuevo tiene una velocidad entorno a los 60 MB/s
11. (VM arrancada con live CD) Apagar
sudo shutdon -h now
12. Deshacer los cambios sobre la VM hechos en el paso 7. Si se quiere encerrarlo entre comentarios por si hay que repetir algun paso
13. Arrancar la VM
14. Si todo funciona correctamente, borrar el LV de backup creado en el paso 2:
sudo lvremove /dev/vg/lv_test_2_clone
==== Usar LV como almacenamiento ====
http://blog.gadi.cc/better-lvm-for-kvm/
http://vitobotta.com/kvm-virtual-machines-lvm/#sthash.DSURrZdj.dpbs
Asumo que el PV y el VG ya existen. Vamos a crear un LV por cada VM. Seguimos pues los siguientes pasos:
1. Crear el LV con la extension deseada:
sudo lvcreate vg --name lv_machine_1 --size=8G
**NOTA**: NO tenemos que formatear el LV, de eso se encarga el guest
2. Ya podemos usar la ruta (Path) al LV como almacenamiento. Ejemplo de clonar una VM:
sudo virt-clone --connect=qemu:///system -o original.example.com -n machine-1.example.com -f /dev/vg/lv_machine_1
==== Montar LV dentro de una VM en el host ====
* Tenemos un host con un LV que se llama "/dev/mapper/vg-lv_test_2"
* Ese LV es el almacenamiento de una VM, "vm_1"
* Esa VM a su vez tiene LVM
1. Apagar la VM
2. Instalar paquete:
sudo aptitude install kpartx
3. Listar todos los LVs del host:
sudo lvdisplay | grep Path
En este caso nos interesa este:
/dev/vg/lv_test_2
4. (Host) Crear el mapeo de dispositivos desde la tabla de particiones:
sudo kpartx -av /dev/mapper/vg-lv_test_2
Salida:
add map vg-lv_test_2p1 (253:9): 0 497664 linear /dev/mapper/vg-lv_test_2 2048
add map vg-lv_test_2p2 (253:11): 0 2 linear /dev/mapper/vg-lv_test_2 501758
add map vg-lv_test_2p5 : 0 9981952 linear /dev/mapper/vg-lv_test_2 501760
5. Listar nuevos LVs y VG:
sudo lvscan
Aparecen estos dos nuevos:
inactive '/dev/template-1/root' [4.51 GiB] inherit
inactive '/dev/template-1/swap_1' [252.00 MiB] inherit
Aparece tambien un nuevo VG, al que pertenecen esos dos nuevos LVs:
sudo vgscan
Reading all physical volumes. This may take a while...
Found volume group "template-1" using metadata type lvm2
6. Activar el nuevo VG, para que los LVs se puedan montar:
sudo vgchange -ay template-1
Salida:
2 logical volume(s) in volume group "template-1" now active
Comprobar que ahora los LVs estan activos:
sudo lvscan
Aparecen estos dos nuevos:
ACTIVE '/dev/template-1/root' [4.51 GiB] inherit
ACTIVE '/dev/template-1/swap_1' [252.00 MiB] inherit
7. Usar los LVs. Por ejemplo lo monto:
touch /tmp/root
sudo mount /dev/template-1/root /tmp/root
8. Deshacer los cambios:
8.1. Desmontar:
sudo umount /tmp/root
8.2. Deshabilitar el VG:
sudo vgchange -an template-1
Salida:
0 logical volume(s) in volume group "template-1" now active
8.3. Eliminar el mapeo de dispositivos desde la tabla de particiones:
sudo kpartx -rv /dev/mapper/vg-lv_test_2
Salida:
del devmap : vg-lv_test_2p5
del devmap : vg-lv_test_2p2
del devmap : vg-lv_test_2p1
===== Crear storage pool =====
En este ejemplo le vamos a asignar un LV a una VM.
1. Crear un .xml con la definicion, no importa la ruta:
vim ~/vm_1.xml
template_1/var/lib/libvirt/images/template_1
2. Crear el directorio "target"
sudo mkdir /var/lib/libvirt/images/template_1
3. Definir el pool storage:
sudo virsh pool-define ~/vm_1.xml
4. Marcarlo para que se inicie al arrancar la maquina:
sudo virsh pool-autostart vm_1
5. Arrancar el pool. Esta accion monta "source" en "target". Si "target" no existe devuelve un error:
sudo virsh pool-start vm_1
6. Comprobar:
cat /etc/mtab | grep vm_1
/dev/mapper/vg-vm_1 /var/lib/libvirt/images/vm_1 ext4 rw,relatime,data=ordered 0 0
===== Cambiar formato del disco =====
1. Paramos la VM:
sudo shutdown www-1.dev.local.example.com
2. Exportamos el disco de formato 'raw' a 'qcow2':
sudo qemu-img convert -p -O qcow2 /var/lib/libvirt/images/www-1.dev.local.example.com.raw /var/lib/libvirt/images/www-1.dev.local.example.com.qcow2
Se ha creado el nuevo archivo.
3. Editamos la VM:
sudo virsh edit www-1.dev.local.example.com
Y editamos los parametros 'type' y 'source file':
Grabamos y salimos
4. Arrancamos la VM:
sudo virsh start www-1.dev.local.example.com
Si arranca correctamente nos cepillamos el disco en formato "raw" que ya no usaremos:
sudo rm -fr www-1.dev.local.example.com.raw
===== Anyadir un disco en caliente =====
http://serverfault.com/questions/457250/kvm-and-libvirt-how-do-i-hotplug-a-new-virtio-disk
First of all, you should avoid using virsh attach-disk with its limited amount of options. Instead, I suggest to specify the exact disk format you prefer in a separate, temporary XML file, like this:
Before adding it, make sure the hotplug kernel modules are loaded in the guest:
modprobe acpiphp
modprobe pci_hotplug
Some distributions, including recent CentOS/RHEL/Fedora have this built-in in the kernel. In this case, check for CONFIG_HOTPLUG_PCI_ACPI. If it's y, then you're all set.
Finally, add it to the running VM using
virsh # attach-device [domain] /path/to/disk.xml
(optionally, add the --persistent option to let Libvirt update the domain XML definition 'persistent'.)
In the guest, the kernel should now be triggered, as can be checked with dmesg:
[ 321.946440] virtio-pci 0000:00:06.0: using default PCI settings
[...]
[ 321.952782] vdb: vdb1 vdb2
This also works perfectly using the GUI-enabled virt-manager application.
See also:
http://www.linux-kvm.org/page/Hotadd_pci_devices
http://serverfault.com/questions/453456/adding-virtio-block-devices-at-runtime-in-libvirt-kvm
====== Snapshots ======
http://redes-privadas-virtuales.blogspot.com.es/2011/03/taking-snapshots-on-kvm-with-libvirt.html
http://www.thegoldfish.org/2011/09/reverting-to-a-previous-snapshot-using-linux-lvm/
Caracteristicas/limitaciones:
* Virt-manager (0.9.1) NO soporta snapshots, por lo que tenemos que hacerlo desde la lina de comandos
* Solo el formato de disco virtual qcow2 soporta snapshots
* Se puede tomar un snapshot con la VM corriendo (2GB disco tarda 3m14.810s)
* **Se puede restaurar un snapshot con la VM corriendo** (creo que Virtualbox NO lo soporta)
===== raw + LVM =====
* El host tiene que tener instalado LVM
* El almacenamiento de la VM es un LV dedicado de LVM
* El disco de la VM esta en formato raw, que **NO** soporta snapshots
Consideraciones y estrategia propuesta:
* El snapshot impacta negativamente el rendimiento del disco
* La estrategia pues tiene que ser: 1) Crear "snapshot" 2) Copiar "snapshot" a "snapshot_backup" 3) Eliminar snapshot
* El tamanyo de "snapshot" puede ser pequenyo, muy inferior al del LV original
* El tamanyo de "snapshot_backup" tiene que ser el mismo que el del LV original
==== Tomar snapshot ====
1. Se puede ejecutar con la VM corriendo. Desde el host ejecutar:
sudo lvcreate -s /dev/vg/lv_vm_1 -L 1G -n lv_vm_1_snapshot_1
==== Backup del snapshot ====
1. Crear un nuevo LV para el backup. Tiene que tener el mismo tamanyo que el del LV del cual se tomo el snapshot:
sudo lvcreate vg --name lv_vm_1_snapshot_1_backup --size=8G
2. Copiar con dd el snapshot al backup. Ajustar el block size (bs):
time sudo dd if=/dev/vg/lv_vm_1_snapshot_1 of=/dev/vg/lv_vm_1_snapshot_1_backup bs=512
Velocidad: **50.9 MB/s**
3. Eliminar el snapshot:
sudo lvremove /dev/vg/lv_vm_1_snapshot_1
==== Restaurar el snapshot ====
1. Parar la VM
2. Copiar con dd desde el backup al LV original. Ajustar el block size (bs):
time sudo dd if=/dev/vg/lv_vm_1_snapshot_1_backup of=/dev/vg/lv_vm_1 bs=512
Velocidad: **53.8 MB/s**
3. Encender la VM
===== qcow2 =====
==== Tomar snapshot / migrar formato de disco raw a qcow2 ====
1. Conectarse al hipervisor. Yo por simplicidad lo hago a traves de SSH, pero a lo mejor es posible conectarse desde el cliente con un virsh -c URL
ssh usuario@hipervisor
2. Crear un archivo .xml con informacion sobre el snapshot:
sudo vim /var/lib/libvirt/qemu/snapshot/test2_snapshot_01.xml
Con el siguiente contenido:
test2_snapshot_01_160520121140Fresh install of Debian Squeeze 64 bits
Grabar y salir
3. **IMPORTANTE**: solo el formato qcow2 soporta snapshots. Vamos a comprobar que formato tiene el disco duro de la VM, que en este ejemplo se llama "test2"
sudo virsh edit test2
De la informacion que muestra nos fijamos en el disco:
...
...
Si intentamos tomar el snapshot veremos que NO lo soporta (:q! para salir de la ventana de edicion):
sudo virsh snapshot-create test2 /var/lib/libvirt/qemu/snapshot/test2_snapshot_01.xml
error: Requested operation is not valid: Disk '/var/lib/libvirt/images/test2.img' does not support snapshotting
Por lo que volvemos a editar:
sudo virsh edit test2
Y dejamos la seccion de disco tal que asi (solo cambiar qcow2):
...
...
Grabar y salir
Domain test2 XML configuration edited.
**TODO**: quiza hay un comando para cambiar el formato del disco
4. Convertir el disco de formato raw a qcow2. La VM debe estar apagada
sudo qemu-img convert -f raw -O qcow2 -o preallocation=metadata /var/lib/libvirt/images/test2.img /var/lib/libvirt/images/test2.qcow2
sudo chown libvirt-qemu:kvm /var/lib/libvirt/images/test2.qcow2
5. Volver a tomar el snapshot:
sudo virsh snapshot-create test2 /var/lib/libvirt/qemu/snapshot/test2_snapshot_01.xml
Domain snapshot test2_snapshot_01_160520121140 created from '/var/lib/libvirt/qemu/snapshot/test2_snapshot_01.xml'
Para verlo:
sudo virsh snapshot-list test2
Name Creation Time State
------------------------------------------------------------
test2_snapshot_01_160520121140 2012-05-16 12:46:48 +0200 shutoff
**RENDIMIENTO** si tomamos el snapshot de una VM corriendo (2GB de disco duro) me tomo 03'14"
6. Arrancar la VM y verificar que funciona correctamente
sudo virsh start test2
Domain test2 started
7. Si ha arrancado correctamente, eliminar el viejo disco:
sudo rm -fr /var/lib/libvirt/images/test2.img
==== Script para tomar snapshot ====
* Requiere python 2
* Se tiene que ejecutar como root
* Ejecutar 'sudo ./snapshot.py', o el nombre que le des al script
#!/usr/bin/python
import sys, commands, time, os, datetime
# Variables
path_snapshots = '/var/lib/libvirt/qemu/snapshot/'
header = ['Id', 'Name', 'State']
snapshot_template = """\
NAMEDESCRIPTION
"""
# Code
if not os.geteuid() == 0:
print "You aren't root. Goodbye."
sys.exit()
output = commands.getoutput('virsh list --all')
print output
list_vm = [line for line in output.split('\n') if '---' not in line and not all(e in line for e in header)]
row_number_list_vm = int(raw_input('Select which VM to take snapshot.\nUse line number (1 for " %s" etc...): '\
%(list_vm[0])))
line = list_vm[row_number_list_vm-1]
print 'You selected "%s"' %(line)
description = raw_input('Please type a description for this snapshot: ')
aux = line.split(' ')[0].split(' ')
vm_name = aux[len(aux)-1]
snapshot_name = vm_name + '_' + str(time.time()).split('.')[0]
snapshot_xml_path = path_snapshots + snapshot_name + '.xml'
snapshot_xml = snapshot_template.replace('NAME',snapshot_name).replace('DESCRIPTION',description)
file = open(snapshot_xml_path, 'w+')
file.write(snapshot_xml)
file.close()
print "WARNING, the process takes a while. For a running machine with 2 GB disk can take 3 minutes"
print datetime.datetime.today()
output = commands.getstatusoutput('virsh snapshot-create %s %s' %(vm_name,snapshot_xml_path))
if output[0] != 0:
print 'Error %s' %(str(output))
print datetime.datetime.today()
==== Restaurar snapshot ====
1. Conectarse al hipervisor. Yo por simplicidad lo hago a traves de SSH, pero a lo mejor es posible conectarse desde el cliente con un virsh -c URL
ssh usuario@hipervisor
2. Listar las snapshots que tenemos (nuestra VM se llama 'test2'):
sudo virsh snapshot-list test2
Name Creation Time State
------------------------------------------------------------
test2_snapshot_01_160520121140 2012-05-16 12:46:48 +0200 shutoff
test2_snapshot_02 2012-05-16 12:58:29 +0200 running
test2_snapshot_03 2012-05-16 13:03:33 +0200 running
3. Restaurar por ejemplo segunda (test2_snapshot_02):
sudo virsh snapshot-revert test2 test2_snapshot_02
Tarda un par de segundos
==== Borrar snapshot ====
Los snapshots soportan como parametros --children, pero si no se le ha pasado en el momento de tomarlo, son considerados totalmente independientes, es decir, se pueden borar 1 a 1:
sudo virsh snapshot-delete test2 test2_snapshot_02
Domain snapshot test2_snapshot_02 deleted
====== Clonar ======
* Se puede hacer tanto desde GUI (no lo he probado) como desde linea de comandos
* Requiere pausar (mejor) o apagar la VM
* Para una maquina de 2 GB de disco duro .qcow2 provisionado por completo el proceso completo tarda unos 20"
1. Conectar al hipervisor
ssh USUARIO@HIPERVISOR
2. Pausar la VM a clonar. Durante este tiempo consume recursos pero NO es accesible
sudo virsh suspend template
Domain template suspended
3. Clonar la VM:
sudo virt-clone --connect=qemu:///system -o template -n template_clone -f /var/lib/libvirt/images/template_clone.qcow2
Asignando 'template_clone.qcow2' | 2.0 GB 00:02
Clon 'template_clone' creado correctamente.
**NOTA**: para mayor rendimiento el almacenamiento tiene que ser un LV de LVM previamente creado y NO montado:
sudo virt-clone --connect=qemu:///system -o template -n template_clone -f /dev/lvm_vg/lvm_lv_template_clone
4. Reanudar la VM:
sudo virsh resume template
Domain template resumed
Tabla resumen de tiempos
^ CPU host ^ Memoria host ^ Discos host ^ Formato origen ^ Formato destino ^ MB/s ^
| 2xIntel(R) Core(TM)2 Duo E6750 2.66GHz | 8GB DDR2 800MHz | RAID 1 2xST1000DM003-1CH162 | qcow2 file | qcow2 LV | 105.03 |
====== Exportar ======
El proceso comprende dos pasos: exportar la configuracion del guest y copiar el disco o discos.
El primero es comun para cualquier tipo de disco, y se hace asi:
virsh dumpxml foo > /tmp/foo.xml
El segundo depende del tipo de almacenamiento que se haya escogido.
* Almacenamiento en archivo
Copiar el disco o discos. En mi caso lo he hecho con un disco .qcow2, pero hay que documentar como exportar VMs con discos en volumenes LVM
scp /path/disco_1.qcow2 /destino/disco_1.qcow2
* Almacenamiento en LV
time sudo dd if=/dev/vg/lv_test_3 bs=512 | gzip -9 > /srv/no_data/test_3_backup
o
time sudo qemu-img convert -c /dev/vg/lv_test_3 -O qcow2 test.img -p
o
time sudo qemu-img convert /dev/vg/lv_test_3 test_3.img -p
o
time sudo qemu-img convert /dev/vg/lv_test_3 /dev/vg/lv_test_3_clone -p
^ Metdo ^ Almacenamiento origen ^ Formato origen ^ Almacenamiento destino ^ Formato destino ^ AlMB/s ^
| dd | ? | ? | ? | ? | 20.2 MB/s |
| qemu-img (cambio formato) | ? | ? | ? | ? |40.3 MB/s |
| qemu-img (mantengo formato) | ? | ? | ? | ? | 124.12 MB/s |
| qemu-img (mantengo formato, destino LV) | ? | ? | ? | ? | 91.02 MB/s |
| qemu-img | LV | raw | LV | raw | 54.61 MB/s |
| dd bs=4096 | LV | raw | LV | raw | 57.1 MB/s |
====== Importar ======
===== Metodo 1 (seguir este) =====
1. Copiar el .xml donde se define la VM y que previamente hemos exportado a una ruta accesible por livbirt-bin:
sudo cp /tmp/vm-1.example.com.xml /etc/libvirt/qemu
2. Editar el archivo para verificar que los siguientes elementos existen o son soportados. en el nuevo hipervisor al que se quiere importar:
* CPU. Verificar que el nuevo hipervisor tiene esas capacidades
core2duoIntel
* Disco. Asegurarnos que hemos movido/montado el disco que previamente hemos exportado a la ruta/volumen/etc... correcto en el hipervidor:
* Red. Asegurarnos que la red existe en el hipervisor. Por supuesto luego tendremos que resolver cualquier conflicto de IPs, pero eso es ya a nivel de Sistema Operativo. En este ejemplo la red se llama "default"
3. Mover/montar el disco a la ruta/punto de montaje especificado por el archivo .xml
4. Definir la VM:
sudo virsh define /etc/libvirt/qemu/vm-1.example.com.xml
5. Si todo ha ido bien ya podemos arrancar la maquina:
sudo virsh start vm-1.example.com
===== Metodo 2 (revisar) =====
1. Arrancar la red 'default':
sudo virsh net-start default
Salida:
Network default started
2. Restaurar/importar una VM a partir de un archivo:
sudo virt-install --name dns-1.dev.jj.com --ram 512 --disk /var/lib/libvirt/images/dns-1.dev.jj.com.qcow2 --import
====== Red ======
Configuraciones de red
===== Hipervisor =====
* Crear una red nueva (pulir)
Probar con el procedimiento documentado en:
http://libvirt.org/sources/virshcmdref/html/sect-net-start.html
1. Crear directorio:
sudo mkdir /var/lib/libvirt/network
2. Crear archivo de configuracion:
sudo vim /var/lib/libvirt/network/default.xml
Con el siguiente contenido:
default066c4de2-ec3f-aebe-742e-dfa7f4de3f28
3. Intentar editar el archivo:
sudo virsh
net-create /var/lib/libvirt/network/default.xml
Si da un error, intentar arrancar la red:
sudo virsh net-autostart default
4. Ajustar IP y nombre del bridge de la maquina KVM en las reglas de cortafuegos
* Editar una red
1. Editar la red, en este caso "default":
sudo virsh net-edit default
2. Realizar los cambios y guardarlos
3. **AVISO** en este punto se pierde conectividad. Reiniciar la red:
sudo virsh net-destroy default; sudo virsh net-start default
===== VM =====
Ejemplo de archivo de configuracion de VM:
template-1.dev.jj.comf75dcbdc-8fc9-b50c-6612-c34dfebea16f10485765242882hvmdestroyrestartrestart/usr/bin/kvm
====== Compartir directorios del hipervisor a las VM ======
http://wiki.qemu.org/Documentation/9psetup
http://libvirt.org/formatdomain.html#elementsFilesystems
http://v9fs.sourceforge.net/
http://sourceforge.net/p/v9fs/mailman/v9fs-users/?viewmonth=201310
http://troglobit.com/blog/2013/07/05/file-system-pass-through-in-kvm-slash-qemu-slash-libvirt/
https://www.kernel.org/doc/ols/2010/ols2010-pages-109-120.pdf
===== Virtfs (9p) mapped =====
NO hace falta cargar los modulos en el host. En los guests ya se cargan por defecto, por tanto no hay que hacer nada a nivel de modolos del kernel.
1. (Hipervisor) Editar la vm en cuestion, mejor si esta apagada:
sudo virsh edit vm_1
Y anyadirle el siguiente bloque, dentro de la seccion :
...
...
...
...
**NOTA**: tras grabar KVM le anyadira la siguiente linea:
2. (Hipervisor) Arrancar la VM:
sudo virsh start vm_1
3. (VM) Montar manualmente la particion:
sudo mkdir /mnt/kvm_9p
sudo mount -t 9p -o trans=virtio tag_srv_data /mnt/kvm_9p -oversion=9p2000.L
Con fstab:
/mnt/kvm_9p /mnt/kvm_9p 9p trans=virtio,version=9p2000.L,rw,users,auto 0 0
4. Pruebas:
4.1. Lectura:
sudo ls -la /mnt/kvm_9p
Si hay algun error, consultar los logs del hipervisor y ver si es apparmor el que se queja:
Apr 18 14:03:10 kvm-1 kernel: [446419.384647] type=1400 audit(1366286590.878:72): apparmor="DENIED" operation="open" parent=1 profile="libvirt-c9fcbe04-e995-48eb-0bae-6a00427cb0cf" name="/tmp/test/" pid=6786 comm="pool" requested_mask="r" denied_mask="r" fsuid=106 ouid=0
Si es asi hay que mirar apparmor (TODO)
4.2. Escritura:
touch /mnt/kvm_9p/file
Si obtenemos un error de permiso:
4.2.1. (Hipervisor) Ver con que usuario correo el proceso "qemu-system-x86_64":
ps aux | grep qemu-system-x86_64
En mi caso:
libvirt+
TODO: ver por que no aparece el nombre completo, que es 'libvirt-qemu'
4.2.2. (Hipervisor) Ajustar los permisos:
sudo chown libvirt-qemu:libvirt-qemu /srv/data
**TODO**
* Cuando el volumen es montado por un segundo guest, los guests ya solo pueden leer, y escribir como root, pero no escribir como un usuario normal. No creo que sea una limitacion de virtfs, pero tengo que investigarlo.
* En las mismas circunstancias no puedo hacer un "./script.sh" y si un "bash script.sh". No se que consecuencias puede tener
* **BUG**: cuando se anyade un nuevo punto de montaje en una VM (virsh edit vm_1) tengo que parar y luego arrancar la VM para que esta vea el punto de montaje. Si simplemente la reinicio vera los puntos de montajes anteriores, pero no el nuevo
===== Virtfs (9p) passthrough =====
El proceso es identico a [[informatica:linux:virtualizacion:kvm#virtfs_9p_mapped]] con la excepcion que se usa "passthrough" en lugar de "mapped" en el paso 1.
Ademas no se podra escribir (si leer) a no ser que el proceso "qemu-system-x86_64" se ejecute como root.
====== Performance tunning ======
http://pic.dhe.ibm.com/infocenter/lnxinfo/v3r0m0/index.jsp?topic=%2Fliaat%2Fliaattunkickoff.htm
http://virt-tools.org/learning/install-with-command-line/
===== Disco =====
TODO
===== CPU =====
https://www.berrange.com/posts/2010/02/15/guest-cpu-model-configuration-in-libvirt-with-qemukvm/
Primero algunos conceptos:
* Cada modelo de CPU tiene unas capacidades
* Las capacidades que ve el Sistema Operativo (/proc/cpuinfo) NO tienen una correpondencia exacta en libvirt (sudo virsh capabilities), porque incluye una capa de abstraccion que soporta distintas arquitecturas
* Para poder migrar VMs de un host a otro, en caso de que se haya especificado alguna capacidad en esa VM en concreto, los dos hosts tienen que soportarla
En este ejemplo vamos a ver el antes y el despues en las capacidades CPU de una VM antes y despues de exponerle las capacidades de la CPU del host en el que esta.
1. (Host) Vemos capacidades de la CPU a nivel de sistema operativo:
cat /proc/cpuinfo | grep flags | uniq
O para importar en una tabla:
cat /proc/cpuinfo | grep flags | uniq | cut -d ":" -f2 | sed 's/\ /\n/g' | sort
2. (Host) Repetimos el mismo procedimiento en una VM. Iniciamos sesion en la VM y lanzamos el mismo comando:
cat /proc/cpuinfo | grep flags | uniq
Pongo juntos en una misma tabla los resultados:
^ Capacidades CPU host ^ Capacidades CPU guest (antes) ^ Capacidades CPU guest (despues) ^
| acpi | | |
| aperfmperf | | |
| apic | apic | |
| arat | | |
| arch_perfmon | | |
| bts | | |
| clflush | clflush | |
| cmov | cmov | |
| constant_tsc | | |
| cx16 | cx16 | |
| cx8 | cx8 | |
| de | de | |
| ds_cpl | | |
| dtes64 | | |
| dtherm | | |
| dts | | |
| epb | | |
| ept | | |
| est | | |
| flexpriority | | |
| fpu | fpu | |
| fxsr | fxsr | |
| ht | hypervisor | |
| lahf_lm | lahf_lm | |
| lm | lm | |
| mca | mca | |
| mce | mce | |
| mmx | mmx | |
| monitor | | |
| msr | msr | |
| mtrr | mtrr | |
| nonstop_tsc | | |
| nopl | nopl | |
| nx | nx | |
| pae | pae | |
| pat | | |
| pbe | | |
| pcid | | |
| pclmulqdq | | |
| pdcm | | |
| pebs | | |
| pge | pge | |
| pln | | |
| pni | pni | |
| popcnt | popcnt | |
| pse | pse | |
| pse36 | pse36 | |
| pts | | |
| rdtscp | | |
| rep_good | rep_good | |
| sep | sep | |
| ss | | |
| sse | sse | |
| sse2 | sse2 | |
| sse4_1 | | |
| sse4_2 | | |
| ssse3 | | |
| syscall | syscall | |
| tm | | |
| tm2 | | |
| tpr_shadow | | |
| tsc | tsc | |
| tsc_deadline_timer | | |
| vme | | |
| vmx | vmx | |
| vnmi | | |
| vpid | | |
| xsave | | |
| xsaveopt | | |
| xtopology | | |
| xtpr | | |
3. (Host) vemos las capacidades que libvirt nos dice que tiene el host:
sudo virsh capabilities | more
Nos quedamos con el siguiente bloque:
x86_64NehalemIntel
4. (Host) vemos las capacidades que libvirt nos dice que tiene la VM:
sudo virsh dumpxml vm-1.example.com | more
Nos quedamos con el siguiente bloque:
...
2
...
Como puede observarse no tienen acceso a ninguna de las capacidades de la CPU del host donde corre.
5. Expongo las capacidades de la CPU del host a la VM:
5.1. Apago la VM a nivel de sistema operativo:
ssh vm-1.example.com
sudo shutdown -h now
5.2. Edito la VM:
sudo virsh edit vm-1.example.com
En el editor busco el bloque del paso 4:
2
Y lo sustituyo por el siguiente bloque, adaptacion del bloque del paso 3:
NehalemIntel
Grabo y salgo.
5.3. Compruebo que los cambios se han grabado repitiendo el paso 4.
5.4. Arranco la VM:
sudo virsh start vm-1.example.com
5.5. Repito el paso 2. La salida ahora es diferente. Resumen:
^ Capacidades CPU host ^ Capacidades CPU guest (antes) ^ Capacidades CPU guest (despues) ^
| acpi | | |
| aperfmperf | | |
| apic | apic | apic |
| arat | | |
| arch_perfmon | | |
| bts | | |
| clflush | clflush | clflush |
| cmov | cmov | cmov |
| constant_tsc | | |
| cx16 | cx16 | cx16 |
| cx8 | cx8 | cx8 |
| de | de | de |
| ds_cpl | | |
| dtes64 | | |
| dtherm | | |
| dts | | |
| epb | | |
| ept | | |
| est | | |
| flexpriority | | |
| fpu | fpu | fpu |
| fxsr | fxsr | fxsr |
| ht | hypervisor | hypervisor |
| lahf_lm | lahf_lm | lahf_lm |
| lm | lm | lm |
| mca | mca | mca |
| mce | mce | mce |
| mmx | mmx | mmx |
| monitor | | |
| msr | msr | msr |
| mtrr | mtrr | mtrr |
| nonstop_tsc | | |
| nopl | nopl | nopl |
| nx | nx | nx |
| pae | pae | pae |
| pat | | |
| pbe | | |
| pcid | | |
| pclmulqdq | | pclmulqdq |
| pdcm | | |
| pebs | | |
| pge | pge | pge |
| pln | | |
| pni | pni | pni |
| popcnt | popcnt | popcnt |
| pse | pse | pse |
| pse36 | pse36 | pse36 |
| pts | | |
| rdtscp | | rdtscp |
| rep_good | rep_good | rep_good |
| sep | sep | sep |
| ss | | ss |
| sse | sse | sse |
| sse2 | sse2 | sse2 |
| sse4_1 | | sse4_1 |
| sse4_2 | | sse4_2 |
| ssse3 | | ssse3 |
| syscall | syscall | syscall |
| tm | | |
| tm2 | | |
| tpr_shadow | | |
| tsc | tsc | tsc |
| tsc_deadline_timer | | tsc_deadline_timer |
| | | up |
| vme | | vme |
| vmx | vmx | vmx |
| vnmi | | |
| vpid | | |
| xsave | | |
| xsaveopt | | |
| xtopology | | |
| xtpr | | |
Conclusiones:
* NO todas las capacidades de la CPU del host son ahora accesibles por la VM
* Hay capacidades nuevas que antes no estaba
* Ha aparecido una capacidad nueva, "up" que antes no estaba ni siquiera en el host
====== Apagado y encendido controlado ======
Siempre es bueno ir VM a VM parando servicios de forma controlada, como por ejemplo mysql, pero si tenemos prisa:
1. Parar todas las VMs:
sudo service libvirt-guests stop
Por pantalla va indicando el progreso. Para comprobar siempre haremos un:
sudo virsh list --all
2. Arrancar todas las VMs que esten definidas como autostart:
sudo service libvirt-bin restart
====== Otras herramientas ======
http://libguestfs.org/virt-resize.1.html
http://libguestfs.org/guestfish.1.html
====== libvirt ======
**TODO** quiza habria que mover esta seccion a un articulo propio
===== ACL =====
http://libvirt.org/acl.html
http://libvirt.org/aclpolkit.html
https://wiki.archlinux.org/index.php/libvirt#Using_Python
Ejemplo sencillo de uso sin contrasenya si se dan las siguientes condiciones:
* Configuracion por defecto (**NO** se ha habilitado policykit)
* El usuario que ejecuta el script pertenece al grupo especificado en la variable "unix_sock_group" de /etc/libvirt/libvirtd.conf
* El script se ejecuta desde el mismo hipervisor
virsh -c qemu:///system list
La url sirve para la API tambien
===== API =====
http://libvirt.org/html/libvirt-libvirt.html
==== virConnect ====
[('__class__', )
('__del__', >)
('__delattr__', )
('__dict__', {'_o': })
('__doc__', None)
('__format__', )
('__getattribute__', )
('__hash__', )
('__init__', >)
('__module__', 'libvirt')
('__new__', )
('__reduce__', )
('__reduce_ex__', )
('__repr__', )
('__setattr__', )
('__sizeof__', )
('__str__', )
('__subclasshook__', )
('__weakref__', None)
('_dispatchCloseCallback', >)
('_dispatchDomainEventBalloonChangeCallback', >)
('_dispatchDomainEventBlockPullCallback', >)
('_dispatchDomainEventCallbacks', >)
('_dispatchDomainEventDeviceRemovedCallback', >)
('_dispatchDomainEventDiskChangeCallback', >)
('_dispatchDomainEventGenericCallback', >)
('_dispatchDomainEventGraphicsCallback', >)
('_dispatchDomainEventIOErrorCallback', >)
('_dispatchDomainEventIOErrorReasonCallback', >)
('_dispatchDomainEventLifecycleCallback', >)
('_dispatchDomainEventPMSuspendCallback', >)
('_dispatchDomainEventPMSuspendDiskCallback', >)
('_dispatchDomainEventPMWakeupCallback', >)
('_dispatchDomainEventRTCChangeCallback', >)
('_dispatchDomainEventTrayChangeCallback', >)
('_dispatchDomainEventWatchdogCallback', >)
('_o', )
('baselineCPU', >)
('changeBegin', >)
('changeCommit', >)
('changeRollback', >)
('close', >)
('compareCPU', >)
('createLinux', >)
('createXML', >)
('createXMLWithFiles', >)
('defineXML', >)
('domainEventDeregister', >)
('domainEventDeregisterAny', >)
('domainEventRegister', >)
('domainEventRegisterAny', >)
('domainXMLFromNative', >)
('domainXMLToNative', >)
('findStoragePoolSources', >)
('getCPUMap', >)
('getCPUModelNames', >)
('getCPUStats', >)
('getCapabilities', >)
('getCellsFreeMemory', >)
('getFreeMemory', >)
('getHostname', >)
('getInfo', >)
('getLibVersion', >)
('getMaxVcpus', >)
('getMemoryParameters', >)
('getMemoryStats', >)
('getSecurityModel', >)
('getSysinfo', >)
('getType', >)
('getURI', >)
('getVersion', >)
('interfaceDefineXML', >)
('interfaceLookupByMACString', >)
('interfaceLookupByName', >)
('isAlive', >)
('isEncrypted', >)
('isSecure', >)
('listAllDevices', >)
('listAllDomains', >)
('listAllInterfaces', >)
('listAllNWFilters', >)
('listAllNetworks', >)
('listAllSecrets', >)
('listAllStoragePools', >)
('listDefinedDomains', >)
('listDefinedInterfaces', >)
('listDefinedNetworks', >)
('listDefinedStoragePools', >)
('listDevices', >)
('listDomainsID', >)
('listInterfaces', >)
('listNWFilters', >)
('listNetworks', >)
('listSecrets', >)
('listStoragePools', >)
('lookupByID', >)
('lookupByName', >)
('lookupByUUID', >)
('lookupByUUIDString', >)
('networkCreateXML', >)
('networkDefineXML', >)
('networkLookupByName', >)
('networkLookupByUUID', >)
('networkLookupByUUIDString', >)
('newStream', >)
('nodeDeviceCreateXML', >)
('nodeDeviceLookupByName', >)
('nodeDeviceLookupSCSIHostByWWN', >)
('numOfDefinedDomains', >)
('numOfDefinedInterfaces', >)
('numOfDefinedNetworks', >)
('numOfDefinedStoragePools', >)
('numOfDevices', >)
('numOfDomains', >)
('numOfInterfaces', >)
('numOfNWFilters', >)
('numOfNetworks', >)
('numOfSecrets', >)
('numOfStoragePools', >)
('nwfilterDefineXML', >)
('nwfilterLookupByName', >)
('nwfilterLookupByUUID', >)
('nwfilterLookupByUUIDString', >)
('registerCloseCallback', >)
('restore', >)
('restoreFlags', >)
('saveImageDefineXML', >)
('saveImageGetXMLDesc', >)
('secretDefineXML', >)
('secretLookupByUUID', >)
('secretLookupByUUIDString', >)
('secretLookupByUsage', >)
('setKeepAlive', >)
('setMemoryParameters', >)
('storagePoolCreateXML', >)
('storagePoolDefineXML', >)
('storagePoolLookupByName', >)
('storagePoolLookupByUUID', >)
('storagePoolLookupByUUIDString', >)
('storageVolLookupByKey', >)
('storageVolLookupByPath', >)
('suspendForDuration', >)
('unregisterCloseCallback', >)
('virConnGetLastError', >)
('virConnResetLastError', >)]
==== virDomain ====
[('ID', >)
('OSType', >)
('UUID', >)
('UUIDString', >)
('XMLDesc', >)
('__class__', )
('__del__', >)
('__delattr__', )
('__dict__', {'_conn': , '_o': })
('__doc__', None)
('__format__', )
('__getattribute__', )
('__hash__', )
('__init__', >)
('__module__', 'libvirt')
('__new__', )
('__reduce__', )
('__reduce_ex__', )
('__repr__', )
('__setattr__', )
('__sizeof__', )
('__str__', )
('__subclasshook__', )
('__weakref__', None)
('_conn', )
('_o', )
('abortJob', >)
('attachDevice', >)
('attachDeviceFlags', >)
('autostart', >)
('blkioParameters', >)
('blockCommit', >)
('blockInfo', >)
('blockIoTune', >)
('blockJobAbort', >)
('blockJobInfo', >)
('blockJobSetSpeed', >)
('blockPeek', >)
('blockPull', >)
('blockRebase', >)
('blockResize', >)
('blockStats', >)
('blockStatsFlags', >)
('connect', >)
('controlInfo', >)
('coreDump', >)
('create', >)
('createWithFiles', >)
('createWithFlags', >)
('destroy', >)
('destroyFlags', >)
('detachDevice', >)
('detachDeviceFlags', >)
('diskErrors', >)
('emulatorPinInfo', >)
('fSTrim', >)
('getCPUStats', >)
('hasCurrentSnapshot', >)
('hasManagedSaveImage', >)
('hostname', >)
('info', >)
('injectNMI', >)
('interfaceParameters', >)
('interfaceStats', >)
('isActive', >)
('isPersistent', >)
('isUpdated', >)
('jobInfo', >)
('jobStats', >)
('listAllSnapshots', >)
('managedSave', >)
('managedSaveRemove', >)
('maxMemory', >)
('maxVcpus', >)
('memoryParameters', >)
('memoryPeek', >)
('memoryStats', >)
('metadata', >)
('migrate', >)
('migrate2', >)
('migrate3', >)
('migrateGetCompressionCache', >)
('migrateGetMaxSpeed', >)
('migrateSetCompressionCache', >)
('migrateSetMaxDowntime', >)
('migrateSetMaxSpeed', >)
('migrateToURI', >)
('migrateToURI2', >)
('migrateToURI3', >)
('name', >)
('numaParameters', >)
('openChannel', >)
('openConsole', >)
('openGraphics', >)
('pMSuspendForDuration', >)
('pMWakeup', >)
('pinEmulator', >)
('pinVcpu', >)
('pinVcpuFlags', >)
('reboot', >)
('reset', >)
('resume', >)
('revertToSnapshot', >)
('save', >)
('saveFlags', >)
('schedulerParameters', >)
('schedulerParametersFlags', >)
('schedulerType', >)
('screenshot', >)
('securityLabel', >)
('securityLabelList', >)
('sendKey', >)
('sendProcessSignal', >)
('setAutostart', >)
('setBlkioParameters', >)
('setBlockIoTune', >)
('setInterfaceParameters', >)
('setMaxMemory', >)
('setMemory', >)
('setMemoryFlags', >)
('setMemoryParameters', >)
('setMemoryStatsPeriod', >)
('setMetadata', >)
('setNumaParameters', >)
('setSchedulerParameters', >)
('setSchedulerParametersFlags', >)
('setVcpus', >)
('setVcpusFlags', >)
('shutdown', >)
('shutdownFlags', >)
('snapshotCreateXML', >)
('snapshotCurrent', >)
('snapshotListNames', >)
('snapshotLookupByName', >)
('snapshotNum', >)
('state', >)
('suspend', >)
('undefine', >)
('undefineFlags', >)
('updateDeviceFlags', >)
('vcpuPinInfo', >)
('vcpus', >)
('vcpusFlags', >)]
==== Varios ====
* Obtener la lista de dominios no-activos:
conn = libvirt.open("qemu+ssh://localhost/system")
domains = conn.listDefinedDomains()
* Obtener la lista de dominios activos:
conn = libvirt.open("qemu+ssh://localhost/system")
domains = conn.listDomainsID()