Virtualizar servidor centos

2017/08/16

A continuación se detalla la experiencia obtenida al virtualizar un servidor CentOS 5.7 que utiliza LVM. La vm correspondiente a dicho servidor será creada en un servidor de vm’s con CentOS 6.4 utilizando libvirt y virt-manager.

Dump del disco físico

Para comenzar la virtualización copiamos el contenido del disco al servidor de vm’s.

En el servidor de vm’s (al que se desea enviar la imagen) se ejecuta para recibir la imagen de disco:

(mintaka) # nc -l 12345 | bzip2 -d | dd of=/var/lib/libvirt/images/alnitak-disk1.img bs=16M

Se bootea el servidor que se desea virtualizar con una imagen live y se ejecuta para enviar la imagen de disco:

(alnitak-live) # dd if=/dev/sda bs=16M | bzip2 -c | nc 10.11.12.13 12345

Limpiar bloques no utilizados del disco

Al realizar una copia física del disco es probable que se haya leído basura en los sectores no utilizados por el filesystem. Luego, si se intenta convertir el disco a un formato que soporte la creación de imagenes dispersas (sparse images), la información basura evitará que pueda compactarse correctamente la nueva imagen de disco durante su conversión. Una técnica para evitar lo anterior es crear en el filesystem un archivo que ocupe todo el tamaño disponible y cuyo contenido sea una repetición del valor nulo, \0. Luego de que se obtenga un error, ya que no queda espacio en el dispositivo, se borra el archivo.

Crear vm para escribir disco

Para realizar lo anterior se debe crear una vm utilizando la imagen de disco. Para ello utilizamos la interfaz gráfica virt-manager.

Como detalle relevante de la configuración:

NOTA: En el último paso de la creación de la vm elegir la opción Customize configuration before install.

  1. Se elige como versión del OS CentOS 6.0, ya que la 5.7 no está disponible

  2. Se utiliza como configuración de red Host device: eth0: macvtap y como Source mode el valor Bridge para conectarnos remotamente.

  3. Se cambia la dirección MAC del dispositivo NIC.

    Esto es necesario para que al iniciar la vm no sea sobreescrito el archivo /etc/sysconfig/network-scripts/ifcfg-eth0 con la configuración de red actual.

    Para obtener la dirección MAC utilizamos el comando ip en la imagen live:

    (alnitak-live) # ip link show
    1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1
        link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    2: enp2s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
        link/ether 01:23:45:67:89:ab brd ff:ff:ff:ff:ff:ff
    

    La diferencia en los nombres de interfaz es debido a que en versiones recientes de linux se utilizan nombres consistentes para interfaces de red.

  4. Se debe cambiar el valor de Disk bus que por defecto es VirtIO, ya que utilizando este obtenemos el siguiente error al iniciar la vm:

    error al inicio

    Esto es debido a que en la wiki de libvirt sobre virtio se indica que para utilizar VirtIO hay que tener un kernel >= 2.6.25, y el CentOS 5.7 a virtualizar tiene instalada la versión del kernel 2.6.18.

    En el caso de utilizar para Disk bus el valor SATA se obtiene el siguiente error en virt-manager (versión 0.10.2):

    Error starting domain: unsupported
    configuration: SATA is not
    supported with this QEMU binary
    

    NOTA: eliminar el controlador SATA si se obtuvo el mensaje de error previo.

    Debido a los problemas anteriores encontrados terminamos utilizando IDE como valor para Disk bus.

    NOTA: según el sitio de kvm, usar IDE como storage interface es lento. En caso de ser posible es recomendable cambiar el SO a uno que pueda utilizar VirtIO (menor riesgo) o actualizar el servidor de virtualización para que pueda utilizarse SATA en las vm’s.

Actualización del kernel

Limpieza de disco

Una vez que se inició la vm pasamos a escribir todo el espacio libre del disco con el carácter \0.

Aquí hay que tener en cuenta que hay varias particiones y se está utilizando LVM, por lo que debe crearse un archivo lleno de nulos que ocupe todo el filesystem para cada filesystem y para los volúmenes libres.

Primero vemos que particiones existen utilizando parted

(alnitak-vm) # parted /dev/hda print

Model: QEMU HARDDISK (ide)
Disk /dev/hda: 160GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos

Number  Start   End    Size   Type     File system  Flags
 1      32.3kB  107MB  107MB  primary  ext3         boot
 2      107MB   160GB  160GB  primary               lvm

Information: Don't forget to update /etc/fstab, if necessary.

Luego para la invormación relativa a LVM utilizamos los comandos pvs, vgs y lvs:

(alnitak-vm) # pvs
  PV         VG         Fmt  Attr PSize   PFree
  /dev/hda2  VolGroup00 lvm2 a-   148.94G    0
(alnitak-vm) # vgs
  VG         #PV #LV #SN Attr   VSize   VFree
  VolGroup00   1   2   0 wz--n- 148.94G    0
(alnitak-vm) # lvs
  LV       VG         Attr   LSize   Origin Snap%  Move Log Copy%  Convert
  LogVol00 VolGroup00 -wi-ao 143.16G
  LogVol01 VolGroup00 -wi-ao   5.78G

Verificamos si ya están montadas las particiones en el sistema (en caso contrario necesitaremos montarlas) o están en uso como swap:

(alnitak-vm) # mount | grep -P '/dev/hda1|VolGroup'
/dev/mapper/VolGroup00-LogVol00 on / type ext3 (rw)
/dev/hda1 on /boot type ext3 (rw)
(alnitak-vm) # swapon -s | grep 'VolGroup'
/dev/mapper/VolGroup00-LogVol01         partition	6062072	0	-1

De lo anterior se deduce que:

  1. El disco está siendo totalmente utilizado por las particiónes boot y lvm
  2. La partición lvm consta de un solo volume group, VolGroup00 y este está dividido en dos logical volumes: LogVol00 y LogVol01 que utilizan todo el espacio del volumen.
  3. La partición boot (/dev/hda1) está montada en /boot.
  4. El volumen lógico LogVol00 está montado en /
  5. El volumen lógico LogVol01 está funcionando como partición swap (activa).

Para limpiar las particiones anteriores se utiliza:

NOTA: conviene ejecutar los siguientes comandos dentro de un script, y en caso de realizarlos mediante ssh utilizando screen. En caso contrario utilizar la consola desde virt-manager ya que puede llevar un buen rato que el comando se complete.

(alnitak-vm) # dd if=/dev/zero of=/EMPTY bs=16M
(alnitak-vm) # rm /EMPTY
(alnitak-vm) # dd if=/dev/zero of=/boot/EMPTY bs=16M
(alnitak-vm) # rm /boot/EMPTY
(alnitak-vm) # swapoff /dev/mapper/VolGroup00-LogVol01
(alnitak-vm) # dd if=/dev/zero of=/dev/mapper/VolGroup00-LogVol01 bs=16M
(alnitak-vm) # mkswap /dev/mapper/VolGroup00-LogVol01
(alnitak-vm) # sync

Luego apagamos y eliminamos la vm, ya que no tenemos más necesidad de utilizarla, teniendo cuidado de NO ELIMINAR LA IMAGEN DE DISCO.

Convertir disco para uso con virtualizador

Una vez que se haya limpiado la imagen del servidor que queremos virtualizar generamos una imagen dispersa (sparse image):

(mintaka) # qemu-img convert -f raw -O qcow2 \
    /var/lib/libvirt/images/alnitak-disk1.img \
    /var/lib/libvirt/images/alnitak-disk1.qcow2

Al comando anterior se le puede agregar el flag -p para tener un indicador de progreso ya que la conversión puede ser una operación lenta.

Notas

Elección del formato de imagen a utilizar

Se eligió el formato qcow2 siguiendo la sugerencia en la documentación de openstack sobre imagenes:

If your deployment uses QEMU or KVM, we recommend using the images in qcow2
format

Entre las ventajas del formato qcow2 se destacan:

TODO’s

  1. buscar una comparativa entre distintos formatos de imagen a utilizar; una búsqueda rápida en internet no dió resultado satisfactorio.

  2. En varios sitios se menciona la fragilidad de qcow2, detallar.