**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.com 12b440aa-fee3-b6cc-31d1-4d2bde56e0df 1048576 524288 2 hvm destroy restart restart /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:kvm&#vm_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_160520121140 Fresh 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 = """\ NAME DESCRIPTION """ # 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 core2duo Intel * 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: default 066c4de2-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.com f75dcbdc-8fc9-b50c-6612-c34dfebea16f 1048576 524288 2 hvm destroy restart restart /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_64 Nehalem Intel 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: Nehalem Intel 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()