BMaaS Part 3: Multi-tenancy

So far we have learned how to configure and provision baremetal nodes with OpenStack Ironic in Part 1 of the blog. We also configured our deployment to allow zero-touch discovery in Part 2. The next "LEGO" building block is to allow our tenants/project to isolate their baremetal resources. This unique OpenStack feature can take advantage of neutron to reach out to top of rack switches (TORs) via ml2 driver and dynamically assign a VLAN id to switch ports for corresponding nodes. 

With this functionality, your tenants can take ownership of the pool of baremetal nodes for the time of the project and not worry about other users of the cloud. When they are done, they simply delete instances and the baremetal resource return to the pool of nodes that can be consumed by other projects (and the networking is being set back to default).

Let's look at the short 7 minutes video:



There are currently 3 alternatives for configuring Multi-tenancy for baremetal in Ironic (ml2 drivers):

In this blog we are going to focus mostly on the one up top (generic-switch), since it's the one officially working with Queen release of OpenStack (OSP13). However you will also receive a sneak peak into ansible-networking driver that is going to be a driver of choice starting with OSP14 (Rocky) and beyond. I would probably recommend to avoid the third option. Even though you might be able to make it work, the drivers I have used are typically far behind current release cycles and are more buggy then the other 2 options.


I. Building new docker container for networking-generic-switch

The process for integrating networking-generic-switch and ansible-networking is very similar. Unfortunately OSP13 doesn't ship with driver being available inside neutron container, so we need to start with rebuilding our neutron container.

1. Create working director and download networking-generic-switch rpms. I have used RDO repository for Queens

(chrisj) [stack@undercloud ~]$ mkdir rebuild-image/

(chrisj) [stack@undercloud ~]$ cd rebuild-image/

2. Open RDO repo - - you will need to download follow RPMs into working directory:

  • python2-networking-generic-switch-1.0.0-1.el7.noarch.rpm
  • python2-scp-0.10.2-6.el7.noarch.rpm
  • python2-netmiko-1.4.1-1.el7.noarch.rpm

3. Find out the name and version of openstack-neutron-server docker container

(chrisj) [stack@undercloud rebuild-image]$ grep openstack-neutron-server ~/templates/overcloud_images.yaml 

4. Create Dockerfile with following content:

(chrisj) [stack@undercloud rebuild-image]$ cat Dockerfile 
USER root
# add packages for generic driver
ADD /python2-networking-generic-switch-1.0.0-1.el7.noarch.rpm /python2-networking-generic-switch-1.1.0-1.el7.noarch.rpm
ADD /python2-scp-0.10.2-6.el7.noarch.rpm /python2-scp-0.10.2-6.el7.noarch.rpm
ADD /python2-netmiko-1.4.1-1.el7.noarch.rpm /python2-netmiko-1.4.1-1.el7.noarch.rpm

#install generic driver
RUN yum -y install python2-networking-generic-switch-1.1.0-1.el7.noarch.rpm python2-netmiko-1.4.1-1.el7.noarch.rpm python2-scp-0.10.2-6.el7.noarch.rpm

5. Build and push docker container for neutron

(chrisj) [stack@undercloud rebuild_image]$ docker build -t .

(chrisj) [stack@undercloud rebuild_image]$ sudo docker push

6. Adjust overcloud_images.yaml to include a new neutron container name:

(chrisj) [stack@undercloud rebuild_image]$ sed -i 's/openstack-neutron-server:13.0-58/openstack-neutron-server:13.0-58-custom/g' ~/templates/overcloud_images.yaml


II. Integrating networking-generic-switch configuration into Director/TripleO

This should be an easy part. There are only few parameters that have to be included during the deployment. If you've followed my previous post, I am putting all the custom parameters into 'catch all' yaml file called Extra Config.yaml.

1. Configure multitenancy parameters in parameter_defaults:

(chrisj) [stack@undercloud ~]$ cat templates/ExtraConfig.yaml 

  # Ironic Multi-tenancy
  IronicProvisioningNetwork: baremetal
  NeutronMechanismDrivers: openvswitch,genericswitch
  IronicEnabledNetworkInterfaces: flat,noop,neutron
  IronicDefaultNetworkInterface: neutron
                      value: 'netmiko_arista_eos'
                      value: ''
                      value: 'admin'
                      value: 'secret'

                      value: '00:1c:73:0b:a3:df'

Note: I feel parameters used in here are self-explanatory. At minimum you need IP, user and password (or key) for the switch. The ngs_mac_address you can plug in the physical mac of the switch itself - this will help streamline consumption of newly discovered node, since Inspector will map mac learn from LLDP with the mac specified in ngs_mac_address.

If you anticipate to use multiple switches, simply create multiple entries with different genericswitch:<switch-name>/<parameter>

Note: In my example I am using Arista switch, however there is plethora of other switches available and documented here ->

2. You are now ready to re-deploy your openstack cloud and enjoy multi-tenancy function in overcloud

 time openstack overcloud deploy  --templates --stack chrisj \
  -r /home/stack/templates/roles_data.yaml \
  -n /home/stack/templates/network_data.yaml \

  -e /usr/share/openstack-tripleo-heat-templates/environments/services-docker/ironic.yaml \
  -e /usr/share/openstack-tripleo-heat-templates/environments/services-docker/ironic-inspector.yaml \
  -e /home/stack/templates/ExtraConfig.yaml \
  -e /home/stack/templates/overcloud_images.yaml 

3. (optional) If you don't take advantage of auto discovery described in one of the earlier blogs, you would need to define individual ironic ports and map them to corresponding switch and port-id. Example

openstack baremetal port delete <UUID>

openstack baremetal port create 90:b1:1c:03:9e:fd --node 028e4607-64fc-49bf-94de-0e0b2f48fcb4 --local-link-connection switch_id=00:1c:73:0b:a3:df --local-link-connection switch_info=arista --local-link-connection port_id=Et11 --pxe-enabled true




Here is a sneak peak into upcoming multi-tenancy driver that will be introduced together with RH OSP14 (Rocky) - networking-ansible. I happened to get my hands on re-based OSP13 (Queens) version and was able to validate it's functionality against my juniper ex2200 switch (this is old and slow switch not recommended for production)

Big thank you to Dan Radez for building special version of the driver that could be used with Queen release of OpenStack (OSP13)

The steps used to configure networking-ansible with Ironic are very similar to generic-switch.

1. First configure you neutron container. Follow the steps from above, with following change to Dockerfile

(chrisj) [stack@undercloud rebuild-image]$ cat Dockerfile 
USER root
# add packages for ansible network driver
ADD /python2-networking-ansible-2.0.0-1.el7_radez.noarch.rpm /python2-networking-ansible-2.0.0-1.el7_radez.noarch.rpm
ADD /python2-ansible-runner-1.0.5-1.el7.noarch.rpm /python2-ansible-runner-1.0.5-1.el7.noarch.rpm
ADD /python2-pexpect-4.6-1.el7.noarch.rpm /python2-pexpect-4.6-1.el7.noarch.rpm
ADD /ansible-role-openstack-ml2-2.0.0-1.el7_radez.noarch.rpm /ansible-role-openstack-ml2-2.0.0-1.el7_radez.noarch.rpm
ADD /ansible-2.5.2-1.el7.ans.noarch.rpm /ansible-2.5.2-1.el7.ans.noarch.rpm
ADD /python2-ptyprocess-0.5.2-3.el7.noarch.rpm /python2-ptyprocess-0.5.2-3.el7.noarch.rpm
ADD /python-daemon-1.6-5.1.el7.noarch.rpm /python-daemon-1.6-5.1.el7.noarch.rpm
ADD /python-lockfile-0.9.1-5.1.el7.noarch.rpm /python-lockfile-0.9.1-5.1.el7.noarch.rpm
#ADD /python-neutron-13.0.0-1.el7.noarch.rpm /python-neutron-13.0.0-1.el7.noarch.rpm
#ADD /python2-ryu-4.26-1.el7.noarch.rpm /python2-ryu-4.26-1.el7.noarch.rpm
#ADD /python-ryu-common-4.26-1.el7.noarch.rpm /python-ryu-common-4.26-1.el7.noarch.rpm
#ADD /python2-openvswitch-2.9.0-3.el7.noarch.rpm /python2-openvswitch-2.9.0-3.el7.noarch.rpm

#install ansible ml2 driver
RUN yum -y install python2-networking-ansible-2.0.0-1.el7_radez.noarch.rpm python2-ansible-runner-1.0.5-1.el7.noarch.rpm python2-pexpect-4.6-1.el7.noarch.rpm ansible-role-openstack-ml2-2.0.0-1.el7_radez.noarch.rpm python2-ptyprocess-0.5.2-3.el7.noarch.rpm ansible-2.5.2-1.el7.ans.noarch.rpm python-daemon-1.6-5.1.el7.noarch.rpm python-lockfile-0.9.1-5.1.el7.noarch.rpm


2. Configure multi-tenancy parameters in parameter_defaults:

  # Ironic Multi-tenancy
  IronicProvisioningNetwork: baremetal
  NeutronMechanismDrivers: openvswitch,ansible
  IronicEnabledNetworkInterfaces: flat,noop,neutron
  IronicDefaultNetworkInterface: neutron
                      value: 'junos'
                      value: ''
                      value: 'ansible'
                      value: 'secret'

                      value: 'False'

3. Re-deploy and enjoy multitenancy with Baremetal nodes


There are 2 Comments

I'm digging around looking for a bit more documentation on the ansible-role-openstack-ml2 package and how to get it into my tripleo build. I don't have any of these switches available, but there is Ansible roles for the switches I do have, namely the Onyx and Dellos9.

Any idea on the reasoning of not including more of the supported ansible managed switches?

Hey Justin,

I am not part of the development team for the ml2 ansible plugin. I would hit up radez on irc. I do know the development is driven by the customer demand and we have seen customer interest in Juniper, Cisco ad Arista .. so I think this is where the development will most likely focus on.

Add new comment

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
This question is for testing whether or not you are a human visitor and to prevent automated spam submissions.