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.
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:
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 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/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
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/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.
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
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:
- Bundling
- Uploading
- 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.
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
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
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
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.
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
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
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 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.
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
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
A quick euca-describe-images reveals the EMI that is available for use:
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.