Running cloud-images with qemu
Table of Contents
Keywords: qemu cloud images
In this post I will show how to obtain a cloud image and run it with qemu. We will provide a file that is processed by cloud-init to install software in the VM at boot time. We will also redirect requests from the host machine to the guest.
Obtain the image
We are going to save the image to a folder (it is a demo so /tmp/demo
is a good place):
mkdir /tmp/demo wget https://cloud-images.ubuntu.com/xenial/current/xenial-server-cloudimg-amd64-disk1.img -O /tmp/demo/xenial.img
Increase disk size (if you need it):
IMG="/tmp/demo/xenial.img" qemu-img info $IMG qemu-img resize $IMG 10G echo "------------------" qemu-img info $IMG
Run the image with qemu
These images run cloud-init
at boot time and the try to connect to the IP 169.254.169.254 to get initial configuration from the metadata service. As we are not in a cloud environment we need to provide this information with a different datasource.
We create the file user-data
:
cd /tmp/demo cat > user-data << HERE #cloud-config chpasswd: list: | ubuntu:ubu123 expire: False HERE
and the file meta-data
:
cd /tmp/demo cat > meta-data << HERE instance-id: worker local-hostname: worker HERE
Then we create an ISO file containing these two files:
cd /tmp/demo
genisoimage -o nocloud.iso -V cidata -r -J user-data meta-data
ls
Finally we can run qemu
providing the ISO file:
DIR=/tmp/demo IMG="$DIR"/xenial.img sudo qemu-system-x86_64 -m 2048 --enable-kvm \ --name test1 \ -vga virtio \ -cpu host \ -drive file="$IMG",if=virtio,format=qcow2 \ -drive file="$DIR"/nocloud.iso,media=cdrom
We can login into the VM using ubuntu
and the password provided in the user-data
file.
This VM has access to internet and we can install the required software.
Bonus: installing software at boot time
In this example, we are going to modify user-data
to install Apache and download static files from a host (using wget
). You should provide a host name or IP instead of HOST
:
cd /tmp/demo cat > user-data << HERE #cloud-config ssh_pwauth: True chpasswd: list: | ubuntu:ubu123 expire: False package_update: true packages: - apache2 runcmd: - wget http://HOST/public/site.tgz -O /var/www/html/site.tgz - tar xzvf /var/www/html/site.tgz -C /var/www/html - mv /var/www/html/site/* /var/www/html - rmdir /var/www/html/site HERE
We use the same meta-data
file:
cd /tmp/demo cat > meta-data << HERE dsmode: local instance-id: worker local-hostname: worker HERE
We also generate the ISO file:
cd /tmp/demo
genisoimage -o nocloud.iso -V cidata -r -J user-data meta-data
We can also generate the static content and upload it to the server: Generación del contenido:
mkdir /tmp/demo/site cd /tmp/demo/site cat > index.html << HERE <html> <head> <link rel="stylesheet" href="css/site.css"/> </head> <body> <h1 class="header"> Welcome </h1> <div id="content"> <p> This is my site!</p> </div> </body> <html> HERE mkdir css cd css cat > site.css << HERE .header{ font-size: 140%; margin-left: 20px; background: #AFAFAF; } #content{ margin: 12px; background: #9AF19A; font-size: 120%; } HERE cd /tmp/demo tar czvf site.tgz site # I assume that HOST runs an HTTP server and a SSH server scp site.tgz user@HOST:/path/public rm -rf site/
Finally, we run qemu
:
DIR=/tmp/demo IMG="$DIR"/xenial.img sudo qemu-system-x86_64 -m 2048 --enable-kvm \ --name test1 \ -net user,hostfwd=tcp::8080-:80 \ -net nic \ -vga virtio \ -cpu host \ -drive file="$IMG",if=virtio,format=qcow2 \ -drive file="$DIR"/nocloud.iso,media=cdrom
We are providing the parameters -net user,hostfwd=tcp::8080-:80
to redirect requests from port 8080 to port 80 of the guest where apache service should be running.
We can open a browser and try the following address: http://localhost:8080/index.html
.