Diseñando soluciones con vCloud Director

vCloud Director es un producto de Vmware que permite ofrecer portal web de cliente desde donde gestionar tus propias máquinas virtuales sin tener que gestionar la infraestructura vCennter y ESX subyacente. Esto permite a los Proveedores de Servicio (SPs) poder vender Infraestructura como Servicio (IaaS) de forma sencilla.

Para aquellas personas acostumbradas a trabajar directamente con vSphere y vCenter, vCloud Director 1.5 introduce algunas limitaciones que deben ser consideradas a la hora de diseñar una aplicación a desplegar en la nube:

Tamaño de VM: Los discos de una VM solo pueden estar en un único datastore, así que el máximo coincidirá con ese tamaño de DS. Dependiendo del proveedor, esto puede significar un tamaño máximo de VM de entre 1 y 3 Tb.

RDM: Los discos RDM no están soportados en vCD. Así que no podemos configurar clusters virtuales con almacenamiento compartido. Hay quien recomienda utilizar un servidor iSCSI (ej: FreeNAS) dentro de la solución y evitar el uso de RDMs, pero como veremos después, no hay forma de garantizar el HA del storage.

Redundancia: Si tenemos dos VM servidor web, en vSphere podemos crear una regla de anti-afinidad para que corran en servidores ESX distintos. En VCD no se puede hacer tal cosa, por lo que potencialmente podemos tener todos nuestros servidores web ejecutándose en el mismo servidor ESX. Con lo cual, significa que dejamos la "alta disponibilidad" de las máquinas virtuales en manos del HA de vSphere. En caso de fallo del ESX donde residen nuestras VMs, deberemos esperar a que vCloud las reinicie en otro host ESX.

Seguramente algunas de estas limitaciones se resuelvan o mitiguen con la próxima publicacion de VCD 2.0, que se realizará durante este mes de agosto de 2012.

Optimizando un job de backup

Este fin de semana me aburría y me he puesto a optimizar un script para realizar backup que llevo usando unos cuantos años en diversos PCs de escritorio. Es un poco "pedestre" puesto que básicamente se dedica a comprimir con tar una serie de directorios, y guardar el contenido en un disco externo USB.

Originalmente el script era algo así :

#! /bin/bash
DATE=$(date +%Y-%m-%d)
BACKUP_MNT="/media/disco_usb"
BACKUP_TARGET="$BACKUP_MNT/backup/$HOSTNAME"
TAROPS="--absolute-names --atime-preserve -z "

mkdir -p $BACKUP_TARGET/$DATE
BACKUP_TARGET="$BACKUP_TARGET/$DATE"

FILEPREFIX="$BACKUP_TARGET/$DATE-$HOSTNAME"

if [ ! -d "$BACKUP_TARGET" ]; then
        echo "Backup target '$BACKUP_TARGET' does not exit, cannot backup"
        exit 0
fi

tar -c $TAROPS -f $FILEPREFIX-home.tar.gz /home
tar -c $TAROPS -f $FILEPREFIX-etc.tar.gz  /etc
# Y aquí más comandos similares para otros directorios.

md5sum $FILEPREFIX-home.tar.gz > $FILEPREFIX-home.tar.gz.md5
md5sum $FILEPREFIX-etc.tar.gz  > $FILEPREFIX-etc.tar.gz.md5
# Despues de comprimir los ficheros, guardamos la suma MD5 para poder
# saber en el futuro si han sido alterados (fichero a medias, problemas
# de lectura si es un CDROM, etc).

Esta forma de hacer el backup no es muy eficiente, porque gzip (opción -z) solo aprovecha un único core a la vez, con lo que no sacamos provecho de tener múltiples cores/procesadores.

Además, el proceso de hacer un md5sum era bastante costoso al tener que releer desde disco el fichero comprimido (en mi caso, unos 20Gb).

Para el primer problema, me ha alegrado descubrir pigz, un clon de gzip multihilo que aprovecha todos los cores de forma simultánea. El uso es tan sencillo como pigz fichero.tar , o en el caso de quererlo usar con tar :

tar -I pigz -cf fichero.tar.gz  dir1 dir2 dir3

Para el segundo problema, he recordado la existencia de tee, un programa de GNU que nos permite enviar la entrada estándar hacia múltiples procesos y salidas. ¿Cómo nos influye esto en el rendimiento? Simplemente es mucho menos costoso hacer la suma MD5SUM antes de escribir el fichero en disco (mientras está en memoria), que escribirlo y luego tenerlo que leer.

La idea con esto, por tanto, es que tar genere un fichero comprimido y que mediante tee, sea examinado por MD5SUM y, por otra parte, redireccionada la salida estándar al fichero .tar.gz correspondiente. Tal que así :

tar -I pigz -c dir1 dir2 dir3 | tee >( md5sum > fichero.tar.gz.md5 ) > fichero.tar.gz

Ojo que al usar tee debemos cambiar la forma en la que invocamos tar. Ya no es posible usar la opción -f para indicar el fichero de salida, si no que se especifica redireccionado la salida estándar.

Al final quedaría el script de backup de esta forma:

#! /bin/bash
DATE=$(date +%Y-%m-%d)
BACKUP_MNT="/media/disco_usb"
BACKUP_TARGET="$BACKUP_MNT/backup/$HOSTNAME"
TAROPS="--absolute-names --atime-preserve -I pigz "

mkdir -p $BACKUP_TARGET/$DATE
BACKUP_TARGET="$BACKUP_TARGET/$DATE"

FILEPREFIX="$BACKUP_TARGET/$DATE-$HOSTNAME"

if [ ! -d "$BACKUP_TARGET" ]; then
        echo "Backup target '$BACKUP_TARGET' does not exit, cannot backup"
        exit 0
fi

tar -c $TAROPS /home | tee >(md5sum > $FILEPREFIX-home.tar.gz.md5) > $FILEPREFIX-home.tar.gz
tar -c $TAROPS /etc  | tee >(md5sum > $FILEPREFIX-etc.tar.gz.md5)  > $FILEPREFIX-etc.tar.gz

¿Cuánto ha mejorado con esto? Mi trabajo tardaba originalmente unos 26 minutos en completarse. Activando la compresión paralela, ha pasado a tardar unos 17. Y activando la suma md5sum con tee, ha pasado a tardar 13.5min .

No está mal bajar a la mitad de tiempo con un par de comandos! ;-)

Backup de dispositivos Fortigate

Aquí va una pequeña guía de cómo hacer backup de la configuración de dispositivos Fortigate. A parte de guardar la última versión de la configuración, aprovechamos para guardarla en un repositorio Subversion que nos permite tanto almacenar configuraciones anteriores como ver diferencias entre ellas.

PARTE 1: Crear el repositorio subversion

Este paso solo se debe realizar una vez. Básicamente es:

backup@rhel6 ~ $ mkdir svnrepo
backup@rhel6 ~ $ svnadmin create file:///home/backup/svnrepo/fortigate
backup@rhel6 ~ $ svn checkout file:///home/backup/svnrepo/fortigate .

Esto generará un repositorio en /home/backup/svnrepo/fortigate y tendremos una copia de trabajo (checkout) en /home/backup/fortigate . Es este segundo directorio donde debemos almacenar los ficheros de configuración.

Parte 2: Crear una llave ssh para autenticación sin password.

(Opcional) Solo es necesario una vez. Esto nos permitirá conectarnos al firewall de forma desatendida. Para ello es necesario:

backup@rhel6 ~ $ ssh-keygen -t dsa

Esto nos generará dos ficheros dentro del directorio \~/.ssh , a saber :

$ ll .ssh/
total 72
-rw-------. 1 backup backup   668 Aug 30  2009 id_dsa
-rw-r--r--. 1 backup backup   601 Aug 30  2009 id_dsa.pub

El fichero id_dsa contiene la clave privada, mientras que el id_dsa.pub contiene la clave pública que debemos llevar a cada uno de los firewalls a los que queramos conectarnos. Para ver la clave pública, simplemente podemos hacer un cat del fichero:

$ cat ~/.ssh/id_dsa.pub
ssh-dss CHURRO backup@rhel6

PARTE 3: Configurar el firewall para permitir conexión con clave pública.

Asumiendo que ya tenemos un usuario llamado "backup" con permisos de administrador sobre el firewall, estos son los pasos a seguir:

$ ssh backup@FORTI-FW01
backup@FORTI-FW01's password:
FORTI-FW01 $ config system global
FORTI-FW01 (global) $ set admin-scp enable
FORTI-FW01 (global) $ end
FORTI-FW01 $ config system admin
FORTI-FW01 (admin) $ edit backup
FORTI-FW01 (backup) $ set ssh-public-key1 "ssh-dss CHURRO backup@rhel6"
FORTI-FW01 (backup) $ next
FORTI-FW01 (admin) $ end
FORTI-FW01 $ exit
Connection to FORTI-FW01 closed.

PARTE 4 : Automatizar el backup

Una vez tenido todo esto, lo único que nos hace falta para automatizar la copia es crear un par de scripts que se conecten a los firewalls y recojan la configuración. Por ejemplo:

backup@rhel6 ~/fortigate $  cat devices.conf
# Add firewalls here
forti-fw01

backup@rhel6 ~/fortigate $ cat getconfigs.sh
#!/bin/bash

export PATH=$PATH:usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin

for i in `grep -v ^\# /home/backup//fortigate/devices.conf `; do
    scp $i:sys_config ~/fortigate/sys_cofig.$i
done

cd ~/fortigate/configs
svn add *.conf *.sh sys_config*
svn commit -m "Autocommit"

Empaquetar software en formato RPM

RPM es un formato de paquete usado por Redhat, Fedora, Mandriva y otras distribuciones para distribuir software. Permite declarar versiones, dependencias de unos paquetes con otros, etc.

En este artículo vamos a ver como empaquetar el software dconf de Dag Wieers en formato RPM para que sea posible instalarlo de forma sencilla y homogénea. He elegido este paquete al ser un software que tiene
pocas dependencias y no es necesario compilar código (es un script Python).

ATENCIÓN: este paquete sólo se debe instalar en RedHat Enterprise Linux 5 ó 6. En versiones recientes de Fedora (p.e.: 17) ya existe un paquete llamado dconf que NO es este. Deberemos cambiar el nombre de nuestro paquete para no conflictar con el que ya provee la distribución.

Lo primero de todo, será bajar el paquete desde su fuente. En este caso, desde un repositorio git albergado en GitHub:

dconf@rhel6 : ~ $ sudo yum install -y git

dconf@rhel6 : ~ $ git clone https://github.com/dagwieers/dconf.git  
Initialized empty Git repository in /home/dconf/dconf/.git/  
remote: Counting objects: 291, done.  
remote: Compressing objects: 100% (105/105), done.  
remote: Total 291 (delta 192), reused 282 (delta 183)  
Receiving objects: 100% (291/291), 97.16 KiB, done.   
Resolving deltas: 100% (192/192), done.

dconf@rhel6 : ~ $ ls -l  
total 4  
drwxr-xr-x. 7 dconf dconf 4096 Jul 14 17:31 dconf

Una vez realizado esto, deberemos bajar las herramientas de RPM para crear paquetes, así como inicializar una serie de directorios que nos servirán para futuras construcciones de paquetes:

dconf@rhel6 : ~ $ sudo yum install -y rpm-build  
dconf@rhel6 : ~ $ mkdir -p ~/rpmbuild/{BUILD,RPMS,SOURCES,SRPMS,SPECS,TMP}  
dconf@rhel6 : ~ $ mkdir -p ~/rpmbuild/RPMS/{x86_64,i386,i586,i686,noarch}

rpmbuild espera encontrar un fichero ".spec" (especificaciones) de cómo construir el paquete. Típicamente se almacenan en ~/rpmbuild/SPECS . Además, según el fichero que proporciona el mantenedor de dstat espera encontrar el código en un directorio llamado "dconf-${version}", y no en "dconf" a secas generado por Git. Para solventar esto :

dconf@rhel6 : ~ $ mv ~/dconf/dconf.spec ~/rpmbuild/SPECS/  
dconf@rhel6 : ~ $ mv dconf dconf-0.6svn  
dconf@rhel6 : ~ $ tar -cjf /home/dconf/rpmbuild/SOURCES/dconf-0.6svn.tar.bz2 dconf  
dconf@rhel6 : ~ $ rpmbuild -bb rpmbuild/SPECS/dconf.spec  
[...]

¡Ya tenemos nuestro RPM generado! Ahora solo nos falta instalarlo y probarlo :

dconf@rhel6 : ~ $ ls -l rpmbuild/RPMS/noarch/  
total 44  
-rw-rw-r--. 1 dconf dconf 43118 Jul 14 17:43 dconf-0.6svn-1.noarch.rpm
dconf@rhel6 : ~ $ sudo rpm -i rpmbuild/RPMS/noarch/dconf-0.6svn-1.noarch.rpm
dconf@rhel6 : ~ $ sudo dconf -o dconf.txt -v  
Reading config file /etc/dconf.conf  
Reading config file /etc/dconf.d/redhat.conf  
Building file: dconf.txt

Finalmente, un poco de información sobre el RPM . Todos estos datos son modificables mediante el fichero .spec original.

dconf@rhel6 : ~ $ rpm -qi dconf  
Name : dconf Relocations: (not relocatable)  
Version : 0.6svn Vendor: (none)  
Release : 1 Build date: Sat 14 Jul 2012 05:43:09 PM CEST  
Install date: Sat 14 Jul 2012 05:44:22 PM CEST Build Host: rhel6  
Group : System Environment/Base Source RPM: dconf-0.6svn-1.src.rpm  
Size : 128551 License: GPL  
Signature : (none)  
URL : http://dag.wieers.com/home-made/dconf/  
Summary : Create a system's hardware and software configuration snapshot  
Description :  
Dconf is a tool to collect a system's hardware and software configuration.  
It allows to take your system configuration with you on the road, compare  
identical systems (like nodes in a cluster) to troubleshoot HW or SW  
problems.

Dconf is also useful in projects where you have to manage changes as a  
team. Dconf can send out system changes to a list of email addressesso  
that they can be revised and discussed in group.

You can customize your dconf configuration for specific needs, likemaking  
a profile of your laptop's hardware or copy specific software configuration  
files to send out or compare with other systems.

Hay un excelente documento con más detalle sobre las distintas posibilidades de rpmbuild en el sitio Linux Para Todos.

Limitaciones prácticas de Vmware VDR

Vmware Data Recovery (VDR) provee un mecanismo flexible para obtener copias PIT (point in time) del estado de nuestras máquinas virtuales. Nos podemos olvidar de instalación de agentes de backup tipo Netbackup, Legato, etc en nuestras máquinas virtuales a la vez que obtenemos una copia completa y consistente de nuestro sistema operativo y datos, pudiendo volver a tener una VM funcional tras una catástrofe en minutos.

Sin embargo, esta flexibilidad muchas veces se convierte en un "todo vale" y en una falta de diseño para obtener una estructura de backup adecuada. Voy a exponer alguna de las limitaciones y/o buenas prácticas que me he ido encontrado a la hora de desplegar este producto:

No es aconsejable hacer backups de VMs de más de 250GB. Backups más grandes de ese tamaño hacen difícil cuadrarlo en una ventana de backup de 8h y no hay forma de tunear el VDR para que haga los backups más rápidos (ni asignando más CPU/vRAM al appliance, ni de ninguna otra forma).

NO hacer backup de VMs muy transaccionales. Es decir, no hacer Backup VDR de máquinas virtuales que tengan muchos cambios durante la ventana de Backup (típicamente Bases de datos). Esto es debido a que los snapshots necesarios pueden ocupar mucho espacio y hacer una estimación de espacio necesario es muy complicado.

Aprovisionar un 20%-30% de espacio adicional en datastore de origen por máquina virtual que requiera VDR. Con relación al punto anterior, y para evitar que un datastore se llene por snapshots durante ventana de VDR, es necesario aprovisionar espacio adicional para que se realicen los backups. Si lo del 30% os parece excesivo os contaré que una máquina de GB con 1 Tera en discos ha llegado a tener 300gb en snapshots no consolidados porque su Backup de VDR seguía en ejecución tras más de 48h :-) .

Almacenar los backups FUERA de la SAN. Esto suena a perogrullo, pero en más de un caso me he encontrado que el appliance VDR reside en la misma cabina que las luns a las que hace backup. Si falla la cabina, nos quedamos sin VMs y sin backups, por lo que no tiene sentido almacenarlos en el mismo sitio. Donde sea posible, es aconsejable almacenar los backups en discos locales de los ESX o en una cabina distinta a las VMs de origen. Por ejemplo, en máquinas HP Proliant se pueden comprar discos SATA de 1 ó 2 Terabytes a precios bastante competitivos en relación a los FC/SAS.

No hacer que todos los backups finalicen a la msima hora. Si tenemos muchos trabajos de backup y hacemos que todos finalicen a la misma hora (ej: lunes a las 08:00), conseguiremos que a esa hora se produzca una "tormenta de consolidación de snapshots". VDR cancela todos sus trabajos e informa al vCenter que consolide todos los snapshots que ha creado para poder hacer copias consistentes de las VMs, por lo que conseguimos que a las 8:00 se produzcan operaciones I/O masivas hacia el almacenamiento. Perfecto para que los usuarios estén felices y contentos por la lentitud de sus VMs :-) .

Dimensionamiento de espacio a asignar: Si queremos hacer backup de VMs que ocupan 1 Terabyte neto, típicamente necesitaremos menos de ese espacio asignado a nuestro VDR: ratios de 2/1 no parecen descabellados. Sin embargo, hay que tener en cuenta el crecimiento de nuestras VMs y cuánta retención queremos para ella. No es lo mismo querer guardar los últimos 30 backups diarios, que guardar los últimos 4 semanales. Siempre hay que tener en cuenta el no asignar más de 2 Terabytes de espacio por appliance VDR, lo que según estos cálculos, nos permitiría proteger hasta 3-4 Terabytes de VMs.

Dimensionamiento de los datastores de VMs: Como comentaba antes, es necesario dejar espacio libre en los datastores que vayan a albergar máquinas protegidas por VDR, típicamente entre un 15-20%, dependiendo de la transaccionalidad de las VMs. Para máquinas muy cambiantes, pueden incluso requerir mucho más, por lo que requiere un análisis cuidadoso. El hecho de quedarse sin espacio libre en un datastore mientras se tienen máquinas virtuales encendidas es muy delicado, ya que puede llegar a provocar corrupción de las VMs y/o pérdida de datos (rollback de los snapshots).

Autenticar Postfix contra un servidor SMTP via SASL

Aquí va una pequeña receta para hacer que tu Postfix local use SASL para autenticarse contra un relay externo. Esto es especialmente útil para usuarios móviles (portátiles, etc) donde tu IP varía y no es viable realizar una autorización en base a IPs estáticas.

Basado en el artículo de Patric Koetter.

Para realizar esto, simplemente es necesario crear un fichero con las credenciales SASL a utilizar, tal que:

# ls -l /etc/postfix/sasl_passwd
-rw-------. 1 root root 55 Nov  3 00:15 /etc/postfix/sasl_passwd
# sudo cat  /etc/postfix/sasl_passwd
relay.example.org       user@loquesea:MiPassword

Y añadir esto al fichero main.cf de postfix :

smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_security_options = noanonymous
smtp_sasl_type = cyrus

Instalar software en RHEL6 desde CD/DVD

Como ya comenté hace tiempo se pueden configurar repositorios de YUM que apuntan al CD original, y en RHEL6 no iba a ser menos.

Aquí va el fichero de configuración, ej /etc/yum.repos.d/localcd.repo :

[RHEL6-CD-SERVER]
name=Red Hat 6 Server
baseurl=file:///mnt/Server
enabled=1
gpgcheck=0

[RHEL6-CD-HA]
name=Red Hat 6 Server HA
baseurl=file:///mnt/HighAvailability
enabled=1
gpgcheck=0

[RHEL6-CD-LB]
name=Red Hat 6 LB
baseurl=file:///mnt/LoadBalancer
enabled=1
gpgcheck=0

[RHEL6-CD-RStor]
name=Red Hat 6 RStor
baseurl=file:///mnt/ResilientStorage
enabled=1
gpgcheck=0

[RHEL6-CD-SFS]
name=Red Hat 6 SFS
baseurl=file:///mnt/ScalableFileSystem
enabled=1 
gpgcheck=0

Configuracion de keepalives de SSH

En el caso de que nos conectemos por ssh a un servidor atravesando un firewall, es muy común que éste tire conexiones válidas porque considera que no ha habido actividad en X tiempo (timeout de conexiones TCP establecidas). Para evitar este problema, podemos forzar a que se envíen paquetes cada pocos minutos y que el firewall considere que es una conexión TCP viva.

Basta con añadir estos parámetros al fichero de configuración sshd_config y reiniciar el servicio SSHD

TCPKeepAlive yes  
ClientAliveInterval 5

Conversión P2V de RHEL en VMware

Cada día es más común realizar la migración de servidores físicos a virtuales (P2V). Aunque existen herramientas específicas para ello, como VMware Converter, muchas veces es más sencillo usar una forma manual que no tener que montar una nueva infrastructura de software para 1 ó 2 migraciones.

En este artículo vamos a ver cómo migrar una instalación de RHEL4 en físico (servidor HP Proliant) a máquina virtual bajo vSphere 4.1. El proceso descrito es similar a una Cold migration, es decir, una mgiración con la máquina de origen apagada (y por tanto, con pérdida de servicio).

Los pasos a realizar serán :

  • Preparar la máquina física de origen con los drivers necesarios de VMware (initrd)
  • Crear de una máquina virtual en VMware
  • Arrancar la máquina virtual con un LiveCD
  • Arrancar la máquina física con un LiveCD
  • Copiar por red cada uno de los discos de la máquina de origen a la máquina virtual
  • Editar ficheros de configuración y ver que la VM arranca correctamente
  • Instalación de VMware Tools

Más en detalle:

Preparación de la máquina de origen

Esta será la única modificación que se realiza en la máquina de origen; consiste en incluir los módulos necesarios para que la máquina pueda arrancar con su futuro hardware virtual. Para ello es necesario editar el fichero /etc/modprobe.conf de la siguiente manera:

#alias eth0 tg3  
#alias eth1 tg3  
alias scsi_hostadapter cciss  
alias scsi_hostadapter1 mptspi  
alias scsi_hostadapter2 mptscsih  
alias scsi_hostadapter3 ata_piix

Se han comentado las líneas 1 y 2 para evitar introducir los módulos de las tarjetas de red en el initrd, así como añadido las lineas 4 y 5 que son los módulos de la controladora SCSI virtual de VMware. Una vez realizado esto se procede a construir un initrd nuevo y a añadirlo en la configuración de GRUB :

root@server /boot # uname -a  
Linux server 2.6.18-92.1.6.el5 #1 SMP Fri Jun 20 02:36:16 EDT 2008 i686 i686 i386 GNU/Linux  
root@server /boot $ mkinitrd initrd-2.6.18-92.1.6.el5-vmware.img 2.6.18-92.1.6.el5  
root@server /boot $ cat /etc/grub.conf  
[...]  
# entrada con nuevo initrd  
title Red Hat Enterprise Linux Server (vmware)  
root (hd0,0)  
kernel /vmlinuz-2.6.18-92.1.6.el5 ro root=/dev/vg00/lvol00 rhgb quiet  
initrd /initrd-2.6.18-92.1.6.el5-vmware.img  
#entrada con initrd original  
title Red Hat Enterprise Linux Server (2.6.18-92.1.6.el5)  
root (hd0,0)  
kernel /vmlinuz-2.6.18-92.1.6.el5 ro root=/dev/vg00/lvol00 rhgb quiet  
initrd /initrd-2.6.18-92.1.6.el5.img

Creación de la máquina virtual

La única consideración a tener en cuenta es crear los discos de, al menos, el mismo tamaño que los discos de la máquina física de origen.

Arranque de las máquinas con un LiveCD

En principio, nos vale cualquier LiveCD que tengamos a mano, pero recomiendo SysRescCD debido a su pequeño tamaño (~250MB), soporte simultáneo de 32 y 64 bits y gran cantidad de utilidades embebidas. Una vez arrancadas ambas máquinas, deberemos asignarles a cada una de ellas una IP temporal y verificar que se vean entre sí (por ejemplo, a través de ping).

Transferencia de datos

Usaremos pv para leer los contenidos del disco y netcat para transferirlos por red. PV es una herramienta muy cuca que te aporta información en tiempo real de tamaño leído, velocidad de transferencia actual, tiempo restante (si se conoce el tamaño total del stream); aunque podríamos usar perfectamente cosas más simples como cat ó dd.

En la máquina virtual de destino: Dejamos escuchando un netcat en un puerto TCP arbitrario que queramos, y redirigimos su salida hacia el disco de destino. Ejemplo:

nc -l -p 5000 > /dev/sda

En el servidor físico de origen: Iniciamos la lectura y la enviamos con netcat hacia la IP y puerto de destino, ejemplo:

pv /dev/cciss/c0d0 | nc ipdestino 5000

Algunas notas sobre este proceso: Si tenemos varios discos de origen, podemos paralelizar el proceso cambiándo de TTY y lanzando simultáneamente varios netcats (cambiando los puertos TCP de destino). En pruebas realizadas, hemos visto velocidades combinadas de hasta 70 MB/s (250 GB/hora) para conexiones Gigabit, aunque depende lógicamente de la red y el hardware origen y destino.

Una vez realizado esto, podremos apagar la máquina física de origen y proceder a verificar el estado de la copia. Deberemos recargar la tabla de particiones en la máquina virtual para que se aplique lo escrito a disco y, si usamos LVM, activar los Volume Groups correspondientes.

# cat /proc/partitions  
major minor #blocks name

8 0 244198584 sda  
# partprobe  
# cat /proc/partitions  
major minor #blocks name

8 0 244198584 sda  
8 1 1024000 sda1  
8 2 243172001 sda2  
# vgchange -ay  
# cat /proc/partitions  
major minor #blocks name

8 0 244198584 sda  
8 1 1024000 sda1  
8 2 243172001 sda2  
253 0 16777216 dm-0  
253 1 7864320 dm-1  
253 2 10485760 dm-2  
253 3 2097152 dm-3  
253 4 4194304 dm-4  
253 5 80740352 dm-5  
253 6 52428800 dm-6  
253 7 27262976 dm-7  
253 8 13631488 dm-8

Además, deberemos revisar la configuración de /etc/fstab para verificar que no haya referencias a dispositivos incorrectos (en Proliant el primer disco del sistema es /dev/cciss/c0d0 mientras que en VMware es /dev/sda). Para ello, deberemos montar el filesystem raid en un directorio temporal (por ejemplo mkdir /test ; mount /dev/sda1 /test) y editar los ficheros necesarios. Además, en RHEL deberemos editar los ficheros /test/etc/sysconfig/network-script/ifcfg-eth* para verificar que no tengan asociada ninguna MAC Address concreta, o bien reemplazar las existentes por las de la nueva VM).

Finalmente, reiniciaremos la máquina virtual y comprobaremos si todo levanta correctamente. Si es así, procederemos a quitar todas las herramientas que dependan de un hardware concreto (por ejemplo Proliant Support Pack en HP, OpenManage en Dell, etc) e instalar las VMware Tools.

Configuración de device-mapper-multipath para almacenamiento HP

Aquí va una pequeña chuleta con las opciones de multipath recomendadas por HP para sus almacenamientos. Esto se debe configurar en /etc/multipathd.conf y reiniciar el demonio correspondiente.

# For EVA A/A arrays

device {
        vendor                  "HP|COMPAQ"
        product                 "HSV1[01]1 (C)COMPAQ|HSV2[01]0|HSV300|HSV4[05]0"
        path_grouping_policy    group_by_prio
        getuid_callout          "/sbin/scsi_id -g -u -s /block/%n"
        path_checker            tur
        path_selector           "round-robin 0"
        prio_callout            "/sbin/mpath_prio_alua /dev/%n"
        rr_weight               uniform
        failback                immediate
        hardware_handler        "0"
        no_path_retry           18
        rr_min_io               100
}

# For HP P2000 family

device {
        vendor                  "HP"
        product                 "P2000 G3 FC|P2000G3 FC/iSCSI"
        path_grouping_policy    group_by_prio
        getuid_callout          "/sbin/scsi_id -g -u -s /block/%n"
        path_checker            tur
        path_selector           "round-robin 0"
        prio_callout            "/sbin/mpath_prio_alua /dev/%n"
        rr_weight               uniform
        failback                immediate
        hardware_handler        "0"
        no_path_retry           18
        rr_min_io               100
}

# For XP arrays

device {
        vendor                  "HP"
        product                 "OPEN-.*"
        path_grouping_policy    multibus
        getuid_callout          "/sbin/scsi_id -g -u -s /block/%n"
        path_selector           "round-robin 0"
        rr_weight               uniform
        path_checker            tur
        hardware_handler        "0"
        failback                immediate
        no_path_retry           18
        rr_min_io               1000
}

# For MSA A/A arrays

device {
        vendor                  "HP"
        product                 "MSA VOLUME*"
        path_grouping_policy    group_by_prio
        getuid_callout          "/sbin/scsi_id -g -u -s /block/%n"
        path_checker            tur
        path_selector           "round-robin 0"
        prio_callout            "/sbin/mpath_prio_alua /dev/%n"
        rr_weight               uniform
        failback                immediate
        hardware_handler        "0"
        no_path_retry           18
        rr_min_io               100
}

# For MSA2xxxsa arrays

device {
        vendor                  "HP"
        product                 "MSA2012sa|MSA2312sa|MSA2324sa"
        path_grouping_policy    group_by_prio
        getuid_callout          "/sbin/hp_scsi_id -g -u -n -s /block/%n"
        path_checker            tur
        path_selector           "round-robin 0"
        prio_callout            "/sbin/mpath_prio_alua %d"
        rr_weight               uniform
        failback                immediate
        hardware_handler        "0"
        no_path_retry           18
        rr_min_io               100
}

# For MSA23xxfc and MSA23xxi arrays

device {
        vendor                  "HP"
        product                 "MSA2312fc|MSA2324fc|MSA2312i|MSA2324i"
        path_grouping_policy    group_by_prio
        getuid_callout          "/sbin/scsi_id -g -u -s /block/%n"
        path_checker            tur
        path_selector           "round-robin 0"
        prio_callout            "/sbin/mpath_prio_alua /dev/%n"
        rr_weight               uniform
        failback                immediate
        hardware_handler        "0"
        no_path_retry           18
        rr_min_io               100
}

# For MSA20xxfc, MSA22xxfc and MSA20xxi arrays

device {
        vendor                  "HP"
        product                 "MSA2[02]12fc|MSA2012i"
        path_grouping_policy    multibus
        getuid_callout          "/sbin/scsi_id -g -u -s /block/%n"
        path_selector           "round-robin 0"
        rr_weight               uniform
        path_checker            tur
        hardware_handler        "0"
        failback                immediate
        no_path_retry           18
        rr_min_io               100
}
# To blacklist a device by vendor and product say, to blacklist a XP device
# uncomment the below block

#device {
#       vendor                  "HP"
#       product_blacklist       "OPEN-.*"
#}