sábado, 30 de junio de 2012

Linux/KVM: Growing filesystem on a LVM based virtual disk.

Cuando se utiliza virtualización, las capacidades de flexibilización del storage son enormes, es por ello existen diferentes formas de manejar el almacenamiento utilizando KVM como hypervisor.
Una de ellas es utilizar filedisks, con los cuales, cada uno de ellos emula un disco físico en la VM y los filesystems son armados ahí mismo.
Otra forma es mediante LVM dedicando uno o varios LV a uso exclusivo de la VM.
Esta última forma, optimiza el I/O debido a que se evita pasar por una capa intermedia de abstracción: "un archivo", a fin de escribir los bloques de datos a disco. De esta manera las operaciones de I/O son manejadas directamente por el Device Mapper (LVM), y se evita caer en capas de abstracción intermediarias.
Este caso era sencillo, un servidor de correos en CentOS 5.6, bajo "Zimbra", el cual tiene un disco basado en un LV (vdb1), que monta en /opt, directorio utilizado por Zimbra para mantener todos sus datos, el cual se había quedado sin espacio.

Los pasos a seguir son sencillos:
  • Extender el LV
  • Editar la tabla de particiones de la VM
  • Extender el filesystem
Siguiendo este orden de pasos, haremos el primero de ellos, extender el LV en el cual se encuentra el disco /dev/vdb1 de la VM, en este caso, existe un Volume Group dedicado llamado "vg_virt", el cual contiene todos los discos utilizado por las distintas VM's instaladas en el hypervisor. Lo primero que haremos es comprobar que exista espacio disponible en el VG:
[root@kvm ~]# vgs
  VG          #PV #LV #SN Attr   VSize   VFree  
  Vg_root      1   2   0 wz--n- 279.25G 183.62G
  vg_virt      1   1   0 wz--n- 558.88G 362.39G
Como podemos observar, dentro de vg_virt, aún tenemos disponibles 362.39 Gb. Por lo cual nuestro resize es factible, ya que incrementaremos el LV "vm_zimbra_data" en 100 Gb.
[root@kvm ~]# lvextend -L +100G /dev/vg_virt/vm_zimbra_data
Una vez hecho esto si volvemos, podemos comprobar que nuestro LV se extendió correctamente ejecutando lvdisplay
[root@kvm ~]# lvdisplay /dev/vg_virt/vm_zimbra_data
  --- Logical volume ---
  LV Name                /dev/vg_virt/vm_zimbra_data
  VG Name                vgvm
  LV UUID                esmp7E-sC4u-wbPK-Qqf4-58wA-BVOG-F8xdmh
  LV Write Access        read/write
  LV Status              available
  # open                 1
  LV Size                296.48 GB
  Current LE             75900
  Segments               1
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     256
  Block device           253:2
Este volumen que originalmente era de 196.48 Gb. Ahora se incremento en 100, dando un total de 296 Gb. Por lo cual el mismo se extendió sin problemas. Con el objetivo de que la VM, vea el nuevo tamaño del VG, es fundamental apagarla y volver a encenderla, por lo cual desde el hypervisor ejecutamos:
[root@kvm ~]# virsh shutdown zimbra && virsh start zimbra
Una vez booteada la VM, nos logueamos en ella (mediante virsh console o SSH). Y procederemos a editar la tabla de particiones. Para ello como primera medida pararemos el servicio de Zimbra, desmontaremos la partición y comenzaremos a trabajar finamente en ella:
[root@zimbra ~]# service zimbra stop
Host zimbra.foobar.net
        Stopping stats...Done.
        Stopping mta...Done.
        Stopping spell...Done.
        Stopping snmp...Done.
        Stopping cbpolicyd...Done.
        Stopping archiving...Done.
        Stopping antivirus...Done.
        Stopping antispam...Done.
        Stopping imapproxy...Done.
        Stopping memcached...Done.
        Stopping mailbox...Done.
        Stopping logger...Done.
        Stopping zmconfigd...Done.
        Stopping ldap...Done.
[root@zimbra ~]# umount /dev/vdb1
Ahora, utilizando fdisk, cambiaremos la geometría de nuestro disco /dev/vdb,
[root@zimbra ~]# fdisk /dev/vdb
Command (m for help): p

Disk /dev/vdb: 318.3 GB, 318347673600 bytes
16 heads, 63 sectors/track, 616838 cylinders
Units = cylinders of 1008 * 512 = 516096 bytes

   Device Boot      Start         End      Blocks   Id  System
/dev/vdb1               1      408787   206028616+  83  Linux
Podemos observar a simple vista que la partición /dev/vdb1 comienza en el cilindro número 1 y termina en el cilindro número 408787, si prestamos aún más atención podemos notar que el disco /dev/vdb, tiene 616838 cilindros, por lo cual tenemos algunos cilindros libres todavía a ser utilizados. Lo que debemos hacer es borrar la partición /dev/vdb1, y volver a crearla a con la única diferencia de que el último cilindro sea 616838 en lugar de 408787.
Entonces ahora elimnaremos la partición número 1 (/dev/vdb1):
Command (m for help): d
Selected partition 1
Comprobamos que se haya eliminado de manera correcta
Command (m for help): p

Disk /dev/vdb: 318.3 GB, 318347673600 bytes
16 heads, 63 sectors/track, 616838 cylinders
Units = cylinders of 1008 * 512 = 516096 bytes

   Device Boot      Start         End      Blocks   Id  System
Y crearemos una nueva partición del tipo primaria con el comando de fdsik "n":
Command (m for help): n
Command action
   e   extended
   p   primary partition (1-4)
Indicamos el número de partición (1 en este caso), e indicamos la nueva geometría. El primer cilindro será nuevamente el número 1, y el último será el 616838.
Partition number (1-4): 1
First cylinder (1-616838, default 1):
Using default value 1
Last cylinder or +size or +sizeM or +sizeK (1-616838, default 616838):
Using default value 616838
Una vez definido esto escribimos los cambios a la tabla de particiones con el comando "w":
Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.
La tercera parte consiste en resizear el tamaño de nuestro disco virtual. Lo primero que haremos es ejecutar un fsck sobre el disco a fin de comprobar que no existan errores, si bien esto se puede forzar y omitirse, cuando son cambios críticos como en este caso, esto no es recomendable hacerlo:
[root@zimbra /]# e2fsck -f /dev/vdb1
e2fsck 1.39 (29-May-2006)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/vdb1: 991032/25755648 files (41.6% non-contiguous), 47036062/51507154 blocks
Ahora haremos el resize2fs, sobre la nueva partición, usaremos el flag -p a fin de imprimir cada una de las etapas de resize2fs y conocer que está haciendo:
[root@zimbra /]# resize2fs -p /dev/vdb1
resize2fs 1.39 (29-May-2006)
Resizing the filesystem on /dev/vdb1 to 77721580 (4k) blocks.
Begin pass 1 (max = 800)
Extending the inode table     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
The filesystem on /dev/vdb1 is now 77721580 blocks long.
Listo, ahora montaremos nuevamente /dev/vdb1, y comprobaremos que se haya expandido de manera correcta:
[root@zimbra /]# mount /dev/vdb1

[root@zimbra ~]# df -h
Filesystem             Size  Used Avail Use% Mounted on
/dev/mapper/vg00-lvroot 7.7G  4.1G  3.3G  56% /
/dev/vda1                99M   13M   82M  14% /boot
tmpfs                   3.9G     0  3.9G   0% /dev/shm
/dev/vdb1               292G  177G  107G  63% /opt
E iniciamos el servicio Zimbra nuevamente:
[root@zimbra ~]# service zimbra start
Host zimbra.foobar.net
        Starting zmconfigd...Done.
        Starting ldap...Done.
        Starting mailbox...Done.
        Starting mta...Done.
        Starting antispam...Done.
        Starting cbpolicyd...Done.
        Starting archiving...Done.
        Starting antivirus...Done.
        Starting snmp...Done.
        Starting imapproxy...Done.
        Starting memcached...Done.
        Starting logger...Done.
        Starting stats...Done.
        Starting spell...Done.
¿Por que no un online resize?
Una de las posibilidades de resize2fs es la de hacer online resize, siempre que incrementemos el tamaño de un filesystem, y así evitar desmontarlo realizando la acción con un downtime mínimo.
Como en este caso había que hacerlo sobre un servidor productivo, y más aún un servidor de mail, el cual, esta continuamente escribiendo a disco, esto significa reescribir metadata continuamente y poner en riesgo la consistencia del filesystem. Más aún, aprovechando que obligadamente hay que bajar el servicio Zimbra, no es mala idea también desmontar el filesystem.

Hace unos días, realizando una acción muy similar a esta, me vi afectado por un bug de resize2fs (Bug 525100 - resize2fs online resize hangs), que esta presente en algunas versiones de RHEL y CentOS.
Realizando un online resize, resize2fs se cuelga, tardando horas. Monitoreando la actividad de disco no se ve nada. Por lo cual, no queda mucho más que rebootear el equipo. Esto puede ser realmente peligroso respecto a la consistencia de datos en la partición afectada. Por lo cual, siendo un equipo productivo, prefiero no correr riegos :-)

3 comentarios:

  1. Todavía espero el script para poder configurar mi modem huawei chabón, media pila.

    Si mañana andas por la eko te invito una birra.

    ResponderEliminar
    Respuestas
    1. Bueno dale!, pero ni idea como era para hacerlo, ja cambie de ISP.

      Saludos!.

      Eliminar
  2. It was very nice article and it is very useful to Linux learners.We also provide Linux online training

    ResponderEliminar