Atom feed of this document
 

 Creating raw or QCOW2 images

This section describes how to create a raw or QCOW2 image from a Linux installation ISO file. Raw images are the simplest image file format and are supported by all of the hypervisors. QCOW2 images have several advantages over raw images. They take up less space than raw images (growing in size as needed), and they support snapshots.

[Note]Note

QCOW2 images are only supported with KVM and QEMU hypervisors.

As an example, this section will describe how to create aa CentOS 6.2 image. 64-bit ISO images of CentOS 6.2 can be downloaded from one of the CentOS mirrors. This example uses the CentOS netinstall ISO, which is a smaller ISO file that downloads packages from the Internet as needed.

 Create an empty image (raw)

Here we create a 5GB raw image using the kvm-img command:

$ IMAGE=centos-6.2.img
$ kvm-img create -f raw $IMAGE 5G

 Create an empty image (QCOW2)

Here we create a a 5GB QCOW2 image using the kvm-img command:

$ IMAGE=centos-6.2.img
$ kvm-img create -f qcow $IMAGE 5G

 Boot the ISO using the image

First, find a spare vnc display. (Note that vnc display :N correspond to TCP port 5900+N, so that :0 corresponds to port 5900). Check which ones are currently in use with the lsof command, as root:

# lsof -i | grep "TCP \*:590"
kvm        3437 libvirt-qemu   14u  IPv4 1629164      0t0  TCP *:5900 (LISTEN)
kvm        24966 libvirt-qemu   24u  IPv4 1915470      0t0  TCP *:5901 (LISTEN)

This shows that vnc displays :0 and :1 are in use. In this example, we will use VNC display :2.

Also, we want a temporary file to send power signals to the VM instance. We default to /tmp/file.mon, but make sure it doesn't exist yet. If it does, use a different file name for the MONITOR variable defined below:

$ IMAGE=centos-6.2.img
$ ISO=CentOS-6.2-x86_64-netinstall.iso
$ VNCDISPLAY=:2
$ MONITOR=/tmp/file.mon
$ sudo  kvm -m 1024 -cdrom $ISO -drive file=${IMAGE},if=virtio,index=0 \
-boot d -net nic -net user -nographic -vnc ${VNCDISPLAY} \
-monitor unix:${MONITOR},server,nowait

 Connect to the instance via VNC

VNC is a remote desktop protocol that will give you full-screen display access to the virtual machine instance, as well as let you interact with keyboard and mouse. Use a VNC client (e.g., Vinagre on Gnome, Krdc on KDE, xvnc4viewer from RealVNC, xtightvncviewer from TightVNC) to connect to the machine using the display you specified. You should now see a CentOS install screen.

 Point the installer to a CentOS web server

The CentOS net installer requires that the user specify the web site and a CentOS directory that corresponds to one of the CentOS mirrors.

  • Web site name: mirror.umd.edu (consider using other mirrors as an alternative)

  • CentOS directory: centos/6.2/os/x86_64

See CentOS mirror page to get a full list of mirrors, click on the "HTTP" link of a mirror to retrieve the web site name of a mirror.

 Partition the disks

There are different options for partitioning the disks. The default installation will use LVM partitions, and will create three partitions (/boot, /, swap). The simplest approach is to create a single ext4 partition, mounted to "/".

 Step through the install

The simplest thing to do is to choose the "Server" install, which will install an SSH server.

 When install completes, shut down the instance

Power down the instance using the monitor socket file to send a power down signal, as root:

# MONITOR=/tmp/file.mon
# echo 'system_powerdown' | socat - UNIX-CONNECT:$MONITOR

 Start the instance again without the ISO

$ VNCDISPLAY=:2
$ MONITOR=/tmp/file.mon
$ sudo  kvm -m 1024 -drive file=${IMAGE},if=virtio,index=0 \
-boot c -net nic -net user -nographic -vnc ${VNCDISPLAY} \
-monitor unix:${MONITOR},server,nowait

 Connect to instance via VNC

When you boot the first time, it will ask you about authentication tools, you can just choose 'Exit'. Then, log in as root using the root password you specified.

 Edit HWADDR from eth0 config file

The operating system records the MAC address of the virtual ethernet card in /etc/sysconfig/network-scripts/ifcfg-eth0 during the instance process. However, each time the image boots up, the virtual ethernet card will have a different MAC address, so this information must be deleted from the configuration file.

Edit /etc/sysconfig/network-scripts/ifcfg-eth0 and remove the HWADDR= line.

 Configure to fetch metadata

An instance must perform several steps on startup by interacting with the metada service (e.g., retrieve ssh public key, execute user data script). There are several ways to implement this functionality, including:

  • Install a cloud-init RPM , which is a port of the Ubuntu cloud-init package. This is the recommended approach.

  • Modify /etc/rc.local to fetch desired information from the metadata service, as described below.

 Using cloud-init to fetch the public key

The cloud-init package will automatically fetch the public key from the metadata server and place the key in an account. The account varies by distribution. On Ubuntu-based virtual virtual machines, the account is called "ubuntu". On Fedora-based virtual machines, the account is called "ec2-user".

You can change the name of the account used by cloud-init by editing the /etc/cloud/cloud.cfg file and adding a line with a different user. For example, to configure cloud-init to put the key in an account named "admin", edit the config file so it has the line:

user: admin

 Writing a script to fetch the public key

To fetch the ssh public key and add it to the root account, edit the /etc/rc.local file and add the following lines before the line “touch /var/lock/subsys/local”

depmod -a
modprobe acpiphp

# simple attempt to get the user ssh key using the meta-data service
mkdir -p /root/.ssh
echo >> /root/.ssh/authorized_keys
curl -m 10 -s http://169.254.169.254/latest/meta-data/public-keys/0/openssh-key | grep 'ssh-rsa' >> /root/.ssh/authorized_keys
echo "AUTHORIZED_KEYS:"
echo "************************"
cat /root/.ssh/authorized_keys
echo "************************"
[Note]Note

Some VNC clients replace : (colon) with ; (semicolon) and _ (underscore) with - (hyphen). Make sure it's http: not http; and authorized_keys not authorized-keys.

[Note]Note

The above script only retrieves the ssh public key from the metadata server. It does not retrieve user data, which is optional data that can be passed by the user when requesting a new instance. User data is often used for running a custom script when an instance comes up.

As the OpenStack metadata service is compatible with version 2009-04-04 of the Amazon EC2 metadata service, consult the Amazon EC2 documentation on Using Instance Metadata for details on how to retrieve user data.

 Shut down the instance

From inside the instance, as root:

# /sbin/shutdown -h now

 Modifying the image (raw)

You can make changes to the filesystem of an image without booting it, by mounting the image as a file system. To mount a raw image, you need to attach it to a loop device (e.g., /dev/loop0, /dev/loop1). To identify the next unused loop device, as root:

# losetup -f
/dev/loop0

In the example above, /dev/loop0 is available for use. Associate it to the image using losetup, and expose the partitions as device files using kpartx, as root:

# IMAGE=centos-6.2.img
# losetup /dev/loop0 $IMAGE
# kpartx -av /dev/loop0

If the image has, say three partitions (/boot, /, /swap), there should be one new device created per partition:

$ ls -l /dev/mapper/loop0p*
brw-rw---- 1 root disk 43, 49 2012-03-05 15:32 /dev/mapper/loop0p1
brw-rw---- 1 root disk 43, 50 2012-03-05 15:32 /dev/mapper/loop0p2
brw-rw---- 1 root disk 43, 51 2012-03-05 15:32 /dev/mapper/loop0p3

To mount the second partition, as root:

# mkdir /mnt/image
# mount /dev/mapper/loop0p2 /mnt/image

You can now modify the files in the image by going to /mnt/image. When done, unmount the image and release the loop device, as root:

# umount /mnt/image
# losetup -d /dev/loop0

 Modifying the image (qcow2)

You can make changes to the filesystem of an image without booting it, by mounting the image as a file system. To mount a QEMU image, you need the nbd kernel module to be loaded. Load the nbd kernel module, as root:

# modprobe nbd max_part=8
[Note]Note

If nbd has already been loaded with max_part=0, you will not be able to mount an image if it has multiple partitions. In this case, you may need to first unload the nbd kernel module, and then load it. To unload it, as root:

# rmmod nbd

Connect your image to one of the network block devices (e.g., /dev/nbd0, /dev/nbd1). In this example, we use /dev/nbd3. As root:

# IMAGE=centos-6.2.img
# qemu-nbd -c /dev/nbd3 $IMAGE

If the image has, say three partitions (/boot, /, /swap), there should be one new device created per partition:

$ ls -l /dev/nbd3*
brw-rw---- 1 root disk 43, 48 2012-03-05 15:32 /dev/nbd3
brw-rw---- 1 root disk 43, 49 2012-03-05 15:32 /dev/nbd3p1
brw-rw---- 1 root disk 43, 50 2012-03-05 15:32 /dev/nbd3p2
brw-rw---- 1 root disk 43, 51 2012-03-05 15:32 /dev/nbd3p3
[Note]Note

If the network block device you selected was already in use, the initial qemu-nbd command will fail silently, and the /dev/nbd3p{1,2,3} device files will not be created.

To mount the second partition, as root:

# mkdir /mnt/image
# mount /dev/nbd3p2 /mnt/image

You can now modify the files in the image by going to /mnt/image. When done, unmount the image and release the network block device, as root:

# umount /mnt/image
# qemu-nbd -d /dev/nbd3

 Upload the image to glance (raw)

$ IMAGE=centos-6.2.img
$ NAME=centos-6.2
$ glance image-create --name="${NAME}" --is-public=true --container-format=ovf --disk-format=raw < ${IMAGE}

 Upload the image to glance (qcow2)

$ IMAGE=centos-6.2.img
$ NAME=centos-6.2
$ glance image-create --name="${NAME}" --is-public=true --container-format=ovf --disk-format=qcow2 < ${IMAGE}


loading table of contents...