With Open vSwitch (OVS) support in OpenNebula it was natural to work on using OpenFlow to enable advanced network services. With OVS support the door was opened for a programmable network and a merge of OpenNebula networking paradigm with the area of software defined networking.
OpenFlow is a network controller that OVS switches can use to enforce network rules. The rules control packet flows instead of individual packets and can be created at any layer of the networking stack.
In our recent work we deployed an OpenFlow controller (NOX) on our cloud at Clemson University. The Onecloud is made of a couple KVM hypervisors that use OVS switches and a single NOX controller. The neat features that we implemented are an implementation of Amazon’s Elastic IP and Security Groups. We modified the econe server in OpenNebula to expose the EC2 query API for these services and we wrapped an xml-rpc server on top of NOX to directly set the proper network rules in the controller, which in turn forwarded them to the OVS switches on the hypervisors. The figure below summarizes this setup:
What are these rules? For elastic IP, these rules just re-write all packets at L3 and answer to ARP requests so that a public IP leased via OpenNebula can be associated with an instance previously started on a different vnet. For security groups, more changes were required on the OpenNebula side, like an extension of the database tables, but the rules are now at L4, allowing flows to a specific port of an instance.
The end result is that you can now do something like this (using boto) with an OpenNebula cloud:
#Lease and IP address
address = conn.allocate_address()
# Associate IP with VM
# Remove Elastic IP from the instance it is associated with
# Return the Elastic IP address back to address pool
For security groups, if one started an instance with all ports blocked, to open port 22 one would proceed exactly the same way than with Amazon EC2:
# Start instance in a security group
reservation = image.run(instance_type="m1.small", security_groups=["sg-000007"])
# Create security group
sg = conn.create_security_group("Test Group", "Description of Test Group")
# Allow access from anyone for HTTP
sg.authorize("tcp", 80, 80, "0.0.0.0", None)
# Allow SSH access from private subnet
sg.authorize("tcp", 22, 22, "10.10.1.0/24", None)
Sebastien Goasguen, Greg Stabler, Aaron Rosen and K. C Wang