Category Archives: rsync

Migrating CentOS from VirtualBox (LVM) to a cloud server (without LVM)

Hi squirrels,

Recently we were faced with the requirement of moving a number of CentOS servers partitioned with LVM to the cloud. There are a lot of tutorials and documentation on the internet on how to do this but we found most of them to not be working or not really applying to our case.

For example, there were a few articles discussing using dd backups to do a block by block transfer of the server over the internet. This seemed reasonable but unfortunately some cloud providers VPS’ do not have LVM partitioned disks and others that do, do not allow attaching multiple drives at the same time (unlike EBS volumes at AWS).

So to summarize, here’s the lsblk output from both servers – both servers were running CentOS, ServerA was running 6.8 but the cloud server was running 6.7.

ServerA = source server, partitioned with LVM
ServerB = target server, no LVM

# this is from serverA - the source server
# note the LVM partitions
lsblk
NAME                         MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sr0                           11:0    1 1024M  0 rom  
sda                            8:0    0    8G  0 disk 
├─sda1                         8:1    0  500M  0 part /boot
└─sda2                         8:2    0  7.5G  0 part 
  ├─vg_centos-lv_root (dm-0) 253:0    0  6.7G  0 lvm  /
  └─vg_centos-lv_swap (dm-1) 253:1    0  816M  0 lvm  [SWAP]
# this is from ServerB - the destination server
# note that there are no LVM partitions
lsblk
NAME   MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda      8:0    0  80G  0 disk 
└─sda1   8:1    0  80G  0 part /

As you can see you cannot use dd for the above unless you are also ready to export and import the partition table over as well. This cannot be done without booting from rescue media or a secondary disk as dd will nuke your target filesystem in the process.

Enter rsync.

It looks like this was previously done with rsync by the nice guys over at ArchLinux: https://wiki.archlinux.org/index.php/full_system_backup_with_rsync

Unfortunately the instructions there didn’t quite work for us for CentOS since that example is talking about Grub2, but CentOS 6.x is still on legacy grub.

Here’s how we did it:

1. Save ServerB’s (target) /etc/grub.cfg and /etc/fstab:

ServerB’s /etc/grub.cfg:

# grub.conf generated by anaconda
#
# Note that you do not have to rerun grub after making changes to this file
# NOTICE:  You do not have a /boot partition.  This means that
#          all kernel and initrd paths are relative to /, eg.
#          root (hd0,0)
#          kernel /boot/vmlinuz-version ro root=/dev/sda1
#          initrd /boot/initrd-[generic-]version.img
#boot=/dev/sda
default=0
timeout=5
splashimage=(hd0,0)/boot/grub/splash.xpm.gz
hiddenmenu
title CentOS (2.6.32-573.18.1.el6.x86_64)
	root (hd0,0)
	kernel /boot/vmlinuz-2.6.32-573.18.1.el6.x86_64 ro root=UUID=ca3c1585-34a7-4280-b18f-dcd5f61831b0 rd_NO_LUKS rd_NO_LVM LANG=en_US.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=auto  KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM console=ttyS0 console=tty0
	initrd /boot/initramfs-2.6.32-573.18.1.el6.x86_64.img

ServerB’s /etc/fstab:

#
# /etc/fstab
# Created by anaconda on Wed Jun  3 03:44:43 2015
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
UUID=ca3c1585-34a7-4280-b18f-dcd5f61831b0 /                       ext4    defaults,noatime        1 1
tmpfs                   /dev/shm                tmpfs   defaults        0 0
devpts                  /dev/pts                devpts  gid=5,mode=620  0 0
sysfs                   /sys                    sysfs   defaults        0 0
proc                    /proc                   proc    defaults        0 0

2. Prepare rsync (skip if you are using password authentication for SSH)

Add your ssh key to ~/.ssh/config. There’s other ways to do this as well but this is the easiest one to tell rsync to use a private key.

Host 222.222.222.222 # replace with ServerB's (target server) IP
	User root    # your SSH username for ServerB
	IdentityFile /root/id_rsa # your SSH private key

3. Prepare rsync on the target (remember: rsync needs to be installed on both the source and target)

yum -y install rsync

NOTE: if you are getting the error:

bash: rsync: command not found
rsync: connection unexpectedly closed (0 bytes received so far) [sender]
rsync error: remote command not found (code 127) at io.c(600) [sender=3.0.6]

this means that rsync is not installed on the REMOTE side.

4. rsync across

time /usr/bin/rsync -aHAXv --delete-after --exclude={"/dev/*","/proc/*","/sys/*","/tmp/*","/run/*","/mnt/*","/media/*","/lost+found","/etc/sysconfig/network-scripts/*"} / root@222.222.222.222:/

why are we excluding the above directories?

/dev – special or device files – we want to keep the ORIGINAL ones, do not overwrite those
/proc – a process information pseudo-file system
/sys – hardware hierarchy
/tmp – temporary files
/run – udev runtime data
/mnt – generic mount point
/media – generic mount point for removable media
/lost+found – recovered corrupt files
/etc/sysconfig/network-scripts/ – we want to keep the original networking configuration since we are migrating to the cloud

5. “Fix” /etc/fstab on the target

I quoted “fix” because in this case the “fix” is to simply reuse your old /etc/fstab with a single but important change:

#
# /etc/fstab
# Created by anaconda on Wed Jun  3 03:44:43 2015
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
# the next line is the only one we changed
/dev/sda1	 	/                       ext4    defaults,noatime        1 1
tmpfs                   /dev/shm                tmpfs   defaults        0 0
devpts                  /dev/pts                devpts  gid=5,mode=620  0 0
sysfs                   /sys                    sysfs   defaults        0 0
proc                    /proc                   proc    defaults        0 0

Note how the line: UUID=ca3c1585-34a7-4280-b18f-dcd5f61831b0 / ext4 is gone? it’s replaced with /dev/sda1 / ext4 defaults,noatime 1 1

6. Fix /etc/grub.conf

For the new /etc/grub.conf we need:

* ServerA’s (source) /etc/grub.conf – this has been copied over by rsync
* ServerB’s (targets) paths – in this case this means to prefix everything with /boot

Result:

default=0
timeout=5
splashimage=(hd0,0)/boot/grub/splash.xpm.gz
hiddenmenu
title CentOS 6 (2.6.32-642.el6.x86_64)
root (hd0,0)
kernel /boot/vmlinuz-2.6.32-642.el6.x86_64 ro root=UUID=ca3c1585-34a7-4280-b18f-dcd5f61831b0 rd_NO_LUKS rd_NO_LVM LANG=en_US.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=auto KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM console=ttyS0 console=tty0
initrd /boot/initramfs-2.6.32-642.el6.x86_64.img

7. One last touch – re-install Grub.

If you used the same rsync command as I did above, you’ll notice that /boot was not excluded. This means that ServerB has ServerA’s stage1 and stage2. Note that those are DIFFERENT than /etc/grub.conf.

To re-install grub, go to ServerB (target) and do the following:

Start grub:

grub

Re-install the stage1 and stage2 to (hd0) – that’s the grub notation for the first physical disk. Replace as needed if you have more than one disks.

setup (hd0)

This is the output we got:

setup (hd0)
Checking if "/boot/grub/stage1" exists... yes
Checking if "/boot/grub/stage2" exists... yes
Checking if "/boot/grub/e2fs_stage1_5" exists... yes
Running "embed /boot/grub/e2fs_stage1_5 (hd0)"... 27 sectors are embedded.
succeeded
Running "install /boot/grub/stage1 (hd0) (hd0)1+27 p (hd0,0)/boot/grub/stage2 /boot/grub/grub.conf"... succeeded
Done.

Exit grub:

quit

You should now be ready to go!

Sources: