Linux KVM: Ubuntu 12.10 with Openvswitch
Today I am revisiting my previous post on Openvswitch on Ubuntu 12.04. Things have changed since then. Previously Openvswitch was relatively new and as such the userland tools (with libvirt being the one I use) didn’t support it yet, so while you could have used Openvswitch by executing the kvm processes for each VM manually. Since this was a predictable problem the Openvswitch guys created a brcompat module, which would take the place of the bridge_utils functionality and expose Openvswitch bridges as legacy bridges. This allowed the existing userland which already had the legacy bridge functionality builtin to continue to operate the same way. Anyways as of libvirt 0.9.11 the native Openvswitch functionality is present and supported. As such I am updating my documentation to include this alternate and preferred method of operation.
Here is the libvirt version present in Ubuntu 12.10.
# libvirtd --version libvirtd (libvirt) 0.9.13
Here is the libvirt version present in Ubuntu 12.04.
# libvirtd --version libvirtd (libvirt) 0.9.8
So as we can see above this guide will only work on Ubuntu 12.10 and not on 12.04 or older. For Ubuntu 12.04, please refer to my older article available here.
Install Updates and Prerequisite Software
Check for updates, and install some commonly used hypervisor utilities along with the openvswitch and kvm stacks. Note that below I am installing the openvswitch-brcompat package. I do not think that you need this, however I did install it in my environment in case I was going to need to fail back to the brcompat route, and I haven’t had the time to validate it without that package installed. But it is not being used in this configuration.
# apt-get install aptitude apt-show-versions ntp ntpdate vim kvm libvirt-bin vlan virtinst virt-manager virt-viewer openssh-server iperf pv openvswitch-controller openvswitch-brcompat openvswitch-switch
Destroy the Default Libvirt Bridge (virbr0)
We want to delete the default libvirt interface which is created by default to be used for guests (I think it is NAT – I never use it).
# virsh net-destroy default # virsh net-autostart --disable default
Stop Libvirt and Qemu
This will prevent libvirt from bringing up the legacy bridge.
# service libvirt-bin stop # service qemu-kvm stop
Purge Ebtables from System
Ebtables was needed when we were using VLANs on bridge-utils, we no longer need this for openvswitch.
# aptitude purge ebtables
Restart the Openvswitch Services
#service openvswitch-switch restart #service openvswitch-controller restart
Now this configuration is a single interface which will be used both for management of the hypervisor as well as the bridge. There are three key things to note. We need to set the physical interface to “manual” (instead of “dhcp” or “static”). We also need to perform a quick up and down of the physical interface in order to be able to initialize the bridge on it. Finally we need to setup the configuration of an interface which will connect up to the bridge that we define, this becomes the management interface for the OS. In this example we are simply using DHCP. This will show us if it is working quickly, but it can also add some complexity if things are not working, please keep in mind that you might want to just use a static IP address to eliminate that as an issue.
# cat /etc/network/interfaces auto lo iface lo inet loopback # The primary network interface auto eth0 iface eth0 inet manual up ifconfig $IFACE 0.0.0.0 up down ifconfig $IFACE down auto ovsbr0p1 iface ovsbr0p1 inet dhcp
Configure our Network
Configuring the network will be a three step process. First we define the bridge which I am naming ovsbr0 unlike legacy bridges we don’t need to stick to brX as a naming convention.
# ovs-vsctl add-br ovsbr0
Second we connect our bridge with its uplink which in this case is eth0.
# ovs-vsctl add-port ovsbr0 eth0
Finally we create a port for our hypervisor to connect up to the bridge and out the physical interface.
# ovs-vsctl add-port ovsbr0 ovsbr0p1 -- set interface ovsbr0p1 type=internal
After all of that we should end up with something like below.
# ovs-vsctl show ed1986fc-830e-4f66-9ce7-92fad0787bb8 Bridge "ovsbr0" Port "ovsbr0" Interface "ovsbr0" type: internal Port "ovsbr0p1" Interface "ovsbr0p1" type: internal Port "eth0" Interface "eth0" ovs_version: "1.4.3"
Adjusting Service Sleeps
If your networking seems to hang on boot up.
In /etc/failsafe.conf we need to adjust the sleeps.
$PLYMOUTH message --text="Waiting for network configuration..." || : sleep 40 $PLYMOUTH message --text="Waiting up to 60 more seconds for network configuration..." || : sleep 59 $PLYMOUTH message --text="Booting system without full network configuration..." || :
$PLYMOUTH message --text="Waiting for network configuration..." || : sleep 1 $PLYMOUTH message --text="Waiting up to 60 more seconds for network configuration..." || : sleep 1 $PLYMOUTH message --text="Booting system without full network configuration..." || :
Obviously if you end up needing this change, make sure you reboot again to ensure that it resolved the issue.
Define VM Configuration
I am not going to go into details on how to create a guest from XML, but if you need some help on that refer to my previous article here.
Basically below we have a snippet from a guests XML configuration which configures a single network interface. You can edit an existing machine configuration using “virsh edit vmnamehere”
<interface type='bridge'> <mac address='52:54:00:0f:b4:7a'/> <source bridge='ovsbr0'/> <virtualport type='openvswitch'/> <model type='virtio'/> </interface>
After you have merged the changes in, libvirt will go create a port on Openvswitch for this guest. Which we can see below as vnet0.
# ovs-vsctl show ed1986fc-830e-4f66-9ce7-92fad0787bb8 Bridge "ovsbr0" Port "ovsbr0" Interface "ovsbr0" type: internal Port "ovsbr0p1" Interface "ovsbr0p1" type: internal Port "vnet0" Interface "vnet0" Port "eth0" Interface "eth0" ovs_version: "1.4.3"
Additionally we can see that in our VM configuration libvirt has added more details, the target dev and parameters interfaceid. This is how the VM knows which port on the Openvswitch to connect to.
<interface type='bridge'> <mac address='52:54:00:0f:b4:7a'/> <source bridge='ovsbr0'/> <virtualport type='openvswitch'> <parameters interfaceid='a78ac510-2442-1326-c60f-d76c1e830bd6'/> </virtualport> <target dev='vnet0'/> <model type='virtio'/> <alias name='net0'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> </interface>
That is all there is to it. When you bring up your guest. you will have networking exactly as you expected. But now you open yourself up to a world of possibilities with Openvswitch, such as port mirroring, QoS, LACP and many more.