Introduction: Snapshots Con LVM: Úsalos Como Backup Para Revertir Cambios En Tus Filesystems.

Introduccion:

Una característica muy interesante de LVM es que nos permite realizar snapshots de volúmenes lógicos. Estos snapshots pueden ser utilizados para revertir el estado inicial y conocido de un LV. Los snapshots se pueden utilizar a modo de backup.

Un ejemplo podría ser en una máquina crítica, donde se quieren realizar cambios en la configuración o instalar nuevo software, y que no estamos seguros de que vaya a funcionar correctamente. En caso de que los cambios no salgan como esperamos, podremos revertir el estado y el contenido del/los filesystems quedará como estaban antes de realizar el snapshot, de una manera rápida y transparente para el sistema. En caso de que los cambios sean los esperados, es igualmente sencillo dejarlos permanentes y eliminar el snapshot posteriormente.

Es importante mencionar que si el snapshot se queda sin espacio, este será inservible y no podrá ser usado. Simplemente monitorizando su tamaño podremos vigilar el estado de este, y en caso de que se llene, se podría ampliar sin problema, como si de un volumen lógico normal y corriente se tratara.

En el caso práctico que veremos a continuación, usaremos snapshots antes de actualizar una máquina, en la que prevemos que se actualizará el kernel y no estamos seguros de que vaya a funcionar/reiniciar posteriormente.

Step 1: Estado Inicial De La Máquina.

Tenemos un sistema CentOS 6.5, con un kernel 2.6.32-431, 64 bit.

[root@CentOS-65 ~]# cat /etc/redhat-release 
CentOS release 6.5 (Final)
[root@CentOS-65 ~]# uname  -r
2.6.32-431.el6.x86_64

El equipo tiene una volumetría como la que se muestra a continuación:

[root@CentOS-65 ~]# df -ht ext4
Filesystem                     Size  Used Avail Use% Mounted on
/dev/mapper/system_vg-root_lv 1008M  239M  719M  25% /
/dev/sda1                      504M   39M  440M   9% /boot
/dev/mapper/system_vg-home_lv  504M   17M  462M   4% /home
/dev/mapper/system_vg-opt_lv   504M   17M  462M   4% /opt
/dev/mapper/system_vg-tmp_lv   504M   17M  462M   4% /tmp
/dev/mapper/system_vg-usr_lv   2,0G  430M  1,5G  23% /usr
/dev/mapper/system_vg-var_lv   2,0G   88M  1,8G   5% /var
/dev/mapper/system_vg-log_lv  1008M   35M  923M   4% /var/log
[root@CentOS-65 ~]# vgs
  VG        #PV #LV #SN Attr   VSize  VFree 
  system_vg   1   8   0 wz--n- 19,50g 11,00g 
[root@CentOS-65 ~]# pvs
  PV         VG        Fmt  Attr PSize  PFree 
  /dev/sda2  system_vg lvm2 a--  19,50g 11,00g

Vemos mediante el comando "yum" que hay paquetes pendientes de instalación, entre ellos, un nuevo kernel:

[root@CentOS-65 yum.repos.d]# yum check-update | grep -c updates
59
[root@CentOS-65 yum.repos.d]# yum check-update | grep kernel
kernel.x86_64                              2.6.32-431.23.3.el6         updates
kernel-firmware.noarch                     2.6.32-431.23.3.el6         updates

He añadido a la máquina un nuevo disco de 2Gb para realizar los snapshots. He determinado que con 2Gb hay suficiente espacio, ya que los snapshots los realizaremos de los filesystems /var, /usr y / (los que se modificarán durante el upgrade de la máquina). Los snapshots (tres en total) crecerán tanto como los cambios que hagamos en los filesystems a partir del momento de su creación.

Con el comando "lvmdiskscan" vemos los discos que tiene la máquina:

[root@CentOS-65 ~]# lvmdiskscan 
  /dev/sda1 [     512,00 MiB] 
  /dev/sda2 [      19,50 GiB] LVM physical volume
  /dev/sdb  [       2,00 GiB]

El disco sdb aún no está en uso por LVM.

Step 2: Realizando El Snapshot

El primer paso consiste en incluir el nuevo disco en el VG donde están los LV's que queremos realizar el/los snapshots. Para ello, ampliaremos el VG system_vg, con el comando "vgextend":

[root@CentOS-65 ]# vgextend system_vg /dev/sdb
  No physical volume label read from /dev/sdb
  Physical volume /dev/sdb not found
  Physical volume "/dev/sdb" successfully created
  Volume group "system_vg" successfully extended

NOTA: En versiones actuales de LVM, no es necesario crear previamente un PV en el nuevo disco, LVM se encarga automáticamente de etiquetarlo en caso de que no lo esté.

Comprobamos que el VG system_vg contiene el nuevo disco:

[root@CentOS-65 ]# pvs
PV         VG        Fmt  Attr PSize  PFree 
/dev/sda2  system_vg lvm2 a--  19,50g 11,00g
/dev/sdb   system_vg lvm2 a--   2,00g  2,00g

En este momento ya podemos crear los snapshots. La creación es similar a cuando creamos un volúmen lógico, pero especificando que se trata de un snapshot y de qué LV se trata:

lvcreate -s -n NOMBRE_SNAPSHOT -L TAMAÑO_SNAPSHOT TARGET_SNAPSHOT DISCO

Si no especificamos un disco, usará el primero que haya en el VG con algo de espacio. Es preferible especificar el disco donde queremos que se cree el snapshot para tener un mejor rendimiento.

En nuestro caso:

[root@CentOS-65 ]# lvcreate -s -n var_snapshot_lv -L 500M /dev/system_vg/var_lv /dev/sdb 
  Logical volume "var_snapshot_lv" created 
[root@CentOS-65 ]# lvcreate -s -n root_snapshot_lv -L 500M /dev/system_vg/root_lv /dev/sdb 
  Logical volume "root_snapshot_lv" created 
[root@CentOS-65 ~]# lvcreate -s -n usr_snapshot_lv -L 500M /dev/system_vg/usr_lv /dev/sdb 
  Logical volume "usr_snapshot_lv" created

Podemos comprobar que se han creado los snapshots:

[root@CentOS-65 ]# lvs
  LV               VG        Attr       LSize   Pool Origin  Data%
  home_lv          system_vg -wi-ao---- 512,00m
  log_lv           system_vg -wi-ao----   1,00g
  opt_lv           system_vg -wi-ao---- 512,00m
  root_lv          system_vg owi-aos---   1,00g
  root_snapshot_lv system_vg swi-a-s--- 500,00m      root_lv   0,08
  swap_lv          system_vg -wi-ao----   1,00g
  tmp_lv           system_vg -wi-ao---- 512,00m
  usr_lv           system_vg owi-aos---   2,00g
  usr_snapshot_lv  system_vg swi-a-s--- 500,00m      usr_lv    0,00
  var_lv           system_vg owi-aos---   2,00g        
  var_snapshot_lv  system_vg swi-a-s--- 500,00m      var_lv    0,04

NOTA: Añadiendo al comando "lvs" los modificadores "-a -o+devices", podemos ver más información al respecto de los nuevos LV's.

A partir de ahora, todos las las modificaciones que se realicen el los filesystems /var, /usr y /, se guardarán en los nuevos LV's snapshots (root_snapshot_lv, usr_snapshot_lv y var_snapshot_lv), pero los datos antiguos seguirán en los LV's de origen (root_lv, var_lv y usr_lv).

Procedemos a actualizar el sistema:

[root@CentOS-65 ~]# yum update

Una vez actualizado, podemos observar como el tamaño de los LV's de snapshot han aumentado:

[root@CentOS-65 ~]# lvs
  LV               VG        Attr       LSize   Pool Origin  Data%
  home_lv          system_vg -wi-ao---- 512,00m
  log_lv           system_vg -wi-ao----   1,00g
  opt_lv           system_vg -wi-ao---- 512,00m
  root_lv          system_vg owi-aos---   1,00g
  root_snapshot_lv system_vg swi-a-s--- 500,00m      root_lv  36,14
  swap_lv          system_vg -wi-ao----   1,00g
  tmp_lv           system_vg -wi-ao---- 512,00m
  usr_lv           system_vg owi-aos---   2,00g
  usr_snapshot_lv  system_vg swi-a-s--- 500,00m      usr_lv   76,26
  var_lv           system_vg owi-aos---   2,00g
  var_snapshot_lv  system_vg swi-a-s--- 500,00m      var_lv   27,19

En este momento, podemos reiniciar la máquina para ver si arranca correctamente con el nuevo kernel.

[root@CentOS-65 ~]# uname -r
2.6.32-431.23.3.el6.x86_64 
[root@CentOS-65 ~]# rpm -qa | grep kernel
kernel-2.6.32-431.el6.x86_64
kernel-2.6.32-431.23.3.el6.x86_64
kernel-firmware-2.6.32-431.23.3.el6.noarch

Step 3: Realizando Marcha Atrás Para Revertir Las Modificaciones.

Si los cambios que hemos realizado no han surtido el efecto deseado y queremos volver al estado estable inicial, usaremos el comando "lvconvert":

[root@CentOS-65 ~]# lvconvert --merge /dev/system_vg/root_snapshot_lv
  Can't merge over open origin volume
  Merging of snapshot root_snapshot_lv will start next activation. 
[root@CentOS-65 ~]# lvconvert --merge /dev/system_vg/usr_snapshot_lv 
  Can't merge over open origin volume
  Merging of snapshot usr_snapshot_lv will start next activation. 
[root@CentOS-65 ~]# lvconvert --merge /dev/system_vg/var_snapshot_lv 
  Can't merge over open origin volume
  Merging of snapshot var_snapshot_lv will start next activation.

El mensaje de error que aparece, es porque el filesystem está montado. Al ser filesystems de sistema, no se pueden desmontar porque están en uso, pero no hay problema, simplemente reiniciamos la máquina y al volver a arrancar, el merge surtirá efecto.

NOTA: En este ejemplo concreto, durante la actualización e instalación de un nuevo kernel, se modifica el contenido de "/boot/grub/menu.lst", y se añade una nueva línea de arranque de kernel. Dado que para /boot no hemos realizado un snapshot al no estar gestionado desde LVM, es necesario comentar/eliminar manualmente dicha linea para revertir ese cambio concreto.

Podemos ir viendo con el comando "lvs", el % contenidos en la columna "Data%". Vemos que va bajando según se realiza el merge:

[root@CentOS-65 ~]# lvs -a
  LV                 VG        Attr       LSize   Pool Origin  Data%       
  [root_snapshot_lv] system_vg Swi-a-s--- 500,00m      root_lv   2,21
  [usr_snapshot_lv]  system_vg Swi-a-s--- 500,00m      usr_lv   61,57
  [var_snapshot_lv]  system_vg Swi-a-s--- 500,00m      var_lv    0,44<br>
[root@CentOS-65 ~]# lvs -a 
  LV                 VG        Attr       LSize   Pool Origin  Data%             
  [root_snapshot_lv] system_vg Swi-a-s--- 500,00m      root_lv   1,96
  [usr_snapshot_lv]  system_vg Swi-a-s--- 500,00m      usr_lv   61,44
  [var_snapshot_lv]  system_vg Swi-a-s--- 500,00m      var_lv    0,38
[root@CentOS-65 ~]# lvs -a 
  LV                 VG        Attr       LSize   Pool Origin  Data%             
  [root_snapshot_lv] system_vg Swi-a-s--- 500,00m      root_lv   1,77
  [usr_snapshot_lv]  system_vg Swi-a-s--- 500,00m      usr_lv   61,36
  [var_snapshot_lv]  system_vg Swi-a-s--- 500,00m      var_lv    0,20

Una vez que termine de mover los datos, veremos que volvemos a tener el estado inicial de la máquina:

[root@CentOS-65 ~]# lvs
  LV      VG        Attr       LSize   Pool Origin Data%
  home_lv system_vg -wi-ao---- 512,00m
  log_lv  system_vg -wi-ao----   1,00g
  opt_lv  system_vg -wi-ao---- 512,00m
  root_lv system_vg -wi-ao----   1,00g
  swap_lv system_vg -wi-ao----   1,00g
  tmp_lv  system_vg -wi-ao---- 512,00m
  usr_lv  system_vg -wi-ao----   2,00g
  var_lv  system_vg -wi-ao----   2,00g
[root@CentOS-65 ~]# rpm -qa | grep kernel
dracut-kernel-004-335.el6.noarch
kernel-2.6.32-431.el6.x86_64
kernel-firmware-2.6.32-431.el6.noarch
[root@CentOS-65 ~]# yum check-update | grep -c updates
59 
[root@CentOS-65 ~]# yum check-update | grep kernel
kernel.x86_64                              2.6.32-431.23.3.el6        updates
kernel-firmware.noarch                     2.6.32-431.23.3.el6        updates

Vemos que volvemos a tener 59 paquetes pendientes de actualizar.

Step 4: Borrando Snapshots. Los Cambios Han Surtido El Efecto Deseado.

Si la actualización se ha llevado a cabo con exito y todo funciona correctamente, podemos proceder a eliminar los snapshots. Para ello usaremos el comando "lvremove", tal como si de un volúmen lógico normal y corriente se tratara.

[root@CentOS-65 ~]# lvremove /dev/system_vg/root_snapshot_lv
[root@CentOS-65 ~]# lvremove /dev/system_vg/usr_snapshot_lv
[root@CentOS-65 ~]# lvremove /dev/system_vg/var_snapshot_lv

En este momento, podemos retirar del VG el disco de 2Gb que habíamos usado para realizar los snapshots.

[root@CentOS-65 ~]# vgreduce system_vg /dev/sdb