Networking in OpenStack

For those who are coming from a background that includes working with hardware switches, routers, network design, and other on-premise or data center components, we want to go over a few concepts which should simplify the transition, or, for those of you familiar with other cloud platforms, provide a refresher on how these components work in OpenStack.

Network interfaces

All network-attached components have network interfaces (NICs). In OpenStack, these are called “ports”. OpenStack ports have a MAC address and are associated with an OpenStack network. Devices within OpenStack (routers, VMs, load balancers, etc.) have ports added that can be connected to allow traffic to flow between them at layer 2.

NOTE - ports are added to a device. Unlike in the physical world, where ports are typically pre-installed on a device, such as a server, switch, or router, ports in OpenStack can be created first, and then attached to or removed from a device on-demand.

In the physical world, we would connect ports with cables. In OpenStack, ports are more abstract. When defining a port, a network (layer 2) is assigned to this port. There is no action for this other than a definition in a database. Only when the port is attached to a device, does OpenStack trigger a configuration in the infrastructure. OpenStack ports also have some nice features such as port security, quality of service policies, etc. These services are activated at the time of port assignment to a device. On the back-end, this is typically the configuration of iptables and OpenVSwitch OpenFlow rules.

You can see all ports created by OpenStack by using the following command:

openstack port list

IP addresses

Unlike physical infrastructure, where network administrators assign static IPs or use DHCP servers to assign IP addresses to machines, OpenStack manages this for you. OpenStack keeps track of all IP addresses associated with a subnet you create, including static DHCP assignments in its DHCP servers. When provisioning a VM, you set the network interface to DHCP so it can receive DHCP information from OpenStack’s virtual DHCP servers. Behind the scenes, it is using Linux namespaces to accomplish this, launching a DHCP server process inside a Linux namespace dedicated to a layer 2 network.

By letting OpenStack manage IP addresses, you never have to worry about IP conflicts, plus you automatically get port security added to each OpenStack port, preventing layer 2 (MAC address) or layer 3 (IP address) spoofing from being possible.

Switches

Physical switches are typically basic layer 2 devices that learn the MAC address of every device that is plugged into a physical port. OpenStack does not really have a concept of a switch, rather it has the concept of a VLAN, which we call a “network”. A port is assigned to a network which defines what VLAN should be used when the port is attached to a device. You can create as many networks as you wish, since they are simply abstractions of a VLAN. Behind the scenes, VXLANs are used, and VXLAN/network mappings exist to correlate the two.

Since OpenStack manages both layer 2 and layer 3, it has a database of every port, and thus avoids having to learn anything. This eliminates that need for layer 2 broadcasting.

OpenStack honors all of the concepts of a layer 2 network, in that ports connected to two different networks cannot communicate directly, whereas ports that are connected to the same network can communicate freely (at layer 2).

To create a network, run this command:

openstack network create --mtu 1500 TestNetwork

Subnets

In the physical world, the concept of a subnet is abstract and only delineates the separation of IP address namespaces. On a network diagram, you typically create bubbles, one for each subnet, and avoid overlaps, placing machines inside these bubbles as appropriate.

In OpenStack, when subnets are defined, they are binded to a network (it is highly recommended to bind only a single subnet to a network to avoid assigning multiple IPs to a device). By defining a subnet in OpenStack, this triggers the creation of the DHCP servers mentioned above in the “IP addresses” section. Since the subnet is binded to a network, the subnet becomes active and DHCP responses are available for any device connected to its network.

Subnets are created easily with the following command:

openstack subnet create \
  --network "TestNetwork" \
  --subnet-range 192.168.99.0/24 \
  --gateway 192.168.99.254 \
  --allocation-pool start=192.168.99.1,end=192.168.100.253 \
  "TestSubnet"

Routers

In OpenStack, you typically only work with layer 3, so you will find that managing the network is pretty simple, where you create/update/delete subnets, attach or detach them from routers, and assign devices to ports, which subsequently expose these ports to subnet filters.

In the physical world, routers can be very complex devices, with one or more route tables, virtual routing domains, etc. In OpenStack, the concept of a router is pretty basic, performing one function - moving traffic between networks, filtered at layer 3 by the subnet definitions.

Routers are abstract objects, until you attach ports to them. So, you can create as many routers as you want with a command such as:

openstack router create "TestRouter"

To add a default route to the Internet, this command will add a port to the router that is connected to the upstream network at Genesis (ext-net):

openstack router set --external-gateway ext-net "TestRouter"

To add an internal router to the router, simply bind a subnet to the router using the following command:

openstack router add subnet TestSubnet TestRouter

This command creates a port on the router, a port which is associated with the network that the subnet is binded to.