Statement:
This blog welcome reprint, but please keep the original author information, and please specify the source!
Lin Kai
Team: Huawei Hangzhou OpenStack Team
In the Openstackgrizzly version, the Neutron (then called quantum) component introduced a new network service: LoadBalance (LBaaS), the framework and fundamentals of loadbalance have some good articles on the web, Don't dwell on it here. This article will loadbalancer code flow and implementation of the preliminary analysis, there will be errors and not rigorous place, need to be corrected.
Recommend some basic knowledge of the article to everyone, after you read the source code will be more simple.
http://blog.csdn.net/quqi99/article/details/9898139
Http://www.cnblogs.com/feisky/p/3853734.html
http://www.ustack.com/blog/neutron_loadbalance/
The basic use steps of the Neutron LoadBalancer are:
1) The tenant creates a pool with an initial number of member of 0;
2) The tenant creates one or more member within the pool
3) Tenants create one or more Health Monitor
4) The Tenant associates the health monitors with the pool
5) Tenants create VIP with pool
First, let's look at what the code did when we created the pool, member, HealthMonitor, and VIP.
Figure 1 LoadBalance Overall process framework
Requests from the tenant to create a pool are sent first to lbaasplugin for processing, so our parsing of the code begins here as well. In the/neutron/services/loadbalancer/plugin.py we can see the corresponding Create_pool and other methods:
# pool as the root object of the LB v1, is the starting point of the workflow Def create_pool (self, Context, pool): provider_name =self._get_provider_name (Context, pool[' Pool ']) # DB Create pool object p = Super (loadbalancerplugin,self). Create_pool (context, pool) Self.servic E_type_manager.add_resource_association (context, constants. LoadBalancer, provider_name, p[' id ') #need to add provider name to Pooldict, #because provider W As not known to dbplugin at pool creation p[' provider '] = provider_name Driver = Self.drivers[provider_name] Try: # Call the drive in the default provider to create the pool Driver.create_pool (context, p) except LoadBalancer. Noeligiblebackend: # That should catch cases whenbackend of any kind # are not available (agent,appli ance, etc) self.update_status (context,ldb. Pool, p[' ID '], constants. ERROR, "noeligible backend") RaiseloadbalAncer. Noeligiblebackend (pool_id=p[' id ')) return p
where Driver.create_pool (context,p) is the key method
Driver =self.drivers[provider_name], the corresponding driver is called according to the provider settings in the configuration file.
In neutron.conf, you can see that the default setting is: Service_provider=loadbalancer:haproxy: Neutron.services.loadbalancer.drivers.haproxy.plugin_driver. Haproxyonhostplugindriver:default
So jump to the/neutron/services/loadbalancer/haproxy/plugin_driver.py:
Class Haproxyonhostplugindriver (Agent_driver_base. Agentdriverbase): device_driver =namespace_driver. Driver_name
There is no Create_pool method in this class, so go to his parent class agentdriverbase to see:
def create_pool (self, Context, pool): # First the agent Agent Scheduler is assigned =self.pool_scheduler.schedule ( Self.plugin, context, pool, self.device_driver) if not agent: Raiselbaas_agentscheduler. Noeligiblelbaasagent (pool_id=pool[' id ') self.agent_rpc.create_pool (Context,pool, agent[' host '), Self.device_driver)
Here first through the Agent scheduler Distribution Agent, see the specific implementation method:
def schedule (self, plugin, context, pool, device_driver): # Assigns an active loadbalanceragent to the pool if it does not have an enabled 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) Shas already been hosted ' By Lbaas agent% (agent_id) s '), {' pool_id ':p ool[' id '], ' agent_id ': lbaas_agent[' id ']}) return # Gets the active agent active_agents =PL Ugin.get_lbaas_agents (context, active=true) if not Active_agents:LOG.warn (_ (' No active lbaasage NTS for Pool%s '), pool[' id ']) return # Filter agent candidates =plugin based on Device_driver . Get_lbaas_agent_candidates (Device_driver, active_agents) If not candidates: Log.warn (_ (' No Lbaas agentsupporting device driver%s '), Device_driver) Return # Randomly Select a suitable candidate Agent Chosen_agent =random.choice (candidates) # bind to Pool Binding =poolloadbalanceragentbinding () Binding.agent = chosen_agent binding.pool_id = pool[' id ' ] Context.session.add (binding) Log.debug (_ (' Pool% (pool_id) s isscheduled to ' ' Lbaas agent% (agent_id) s '), {' pool_id ': pool[' id '], ' agent_id ': chosen_agent[' I d ']}) return chosen_agent
We were just in the plugindriver of Haproxy, we know:
Device_driver = Namespace_driver. Driver_name
So the agent selected according to Device_driver is the namespace_driver of Haproxy, and the request to create the pool is forwarded to Device_driver (Haproxynsdriver) via the agent This process is not directly one step, where the agent sends an RPC asynchronous request, at which point Agent_manager receives the request
def create_pool (self, context, pool, driver_name): if driver_name not inself.device_drivers: log.error (_ (' No Device driver Onagent:%s. '), driver_name) self.plugin_rpc.update_status (' pool ', pool[' id '), constants. ERROR) return # get the corresponding driver (default to Haproxynsdriver according to settings) 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 # Update the state in the database self.plugin_rpc.update_status (' pool ', pool[' id '), constants. ACTIVE)
The Create_pool function in Haproxynsdriver is called here, and the corresponding method is found in the namespace_driver.py of Haproxy:
def create_pool (self, Pool): # Anything to does here because a poolneeds a VIP to be useful # when no VIP is in the case, do not do the operation. Pass
The creation process of Member,healthmonitor and VIP is similar, and can be analyzed by reference to this process.
At this point, Neutron loadbalance Source parsing the first part of the content is over, the next part of the content please look forward to.
OpenStack Neutron loadbalance Source Parsing (i)