Neutron/LBaaS/CommonAgentDriver
LBaaS 通用代理驱动
原理
基于代理的 Haproxy-on-host 参考实现非常具体
- 使用 haproxy 时,每次从头部署整个负载均衡器配置比创建/更新/删除单独的组件更容易
- namespace 驱动在初始化时需要虚拟接口驱动,其他驱动可能具有其自身的特定参数
因此,统一参考代理实现是有用的,以便
- 使其适用于任何想要使用异步机制的驱动
- 拥有单一的 lbaas 代理类型,从而拥有单一的代理调度机制
所需条件
- 修订代理 API
- 修订代理加载设备驱动的机制
代理 API 变更
当前的 lbaas 代理 API 是针对 haproxy 的,但它不适用于其他负载均衡器,在这些负载均衡器中,每次从头部署整个配置是不可接受的。需要修改代理 API 以及设备驱动 API,使其几乎与插件驱动 API (quantum.services.loadbalancer.drivers.abstract_driver.LoadBalancerAbstractDriver) 相同。 此外,向代理的 create_pool() 调用应包含设备驱动引用(根据租户选择的服务提供程序)
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)
...
每次代理向插件发送请求以更新对象的状态(活动或错误)。 代理还将 pool_id 保存到其已知设备的缓存 (self.devices) 中,以确定使用哪个驱动程序来处理与该池相关的后续对象
...
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)
...
在代理中加载驱动
不同的设备驱动可能需要不同的初始参数(例如,haproxy 的 vif_driver,namespace_driver)。 当前的解决方案是在 lbaas_agent.ini 中为每个设备驱动程序提供特殊部分,以便在加载时读取这些参数。