In our previous posts on “Building an on-premise private cloud”, we took our first steps by Installing Eucalyptus, a IaaS offering and then dove into Configuring Eucalyptus to look like an Amazon EC2 cloud.

In this post, we will take the next step and that is uploading (to Walrus) and registering a machine image (EMI) with Eucalyptus. Once we have registered the image, we can then run instances of this image using either Amazon EC2 API or Euca2ools.



Eucalyptus Machine Image

A machine image, or more specifically, a Eucalyptus Machine Image (EMI) is a template, stored in Walrus, that can be used to create and run instances. A EMI is a combination of:

  • a kernel image,
  • a ramdisk image, and
  • one or more virtual hard disk image

The kernel image is more specifically referred to as Eucalyptus Kernel Image (EKI) and the ramdisk image is referred to as Eucalyptus Ramdisk Image (ERI).

Each of the images – EKI, ERI, and EMI – have associated xml files containing meta-data about the corresponding images respectively.

The EKIs, ERIs, and EMIs are stored in Walrus and can be referenced by a identifier, Image ID.

Now that we have some background information on EMI’s, let’s get started.




Download Eucalyptus Certified Image

Start by opening a browser and connecting to https://<front-end-ip-address>:8443. In my case, the front-end is 192.168.0.114 (see this post).

Log in with your admin user and password.

Next, click on the Extras tab. And download one of the “Eucalyptus-certified Images”. I picked the CentOS 5.3 i386 image (euca-centos-5.3-i386.tar.gz). I downloaded it on my front-end machine for now.

For the rest of this document, I’ll be referring to the CentOS 5.3 i386 image. Feel free to replace this with the image you downloaded as you proceed through this post.

Once you un-tar the file, you should see a directory structure similar to the following:

-rw-r–r– 1 root root 1001M Apr 23 2009 centos.5-3.x86.img
drwxr-xr-x 2 root root 4.0K Oct 18 2009 kvm-kernel
drwxr-xr-x 2 root root 4.0K Oct 19 2009 xen-kernel
drwxr-xr-x 3 root root 4.0K May 5 14:16 ..
drwxr-xr-x 6 root root 4.0K May 5 14:18 .

where in my case,
centos.5-3.x86.img – is the root disk image
kvm-kernel – directory containing kvm-based kernel and ramdisk (vmlinuz-2.6.28-11-server and initrd.img-2.6.28-11-server)
xen-kernel – directory containing xen-based kernel and ramdisk (vmlinuz-2.6.24-19-xen and initrd.img-2.6.24-19-xen)

Now we can bundle the kernel, ramdisk, and hard disk image, upload it to walrus and register each of them respectively. But before we do this, I’m going to take a small detour.




Detour: Resizing the disk image

Notice in the directory listing of euca-centos-5.3-i386, the size of the centos.5-3.x86.img is only 1 GB. If you bundle, upload and register an EMI out of this image, your instance will have only a 1 GB root partition. Which is fairly small if you plan on installing software on a running instance. For instance, if you try to install Sun Java on it, the installation will fail due to lack of space.

Hence this is a good time to increase the size from 1GB to say, 4GB.

Note: Feel free to skip this step and proceed with the bundling, uploading, and registering of the images.

To re-size the image, let’s start by creating a clean image file, new_centos.5-3.x86.img of size 4GB. We can do this using the dd command.

dd if=/dev/zero of=new_centos.5-3.x86.img bs=1M count-4096

where,
if – source. In this case, we are reading a stream of zeroes from (/dev/zero) device.
of – target. Our new image file (new_centos.5-3.x86.img). The stream of zeroes are copied to this file.
bs – read and write in blocks of 1M
count – copy 4GB of blocks

The above command may take a few minutes to complete. You see output similar to this when done:

4096+0 records in
4096+0 records out
4294967296 bytes (4.3 GB) copied, 191.632 seconds, 22.4 MB/s

Next, associate loop devices with each of the original (centos.5-3.x86.img) and new (new_centos.5-3.x86.img) image files. Make sure that the loop devices that you are going to use are free. You can check the next available loop device using the losetup -f command. In my case, I have /dev/loop1 and /dev/loop2 available.

losetup /dev/loop1 centos.5-3.x86.img
losetup /dev/loop2 new_centos.5-3.x86.img

Confirm the status of the loop devices

losetup /dev/loop1
losetup /dev/loop2
/dev/loop1: [0803]:8585221 (centos.5-3.x86.img)
/dev/loop2: [0803]:8585223 (new_centos.5-3.x86.img)

Next, create a ext3 file system on the new image (in our case, associated with loop device /dev/loop2) as follows:

mke2fs -j /dev/loop2
mke2fs 1.39 (29-May-2006)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
524288 inodes, 1048576 blocks
52428 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=1073741824
32 block groups
32768 blocks per group, 32768 fragments per group
16384 inodes per group
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736

Writing inode tables: done
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done

This filesystem will be automatically checked every 21 mounts or
180 days, whichever comes first. Use tune2fs -c or -i to override.

Let’s create a couple of directories that will serve as temporary mount points for our image files. And then mount the images onto those temporary directories

mkdir orig
mkdir new

mount /dev/loop1 orig
mount /dev/loop2 new

Check the list of mounts by running the mount command without any arguments. You should see the above mount points in the listing. Something similar to the following:

/dev/loop1 on /root/.euca/vmImages/euca-centos-5.3-i386/orig type ext3 (rw)
/dev/loop2 on /root/.euca/vmImages/euca-centos-5.3-i386/new type ext3 (rw)

Also, you can list the contents of the orig (original image) directory. You should see an entire linux file system.

total 96K
drwxr-xr-x 2 root root 4.0K Mar 9 2009 sys
drwxr-xr-x 2 root root 4.0K Mar 9 2009 srv
drwxr-xr-x 2 root root 4.0K Mar 9 2009 selinux
drwxr-xr-x 2 root root 4.0K Mar 9 2009 opt
drwxr-xr-x 2 root root 4.0K Mar 9 2009 mnt
drwxr-xr-x 2 root root 4.0K Mar 9 2009 media
drwxr-xr-x 2 root root 4.0K Mar 9 2009 home
drwx—— 2 root root 16K Apr 23 2009 lost+found
drwxr-xr-x 2 root root 4.0K Apr 23 2009 proc
drwxr-xr-x 17 root root 4.0K Apr 23 2009 var
drwxr-xr-x 13 root root 4.0K Apr 23 2009 usr
drwxr-xr-x 2 root root 4.0K Apr 23 2009 bin
drwxr-xr-x 2 root root 4.0K Apr 23 2009 sbin
drwxr-xr-x 8 root root 4.0K Apr 23 2009 lib
drwxr-xr-x 3 root root 4.0K Apr 23 2009 boot
drwxr-xr-x 2 root root 4.0K Apr 23 2009 dev
-rw-r–r– 1 root root 0 Apr 23 2009 halt
drwxr-xr-x 21 root root 4.0K Apr 23 2009 .
drwxr-x— 2 root root 4.0K Apr 23 2009 root
drwxrwxrwt 3 root root 4.0K Apr 23 2009 tmp
drwxr-xr-x 38 root root 4.0K Oct 18 2009 etc
drwxr-xr-x 6 root root 4.0K Jun 9 09:34 ..

We can now copy the contents of the original (centos.5-3.x86.img) image to the new image new_centos.5-3.x86.img) as follows:

(cd old; tar zcf - .) | (cd new; tar zxf -)

The above command will take a few minutes to complete. Once it is done you can list the contents of the new (new image) directory to confirm the copy worked ok.

Great we now have a new, bigger image new_centos.5-3.x86.img that we can now bundle, upload and register with Eucalyptus.

Before you proceed, make sure you clean up by un-mounting the images and detaching them from the loop devices

umount /dev/loop1
umount /dev/loop2

losetup -d /dev/loop1
losetup -d /dev/loop2




Bundle, Upload, Register

Now would be a good time to install Euca2ools if you haven’t done so already.

There are 3 steps to making an EMI available:

  1. Bundling
  2. Uploading
  3. Registering

And since an EMI is made up for a kernel image, a ramdisk image and a hard disk image, we need to perform the above 3 steps on each of the kernel, ramdisk and hard disk image.

Eucalyptus Kernel Image

First, we bundle the kernel image using Euca2ools euca-bundle-image command as follows:

euca-bundle-image -i xen-kernel/vmlinuz-2.6.24-19-xen --kernel true --arch i386

where,
xen-kernel/vmlinuz-2.6.24-19-xen – is the path to the kernel image
i386 – is the architecture. In our case, 32-bit architecture
The other argument –kernel true tells the euca-bundle-image that this is a kernel image.

i386
Checking image
Tarring image
Encrypting image
Splitting image…
Part: vmlinuz-2.6.24-19-xen.part.0
Generating manifest /tmp/vmlinuz-2.6.24-19-xen.manifest.xml

The above command packages the kernel image and generates a manifest.xml file under /tmp directory.

We will pass the full path to the manifest file as an argument to euca-upload-image to upload the image to Walrus:

euca-upload-bundle -b kernel-bucket -m /tmp/vmlinuz-2.6.24-19-xen.manifest.xml 

where,
kernel-bucket – is the name of the bucket that the image (kernel image) will be stored under.
/tmp/vmlinuz-2.6.24-19-xen.manifest.xml – is the manifest.xml that was generated by the euca-bundle-image command

Checking bucket: kernel-bucket
Uploading manifest file
Uploading part: vmlinuz-2.6.24-19-xen.part.0
Uploaded image as kernel-bucket/vmlinuz-2.6.24-19-xen.manifest.xml

As you can see from the output, the kernel image was uploaded to kernel-bucket in Walrus. Note that you could replace kernel-bucket with a name of your choice.

Once we have uploaded the image, we need to register it so that it is available for use. We can do this using the euca-register command:

euca-register kernel-bucket/vmlinuz-2.6.24-19-xen.manifest.xml

where,
kernel-bucket/vmlinuz-2.6.24-19-xen.manifest.xml – is the path to the kernel image in walrus

IMAGE eki-90461381

The output of the euca-register command is an image id. We can use this image id when we bundle up the hard disk image or when we create an instance from a Eucalyptus machine image. The prefix of “eki” implies that the image is a kernel image, more specifically a Eucalyptus Kernel Image (EKI).

Verify that the EKI image is available by running euca2ools euca-describe-images command:

euca-describe-images 
IMAGE eki-90461381 kernel-bucket/vmlinuz-2.6.24-19-xen.manifest.xml admin available public i386 kernel

Eucalyptus Ramdisk Image

Bundle the ramdisk image as follows:

euca-bundle-image -i xen-kernel/initrd.img-2.6.24-19-xen --ramdisk true --arch i386

where,
xen-kernel/initrd.img-2.6.24-19-xen – is the path to the ramdisk image
i386 – is the architecture. In our case, 32-bit architecture
The other argument –ramdisk true specifies that this is a ramdisk image.

i386
Checking image
Tarring image
Encrypting image
Splitting image…
Part: initrd.img-2.6.24-19-xen.part.0
Generating manifest /tmp/initrd.img-2.6.24-19-xen.manifest.xml

The above command packages the ramdisk image and generates a manifest.xml file in the /tmp directory.

Next, we pass the path to the manifest.xml file as an argument to the euca-upload-bundle command to upload the image to Walrus.

euca-upload-bundle -b ramdisk-bucket -m /tmp/initrd.img-2.6.24-19-xen.manifest.xml

where,
ramdisk-bucket – is the name of the bucket that the ramdisk image will be stored under.
/tmp/initrd.img-2.6.24-19-xen.manifest.xml – is the manifest.xml that was generated in the previous step

Checking bucket: ramdisk-bucket
Uploading manifest file
Uploading part: initrd.img-2.6.24-19-xen.part.0
Uploaded image as ramdisk-bucket/initrd.img-2.6.24-19-xen.manifest.xml

Next we register the image as follows:

euca-register ramdisk-bucket/initrd.img-2.6.24-19-xen.manifest.xml
IMAGE eri-E85914C7

The output of the above euca_register command is an image id. Again, we can use this image id when we bundle up the hard disk image or when we create an instance from a Eucalyptus machine image. The prefix “eri” implies that the image is a ramdisk image, more specifically a Eucalyptus Ramdisk Image (ERI).

Run the describe images command to verify that the ramdisk image is available:

euca-describe-images 
IMAGE eki-90461381 kernel-bucket/vmlinuz-2.6.24-19-xen.manifest.xml admin available public i386 kernel
IMAGE eri-E85914C7 ramdisk-bucket/initrd.img-2.6.24-19-xen.manifest.xml admin available public i386 ramdisk

Finally we are ready to create the Eucalyptus Machine Image.

Eucalyptus Machine Image

We will use the hard disk image – new_centos.5-3.x86.img – we created in the section “Resizing the disk image“. If you skipped the “resize” section, you could use the base image – centos.5-3.x86.img – provided in the download.

Let’s get started with first bundling the hard disk image as follows:

euca-bundle-image -i new_centos.5-3.x86.img --kernel eki-90461381 --ramdisk eri-E85914C7

where,
new_centos.5-3.x86.img – is the path to the hard disk image

The other two arguments to the above command are the Eucalyptus Kernel Image (EKI) id and the Eucalyptus Ramdisk Image (ERI) id. In this case, eki-90461381 and eri-E85914C7 which we obtained when registering the kernel and ramdisk image respectively.

Checking image
Tarring image
Encrypting image
Splitting image…
Part: new_centos.5-3.x86.img.part.0
Part: new_centos.5-3.x86.img.part.1
Part: new_centos.5-3.x86.img.part.2
Part: new_centos.5-3.x86.img.part.3
Part: new_centos.5-3.x86.img.part.4
Part: new_centos.5-3.x86.img.part.5
Part: new_centos.5-3.x86.img.part.6
Part: new_centos.5-3.x86.img.part.7
Part: new_centos.5-3.x86.img.part.8
Part: new_centos.5-3.x86.img.part.9
Part: new_centos.5-3.x86.img.part.10
Part: new_centos.5-3.x86.img.part.11
Part: new_centos.5-3.x86.img.part.12
Part: new_centos.5-3.x86.img.part.13
Part: new_centos.5-3.x86.img.part.14
Part: new_centos.5-3.x86.img.part.15
Part: new_centos.5-3.x86.img.part.16
Part: new_centos.5-3.x86.img.part.17
Part: new_centos.5-3.x86.img.part.18
Part: new_centos.5-3.x86.img.part.19
Part: new_centos.5-3.x86.img.part.20
Part: new_centos.5-3.x86.img.part.21
Part: new_centos.5-3.x86.img.part.22
Part: new_centos.5-3.x86.img.part.23
Part: new_centos.5-3.x86.img.part.24
Part: new_centos.5-3.x86.img.part.25
Part: new_centos.5-3.x86.img.part.26
Part: new_centos.5-3.x86.img.part.27
Part: new_centos.5-3.x86.img.part.28
Part: new_centos.5-3.x86.img.part.29
Part: new_centos.5-3.x86.img.part.30
Part: new_centos.5-3.x86.img.part.31
Part: new_centos.5-3.x86.img.part.32
Part: new_centos.5-3.x86.img.part.33
Part: new_centos.5-3.x86.img.part.34
Part: new_centos.5-3.x86.img.part.35
Part: new_centos.5-3.x86.img.part.36
Part: new_centos.5-3.x86.img.part.37
Part: new_centos.5-3.x86.img.part.38
Generating manifest /tmp/new_centos.5-3.x86.img.manifest.xml

As expected, the above command packages the disk image and generates a manifest.xml file in the /tmp directory.

Next, we upload the disk image to Walrus passing in the manifest.xml file path obtained from the previous command as follows:

euca-upload-bundle -b image-bucket -m /tmp/new_centos.5-3.x86.img.manifest.xml 

where,
image-bucket – is the name of the bucket that the disk image will be stored under.
/tmp/new_centos.5-3.x86.img.manifest.xml – is the manifest.xml that was generated in the previous euca-bundle-image step

Checking bucket: image-bucket
Uploading manifest file
Uploading part: new_centos.5-3.x86.img.part.0
Uploading part: new_centos.5-3.x86.img.part.1
Uploading part: new_centos.5-3.x86.img.part.2
Uploading part: new_centos.5-3.x86.img.part.3
Uploading part: new_centos.5-3.x86.img.part.4
Uploading part: new_centos.5-3.x86.img.part.5
Uploading part: new_centos.5-3.x86.img.part.6
Uploading part: new_centos.5-3.x86.img.part.7
Uploading part: new_centos.5-3.x86.img.part.8
Uploading part: new_centos.5-3.x86.img.part.9
Uploading part: new_centos.5-3.x86.img.part.10
Uploading part: new_centos.5-3.x86.img.part.11
Uploading part: new_centos.5-3.x86.img.part.12
Uploading part: new_centos.5-3.x86.img.part.13
Uploading part: new_centos.5-3.x86.img.part.14
Uploading part: new_centos.5-3.x86.img.part.15
Uploading part: new_centos.5-3.x86.img.part.16
Uploading part: new_centos.5-3.x86.img.part.17
Uploading part: new_centos.5-3.x86.img.part.18
Uploading part: new_centos.5-3.x86.img.part.19
Uploading part: new_centos.5-3.x86.img.part.20
Uploading part: new_centos.5-3.x86.img.part.21
Uploading part: new_centos.5-3.x86.img.part.22
Uploading part: new_centos.5-3.x86.img.part.23
Uploading part: new_centos.5-3.x86.img.part.24
Uploading part: new_centos.5-3.x86.img.part.25
Uploading part: new_centos.5-3.x86.img.part.26
Uploading part: new_centos.5-3.x86.img.part.27
Uploading part: new_centos.5-3.x86.img.part.28
Uploading part: new_centos.5-3.x86.img.part.29
Uploading part: new_centos.5-3.x86.img.part.30
Uploading part: new_centos.5-3.x86.img.part.31
Uploading part: new_centos.5-3.x86.img.part.32
Uploading part: new_centos.5-3.x86.img.part.33
Uploading part: new_centos.5-3.x86.img.part.34
Uploading part: new_centos.5-3.x86.img.part.35
Uploading part: new_centos.5-3.x86.img.part.36
Uploading part: new_centos.5-3.x86.img.part.37
Uploading part: new_centos.5-3.x86.img.part.38
Uploaded image as image-bucket/new_centos.5-3.x86.img.manifest.xml

Finally, we register the image as follows:

euca-register image-bucket/new_centos.5-3.x86.img.manifest.xml
IMAGE emi-9FE813FD

A quick euca-describe-images reveals the EMI that is available for use:

IMAGE eki-90461381 kernel-bucket/vmlinuz-2.6.24-19-xen.manifest.xml admin available public i386 kernel
IMAGE emi-9FE813FD image-bucket/new_centos.5-3.x86.img.manifest.xml admin available public x86_64 machine eri-E85914C7 eki-90461381
IMAGE eri-E85914C7 ramdisk-bucket/initrd.img-2.6.24-19-xen.manifest.xml admin available public i386 ramdisk




In the next post, we will look into creating instances of the EMI that we just registered.