HowTo: Installation of an Ubuntu Cloud Image at Home (on a Xenial – 16.04)

This HowTo describes an installation of an Ubuntu Cloud Image on a home-server running Ubuntu Xenial (16.04 LTS) with qemu-kvm. This will be done without the help of libvirt, which comes with an additional abstraction layer I don’t really need. This blog post is more about basic understanding of virtualization and how it is set up in a more or less simple way – unfortunately it’ll be more complex than I initially thought. But with this HowTo this shouldn’t be a problem anymore.

But what is the Ubuntu Cloud Image? – Well, this is the simple part to explain: The Ubuntu Cloud Image is a pre-installed virtual machine you only have to adjust a bit to your needs. Download it and start it (almost) right away. In the ‘old’ days one had to provide an Installation-Image first in order to install a virtual machine. You had to go through the whole installation process every time – but not anymore.

And what are the scenarios it can be used for?  You can just copy and adjust an virtual machine by copy the original one and start it right away – If you decide to create a web-server or one more test client to play with – it’s a matter of a few minutes. And you can run it on every machine, where qemu-kvm is installed. Just copy the image and its seed to the destination host and start it again. Every virtual machine has its own IP-Address and hostname and you can access is e.g. with VNC from everywhere in you network. In other words: Awesome!

OK – here we go. This HowTo will describe these topics below. We will:

  • Install all needed deb-packages
  • Download the Ubuntu Cloud Image
  • Create a seed image with cloud-localds
  • Create a bridge interface
  • Start the virtual machine
  • Access the machine with VNC or Spice
  • Create a common share for Guest and Host
  • Tweak the Guest
  • Troubleshoot the whole thing

Not all parts of this blog are necessary but make sense in real life situations. E.g. sharing the same harddisk is a pretty nice feature if you want to avoid the usage of cifs aka samba or remote file transfers. I also describe how to use the vmware-drv for X11 – ah – this said – I also will show how a simple X11 installation with openbox will look like – so we will have a desktop to 🙂 – But you can quit reading after you’ve started your guest with a working internet connection – the rest is add-on.

Now let’s begin.

Installation of deb-packages

We need the following debian (.deb) installation packages:

$ sudo apt install cloud-image-utils qemu-kvm

Cloud-image-utils: This will install cloud-localds. This is a helper-tool in oder to generate a image file, which will be given to our primary Ubuntu Cloud Image to mount at boot time. It contains password credentials so you can log into your new virtual machine.

Qemu-kvm: Since we do run a Linux inside a Linux and all are based on x86/x64 architecture, we can speed things up dramatically and use an additional Hypervisor (kvm). For emulating other architectures like ARM or Motorola 680xx CPUs qemu would be enough, but also slower.

Ubuntu Cloud Image download

Here one should pay attention – it is important to download the image containing the “*disk1*” in it. Otherwise it won’t work. Create a working directory and cd into it.

$ wget

Create a seed with credentials

First we have to create a file. Open therefore a file called seed with an editor of your choice (here it is nano):

$ nano seed

Paste the following content into it – please adjust the password to your needs.

password: my_passw0rd_here
chpasswd: { expire: False }
ssh_pwauth: True

Save it and create the seed image now:

$ cloud-localds -H myhost_hostname_here seed.img seed

Please replace myhost_hostname_here with a hostname of your choice.

Your directory should now looks like this (well your user most likely won’t be ‘acme‘ of course):

drwxr-xr-x 2 root root 4096      Jun 19 20:40 ./ 
drwxr-xr-x 4 acme acme 4096      Jun 19 20:08 ../ 
-rwxr-xr-x 1 acme acme 98        Jun 19 20:23 seed* 
-rw-r--r-- 1 acme acme 374784    Jun 19 20:40 seed.img 
-rw-r--r-- 1 acme acme 287506432 Jun 18 17:15 xenial-server-cloudimg-amd64-disk1.img

Btw.: This is the first milestone. Starting cloud-localds without any parameter will tell you very briefly how to start this guest with an poor-mans LAN-access. It says at the very bottom:

    * cat my-user-data
    password: passw0rd
    chpasswd: { expire: False }
    ssh_pwauth: True
    * echo "instance-id: $(uuidgen || echo i-abcdefg)" > my-meta-data
    * cloud-localds my-seed.img my-user-data my-meta-data
    * kvm -net nic -net user,hostfwd=tcp::2222-:22 \
     -drive file=disk1.img,if=virtio -drive file=my-seed.img,if=virtio
    * ssh -p 2222 ubuntu@localhost

If you are inpatient, you can try this already – but it’s not really a solution though.

Creating a bridge (br0)

Now we are close to run our guest. Actually we could already boot the new image, but we wouldn’t be able to do much since we don’t have a network connection for. That’s why we’re going to create a so called ‘bridge’.

A bridge will enable your guest to communicate with the rest of your network and also to the internet. Since we keep things simple without libvert – there won’t be an automatically created interface (old-style: virbr0 / new-style: lxcbr0). Our bridge will be called the old fashion way: br0 – And we make it static!

The traffic of your host and the traffic of your guests (virtual machines) will we all routet over this bridge interface. Additionally and fully automatic another network device will be created: It is called tap0. Don’t worry, qemu-kvm will create it and use it automatically. Btw. tap does the transport on layer 2, where as tun (not used here) does layer 3. In other words, your guest will think it has a fully fledged nic at its disposal.

In order to run our guest without root priveleges and networking at the same time, we need to circumvent more of less a bug actually present around the qemu-bridge-helper tool. We have to do two steps before we create the bridge (br0) in the /etc/network/interfaces):

Chanching the privileges of qemu-bridge-helper

$ sudo chmod u+s /usr/lib/qemu/qemu-bridge-helper

Also documented here:

Granting permission to br0

Create a directory first:

$ sudo mkdir /etc/qemu

Now create the file ‘bridge.conf‘ with the following one-liner inside the newly created directory:

allow br0

Now creating the bridge for real

Now open /etc/network/interfaces and add this to it:

#auto enp4s0
#iface enp4s0 inet dhcp
auto br0 iface br0 inet static 
    bridge_ports enp4s0 
    bridge_fd 15 
    bridge_stp yes 


  • Remove, or better comment all lines which configure your current enpXs0 device. The new br0 will bring the device up for you.
  • Also consider to adjust all red marked entries above, since these are the one for my machine and network right now.

Restarting the network

Now it time to bring the new interface up. You can do this by invoking:

$ sudo systemctl restart networking

The result of ifconfig should look approximately like this:

br0 Link encap:Ethernet HWaddr d1:50:19:12:2e:6b
    inet addr: Bcast: Mask:
    RX packets:56733 errors:0 dropped:218 overruns:0 frame:0
    TX packets:38977 errors:0 dropped:0 overruns:0 carrier:0
    collisions:0 txqueuelen:1000
    RX bytes:297510526 (297.5 MB) TX bytes:2897392 (2.8 MB)

enp4s0 Link encap:Ethernet HWaddr d1:50:19:12:2e:6b
    RX packets:226482 errors:0 dropped:17 overruns:0 frame:0
    TX packets:42793 errors:0 dropped:0 overruns:0 carrier:0
    collisions:0 txqueuelen:1000
    RX bytes:310279886 (310.2 MB) TX bytes:3130336 (3.1 MB)

lo Link encap:Local Loopback
    inet addr: Mask:
    UP LOOPBACK RUNNING MTU:65536 Metric:1
    RX packets:320 errors:0 dropped:0 overruns:0 frame:0
    TX packets:320 errors:0 dropped:0 overruns:0 carrier:0
    collisions:0 txqueuelen:1
    RX bytes:23680 (23.6 KB) TX bytes:23680 (23.6 KB)

If this doesn’t bring up your br0 interface – reboot. If you encounter interface names like virbr0 or lxcbr0, that you have to check, if you accidentally installed libvirt. ($ dpkg -l | grep libvirt). Remove this packages, since you will end up in a mess. Also don’t install cloud-init!

Starting the virtual machine

Now it’s the great moment. We can finally start the virtual machine. Before you do, please don’t use ‘sudo‘ – Running a virtual machine as ‘root‘ is mostly discouraged.

When starting the machine, a window with your console will pop up. This of course can only happen, if you are really in front of a real Linux box. I’ve done it all with ‘xhost +‘ and ‘export DISPLAY‘ or ‘ssh -XC‘ remotely, but this is not part of this blog. So start your guest now with:

$ kvm -hda xenial-server-cloudimg-amd64-disk1.img -hdb seed.img -net nic,macaddr=52:54:00:22:33:44,netdev=hn0 -netdev tap,id=hn0,helper=/usr/lib/qemu/qemu-bridge-helper

If everything went alright, you should see a terminal window booting your new guest. You will and up in the login prompt. The default user is ubuntu. Changing the user is not possible, unless we use more sophisticated tools like cloud-init. But we wont do it here.
Please enter your previously chosen passord now and hit enter. If everthing went right, you should be able to ping the internet or your machines in your network.

The MAC-Address from above is important for your router at home. This is what the router will see and will handle the hostname and routing accordingly. For each new machine, you must provide a different MAC-Address, else you’ll end up with a chaotic situation (well I did) on your router. Just vary the last digits.


to be contiued the next days (don’t worry, I don’t have to figure out the rest first – I’ve got it all running here already. I just need time to write it down.)

Leave a Reply

Your email address will not be published. Required fields are marked *