声明:
本博客欢迎转载,但请保留原作者信息,并请注明出处!
作者:林凯
团队:华为杭州OpenStack团队
在OpenStack Grizzly版本中,Neutron(当时叫Quantum)组件引入了一个新的网络服务:LoadBalancer(LBaaS),关于LoadBalancer的框架和基础知识方面网上已经有了一些好文章,在此不再赘述。本文将对LoadBalancer的代码流程及实现进行初步解析,肯定会有错误和不严谨的地方,需要大家给予指正。
首先我们来看下我们在创建这些pool、member、healthmonitor和vip的时候,代码都做了哪些事情。
# pool作为LB v1的根对象,是工作流的起点 def create_pool(self, context, pool): provider_name = self._get_provider_name(context, pool['pool']) # DB中创建pool对象 p = super(LoadBalancerPlugin, self).create_pool(context, pool) self.service_type_manager.add_resource_association( context, constants.LOADBALANCER, provider_name, p['id']) #need to add provider name to pool dict, #because provider was not known to db plugin at pool creation p['provider'] = provider_name driver = self.drivers[provider_name] try: # 调用默认provider中的驱动创建pool driver.create_pool(context, p) except loadbalancer.NoEligibleBackend: # that should catch cases when backend of any kind # is not available (agent, appliance, etc) self.update_status(context, ldb.Pool, p['id'], constants.ERROR, "No eligible backend") raise loadbalancer.NoEligibleBackend(pool_id=p['id']) return p
在neutron.conf中可以看到默认的设置为:
service_provider=LOADBALANCER:Haproxy:neutron.services.loadbalancer.drivers.haproxy.plugin_driver.HaproxyOnHostPluginDriver:default
class HaproxyOnHostPluginDriver(agent_driver_base.AgentDriverBase): device_driver = namespace_driver.DRIVER_NAME
def create_pool(self, context, pool): # 首先通过agent scheduler分配agent agent = self.pool_scheduler.schedule(self.plugin, context, pool, self.device_driver) if not agent: raise lbaas_agentscheduler.NoEligibleLbaasAgent(pool_id=pool['id']) self.agent_rpc.create_pool(context, pool, agent['host'], self.device_driver)
def schedule(self, plugin, context, pool, device_driver): # 为pool分配一个active的loadbalancer agent,如果其上没有已经使能的agent with context.session.begin(subtransactions=True): lbaas_agent = plugin.get_lbaas_agent_hosting_pool( context, pool['id']) if lbaas_agent: LOG.debug(_('Pool %(pool_id)s has already been hosted' ' by lbaas agent %(agent_id)s'), {'pool_id': pool['id'], 'agent_id': lbaas_agent['id']}) return # 获取active的agent active_agents = plugin.get_lbaas_agents(context, active=True) if not active_agents: LOG.warn(_('No active lbaas agents for pool %s'), pool['id']) return # 根据device_driver筛选候选的agent candidates = plugin.get_lbaas_agent_candidates(device_driver, active_agents) if not candidates: LOG.warn(_('No lbaas agent supporting device driver %s'), device_driver) return # 随机选取一个合适的候选agent chosen_agent = random.choice(candidates) # 与pool进行绑定 binding = PoolLoadbalancerAgentBinding() binding.agent = chosen_agent binding.pool_id = pool['id'] context.session.add(binding) LOG.debug(_('Pool %(pool_id)s is scheduled to ' 'lbaas agent %(agent_id)s'), {'pool_id': pool['id'], 'agent_id': chosen_agent['id']}) return chosen_agent
device_driver = namespace_driver.DRIVER_NAME
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) self.plugin_rpc.update_status('pool', pool['id'], constants.ERROR) return # 获取相应的driver(根据设置默认为HaproxyNSDriver) driver = self.device_drivers[driver_name] try: driver.create_pool(pool) except Exception: self._handle_failed_driver_call('create', 'pool', pool['id'], driver.get_name()) else: self.instance_mapping[pool['id']] = driver_name # 之后更新数据库中的状态 self.plugin_rpc.update_status('pool', pool['id'], constants.ACTIVE)
def create_pool(self, pool): # nothing to do here because a pool needs a vip to be useful # 当没有vip的情况下,不做操作。 Pass
OpenStack Neutron LoadBalance源码解析(一)
原文地址:http://blog.csdn.net/canxinghen/article/details/42144347