Migrating virtual machines to Amazon

When you want to migrate virtuale machines to Amazon, you cannot just use ec2-import-instance for small or medium instances. You'll get the following error:

Status Code: 400, AWS Service: AmazonEC2, AWS Request ID: 394adc25-fef7-4b07-934c-ca579f013e04, AWS Error Code: Unsupported, AWS Error Message: Platform type Linux is incompatible with partition type Linux. Please choose appropriate platform (Example: -p Linux  or -p Windows) Please refer to EC2 User Guide (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instances_of_your_vm.html) for supported operating system versions  

This is because of the difference in virtualisation technique used for small, medium and larger instances.

Together with Prateek Gera we've found a way to easily migrate kvm instances to Amazon (xen), but this technique could be used for migrating all types of VMs.

  • create an instance which we will be using to manage the volumes, lets call that one INSTANCE1.

  • download the volumes from our SAN storage to an volume on an Amazon instance. We are doing this secure by SSH, and gzipped to save bandwidth and time.

dd if=/dev/disk/by-path/ip-10.11.58.10\:3260-iscsi-iqn.2001-05.com.equallogic\:0-8a0906-10c8d0408-75e25ae43c74f390-volume-lun-0 bs=32M| gzip | ssh root@{{INSTANCE1}}.eu-west-1.compute.amazonaws.com dd of=/data/volume.gz bs=32M  

The bs parameter defines the block size, 32M will be fine. The output will be piped through gzip, tunneled through ssh and written to /data/volume.gz

  • create an volume from the drive by unzipping the volume and running ec2-import-volume.
gunzip -c /data/volume.gz > /data/volume.raw

./ec2-import-volume /data/volume.raw -O {{ACCESS_KEY}} -W {{SECRET_KEY}} -f RAW -b {{BUCKET}} -z eu-west-1a  -U https://eu-west-1.ec2.amazonaws.com --debug

The -b means the bucket name, -z the availability zone, -U is the endpoint for the region.

  • if the volume has been imported, you can mount the volume using:
losetup /dev/loop0 /data/volume  
kpartx -l  
kpartx -al /dev/loop0  
mount /dev/mapper/loop0p1 /mnt/dest  
cd /mnt/dest  

These commands will mount the volume using the loopback device. kpartx is used to create mappings for all partitions

  • create a new Linux virtual machine with the same kernel and linux version. We will call this instance INSTANCE2. For Ubuntu you can find them at: http://cloud-images.ubuntu.com/locator/ec2/. We are using in this case ami-09bea87d (Ubuntu 11.10).

  • stop INSTANCE2, detach the volume and attach this volume (the root) to INSTANCE1. Mount the volume to /mnt/dest.

mkdir /mnt/dest  
mount /dev/sdb1 /mnt/dest  
  • attach the volume you imported and mount it to /mnt/src.
mkdir /mnt/src  
mount /dev/sdc1 /mnt/src  
  • copy all files of the filesystem from /mnt/src to /mnt/dest, except for the boot and dev folders.
for a in bin etc lib sbin usr var; do cp -a /mnt/src/$a /mnt/dest/; done;  
  • detach the destination volume and attach (/dev/sda1) it back to the created VM INSTANCE2.

  • now you can start INSTANCE2.


References

http://cloud-images.ubuntu.com/locator/ec2/
http://docs.aws.amazon.com/AWSEC2/latest/CommandLineReference/ApiReference-cmd-ImportVolume.html