Open vSwitch as the core of a virtual network

In this article, KVM / libvirt is used for virtualization, but I note right away that the article is not so much about KVM, but about the features of the benefits of using Open vSwitchto combine virtual and physical network devices through VLAN (802.1q) technology. In the old days, all kinds of crutches and props of varying degrees of surprise (tuntap, brctl, vconfig, ebtables, etc.) were used to forward tagged traffic to the hypervisor, which led to cluttering the operating system that hosts the hypervisor with a large number of unnecessary virtual network interfaces that corrupted the eyes in the output ifconfig and generally upset administrators with the need to build a standard network device (switch) from separate parts like some kind of bicycle. In addition to supporting 802.1q, the switch actually requires many more features today. So the need for a virtual device that is as functional as possible with a standard modern managed switch led to the emergence of a projectOpen vSwitch (hereinafter - OVS).

image
Figure 1: Sandbox Design
The KDPV (Figure 1) depicts the OVS user case for building a sandbox in preparation for replacing our legacy VPN routers with new ones. You need to configure new VPN routers similarly to those already installed in our company with the same IP addresses, filtering rules, and dynamic routing settings. And test everything in a sandbox emulating ISPs (through which VPN routers connect) and our LAN sites. But again, this article is not about the difficulties of setting up our VPN routers, but about how to connect them to our cozy virtual sandbox via VLAN in general and OVS in particular.
Let's start from the very beginning by installing a clean copy of ubuntu-14.04.1-server-amd64 with the option “Virtual Machine host”. After installation, the system has the following form:
Display Utilities for Viewing Network Settings
root @ sandbox: ~ # ifconfig | grep -vE 'RX | TX | coll | inet6 | MTU'
eth0 Link encap: Ethernet HWaddr 00: 1b: 78: 9c: 2b: fc  
          inet addr: 10.0.7.1 Bcast: 10.0.7.255 Mask: 255.255.255.0
lo Link encap: Local Loopback  
          inet addr: 127.0.0.1 Mask: 255.0.0.0
virbr0 Link encap: Ethernet HWaddr 1a: 70: 19: e9: 3c: c7  
          inet addr: 192.168.122.1 Bcast: 192.168.122.255 Mask: 255.255.255.0
root @ sandbox: ~ # route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 10.0.7.254 0.0.0.0 UG 0 0 0 eth0
10.0.7.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
192.168.122.0 0.0.0.0 255.255.255.0 U 0 0 0 virbr0
root @ sandbox: ~ # cat / etc / network / interfaces | grep -v ^ #
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet static
	address 10.0.7.1
	netmask 255.255.255.0
	network 10.0.7.0
	broadcast 10.0.7.255
	gateway 10.0.7.254
	# dns- * options are implemented by the resolvconf package, if installed
	dns-nameservers 10.0.1.1
root @ sandbox: ~ # virsh net-list --all
Name State Autostart Persistent
-------------------------------------------------- --------
default active yes yes
root @ sandbox: ~ # virsh net-dumpxml default
default865fd53b-5bd5-430c-b7c7-664125dee9f6
root @ sandbox: ~ # brctl show
bridge name bridge id STP enabled interfaces
virbr0 8000.000000000000 yes	
Everything is very standard, nothing unusual.
The picture is still simpler:
image
Figure 2: Initial System Status
Install openvswitch:
apt-get install openvswitch-switch
After installing it, no changes in the network parameters occur, only the OVS service is launched, waiting for our orders. Let's not make him wait. We enter the commands below from the console or place them in a temporary .sh script and run:
ovs-vsctl add-br ovs-br0
ovs-vsctl set port ovs-br0 tag = 7
ovs-vsctl add-port ovs-br0 eth0
ovs-vsctl set port eth0 trunks = 7,10,20,1010,1020,30,1030
ifconfig eth0 0
ifconfig ovs-br0 10.0.7.1/24 up
ip r add default via 10.0.7.254
switch the host to the tagged port of the switch
Explanations
ovs-vsctl add-br ovs-br0
Creates an almost empty virtual switch instance, there is only one port to which the eponymous internal interface ovs-br0 is connected.
ovs-vsctl set port ovs-br0 tag = 7
We configure this port as access-port for VLAN 7.
ovs-vsctl add-port ovs-br0 eth0
We add one more port to our switch, into which we switch the eth0 interface.
ovs-vsctl set port eth0 trunks = 7,10,20,1010,1020,30,1030
make this port trunk for the specified VLAN IDs. In principle, the trunks parameter can be omitted at all, then the port will skip all VLAN IDs.
ifconfig eth0 0
Zero the IP configuration for eth0. It will no longer be bound to the OS IP stack.
ifconfig ovs-br0 10.0.7.1/24 up
Instead of eth0, we fasten the internal interface ovs-br0 to the IP stack of OS.
ip r add default via 10.0.7.254
Well, do not forget to restore the routing table
Switch host to tagged switch port
We are online! (from)
We look at what has changed in the network settings
root @ sandbox: ~ # ovs-vsctl show
40952e4d-81ad-433b-b08b-f88ccd55f26a
    Bridge "ovs-br0"
        Port "ovs-br0"
            tag: 7
            Interface "ovs-br0"
                type: internal
        Port "eth0"
            trunks: [7,10,20,1010,1020,30,1030]
            Interface "eth0"
    ovs_version: "2.0.2"
root @ sandbox: ~ # ifconfig | grep -vE 'RX | TX | coll | inet6 | MTU'
eth0 Link encap: Ethernet HWaddr 00: 1b: 78: 9c: 2b: fc  
lo Link encap: Local Loopback  
          inet addr: 127.0.0.1 Mask: 255.0.0.0
ovs-br0 Link encap: Ethernet HWaddr 00: 1b: 78: 9c: 2b: fc  
          inet addr: 10.0.7.1 Bcast: 10.0.7.255 Mask: 255.255.255.0
virbr0 Link encap: Ethernet HWaddr 32: b9: dd: 38: 09: f5  
          inet addr: 192.168.122.1 Bcast: 192.168.122.255 Mask: 255.255.255.0
root @ sandbox: ~ # route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 10.0.7.254 0.0.0.0 UG 0 0 0 ovs-br0
10.0.7.0 0.0.0.0 255.255.255.0 U 0 0 0 ovs-br0
192.168.122.0 0.0.0.0 255.255.255.0 U 0 0 0 virbr0
Well, as a picture:
image
Figure 3: Install openvswitch and connect it to the IP stack of the OS instead of eth0.
The virbr0 switch interface will not be depicted in the future,  
he is not interesting to us and does not affect anything.
Nothing unexpected, everything is logical and intuitive.
Another nice point for those who have already begun to worry about where to place the startup scripts for applying this configuration. You don’t have to do anything special, the OVS configuration by the above ovs-vsctl commands is not only applied, but also automatically saved, so you don’t have to worry about the mismatch between the current and saved OVS configuration.
And the file / etc / network / interfaces we only need to update a little in connection with the replacement of the eth0 interface with ovs-br0:
root @ sandbox: ~ # cat / etc / network / interfaces | grep -v ^ #
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet manual
auto ovs-br0
iface ovs-br0 inet static
	address 10.0.7.1
	netmask 255.255.255.0
	network 10.0.7.0
	broadcast 10.0.7.255
	gateway 10.0.7.254
	# dns- * options are implemented by the resolvconf package, if installed
	dns-nameservers 10.0.1.1
But the switch is currently with only two ports, how can we connect our 5 virtual machines to it? There are at least 2 ways. The first, most obvious, is to use the ovs-vsctl add-port command to add a port (access or trunk - to choose from).
ovs-vsctl add-port ovs-br0 vlan10 tag = 10 - set interface vlan10 type = internal
- (two lines) is used to execute several ovs-vsctl commands in one line
Then it will be possible to select it directly in the virt-manager GUI to connect the network interface of the virtual machine. But we will go in a more scalable way. In this case, you do not need to create ports at all (as in the standard linux core bridge). Instead, you can create port groups for OVS. Each port group is designed to connect the VM to the corresponding VLAN. Unfortunately, their configuration from the virt-manager GUI is not available, you must manually prepare a simple XML file that describes the necessary port groups and then apply it via the libvirt API using the virsh command, as follows:
XML config for the configuration shown in Figure 1
ovs-network
We execute these commands:
vi /tmp/ovs-network.xml
virsh net-define /tmp/ovs-network.xml
virsh net-start ovs-network
virsh net-autostart ovs-network
Explanations
vi /tmp/ovs-network.xml
copy the above XML content to this file
virsh net-define /tmp/ovs-network.xml
configure a new network for KVM
virsh net-start ovs-network
run it
virsh net-autostart ovs-network
make its launch automatic
to remove an unnecessary network
virsh net-destroy ovs-network
virsh net-autostart --disable ovs-network
virsh net-undefine ovs-network
depict the resulting:
image
Figure 4: Created port groups for our VMs
Let's create a couple of VM1 and VM2 virtual machines in the virt-manager, and when creating, select Advanced options Virtual network 'ovs-network': Bridge network
For now, leave them turned off and
tweak the virtual machine config
virsh edit VM1
Find the interface section and add the portgroup parameter
Let's do the same for the second VM.
If we look now at the state of the network interfaces of the switch and the operating system, we will see that no changes have occurred. No ports were added on the switch, and no extra network interfaces appeared in the system.
Now run both VMs:
and check the state of the host network parameters again
root @ sandbox: ~ # ovs-vsctl show
40952e4d-81ad-433b-b08b-f88ccd55f26a
    Bridge "ovs-br0"
        Port "vnet0"
            tag: 10
            Interface "vnet0"
        Port "ovs-br0"
            tag: 7
            Interface "ovs-br0"
                type: internal
        Port "eth0"
            trunks: [7, 10, 20, 1010, 1020, 30, 1030]
            Interface "eth0"
        Port "vnet1"
            tag: 20
            Interface "vnet1"
    ovs_version: "2.0.2"
root @ sandbox: ~ # ifconfig | grep -vE 'RX | TX | coll | inet6 | MTU'
eth0 Link encap: Ethernet HWaddr 00: 1b: 78: 9c: 2b: fc  
lo Link encap: Local Loopback  
          inet addr: 127.0.0.1 Mask: 255.0.0.0
ovs-br0 Link encap: Ethernet HWaddr 00: 1b: 78: 9c: 2b: fc  
          inet addr: 10.0.7.1 Bcast: 10.0.7.255 Mask: 255.255.255.0
virbr0 Link encap: Ethernet HWaddr 32: b9: dd: 38: 09: f5  
          inet addr: 192.168.122.1 Bcast: 192.168.122.255 Mask: 255.255.255.0
vnet0 Link encap: Ethernet HWaddr fe: 54: 00: 5e: b9: b2  
vnet1 Link encap: Ethernet HWaddr fe: 54: 00: 7f: 40: d0  
As you can see, the ports of the corresponding port groups were added to the switch, and a couple of interfaces with MAC addresses corresponding to the VM were added to the system (when the VM is turned off, the corresponding ports and interfaces will disappear again).
image
Figure 5: launched a couple of VMs
I’ll also mention that 802.1q is not the only feature of Open vSwitch , with its help you can organize, for example, the bonding of two interfaces and something else .
That, in fact, is all. I hope this article helps someone decide to use Open vSwitch in their projects and just sandboxes instead of the standard linux bridge.

Also popular now: