Jump to: navigation, search

Neutron/LBaaS/CommonAgentDriver

< Neutron‎ | LBaaS
Revision as of 11:34, 6 August 2013 by Oleg Bondarev (talk | contribs)

LBaaS Common Agent-based Driver

Rationale

Haproxy-on-host reference implementation which is using agents is quite specific:

  • with haproxy it is easier to deploy the whole loadbalancer config from scratch every time then to create/update/delete separate components
  • namespace driver needs virtual interface driver on init, other drivers may have their own specific parameters


So it is useful to unify reference agent implementation to:

  • make it suite any driver which wants to use async mechanism
  • have single lbaas agent type and hense single agent scheduling mechanism


What is required

  1. Revision of agent API
  2. Revision of agent loading device driver(s) mechanism
Agent API changes

Current lbaas agent API is specific for haproxy but it doesn't fit well with other loadbalancers where deploying the whole config from scratch every time is unacceptable. Need to modify agent API as well as device driver API to make them almost a duplication of plugin driver API (quantum.services.loadbalancer.drivers.abstract_driver.LoadBalancerAbstractDriver). In addition a create_pool() call to agent should contain a device driver reference (according to service provider choosen by tenant):

 class LbaasAgentManager(periodic_task.PeriodicTasks):
 ...
   def create_pool(self, context, pool, driver_name):
       if driver_name not in self.device_drivers:
           LOG.error(_('No device driver on agent: %s.') % driver_name)
           return
       driver = self.device_drivers[driver_name]
       try:
           driver.create_pool(pool)
           self.plugin_rpc.update_status('pool', pool['id'], constants.ACTIVE)
           self.devices[pool['id']] = driver_name
       except Exception:
           LOG.exception(_('create pool failed on device driver'))
           self.plugin_rpc.update_status('pool', pool['id'], constants.ERROR)
 ...

Every time agent sends a request to plugin to update status of the object (active or error). Also agent saves pool_id to its cache of known devices (self.devices) to determine which driver to use for handling subsequent objects related to that pool: ...

   def _get_driver(self, pool_id):
       if pool_id not in self.devices:
           msg = _('Unknown device with pool_id %s') % pool_id
           LOG.error(msg)
           raise n_exc.Invalid(msg)
       driver_name = self.devices[pool_id]
       return self.device_drivers[driver_name]
   def create_vip(self, context, vip):
       driver = self._get_driver(vip['pool_id'])
       try:
           driver.create_vip(vip)
           self.plugin_rpc.update_status('vip', vip['id'], constants.ACTIVE)
       except Exception:
           LOG.exception(_('create vip failed on device driver'))
           self.plugin_rpc.update_status('vip', vip['id'], constants.ERROR)

...

Loading drivers in agent

Different device drivers may require different initial parameters (like vif_driver for haproxy namespace_driver). Current solution will be to have special sections in lbaas_agent.ini for every device driver so that it can read those parameters itself when loading.