OpenStack源码分析【2021-12-25】

2021SC@SDUSC
为什么有人圣诞节还要写作业啊

概述

Neutron dhcp实现了为虚机提供动态分配IP的服务,dhcp功能由neutron-server和dhcp-agent配合实现。其中server负责接收请求并向agent发送网络、子网、端口等数据;agent接收数据,创建、配置dhcp实例。社区的dhcp功能由dnsmasq软件实现,即由该软件充当dhcp server。(Neutron dhcp实现

聚焦源码

neutron-18.1.1/neutron/scheduler/dhcp_agent_scheduler.py

这个文件中一共有五个类,分别是AutoScheduler, ChangeScheduler, WeightScheduler, AZAwareWeightScheduler和DhcpFilter。其中,DhcpFilter在前面四个类的初始化函数中被初始化,可以认为,DhcpFilter是它们的一部分。

例如:

class WeightScheduler(base_scheduler.BaseWeightScheduler, AutoScheduler):

    def __init__(self):
        super(WeightScheduler, self).__init__(DhcpFilter())

ChangeScheduler和WeightScheduler在本文件中没有提供方法,但它们继承自各自的基类,这些基类在neutron-18.1.1/neutron/scheduler/base_scheduler.py中提供了select方法,并描述了它们的调度策略:

BaseChanceScheduler()随机选择agent,BaseWeightScheduler()基于负载选择agent;AZAwareWeightScheduler选择策略如下:

选择为network分配了最少agent的AZ;对于分配了相同数目agent的AZ,优先选择负载最少的AZ。

然后我们来看DhcpFilter做了什么。

它提供了3个共有函数:

get_vacant_network_dhcp_agent_binding_index(self, context, network_id, force_scheduling)
bind(self, context, agents, network_id, force_scheduling=False)
filter_agents(self, plugin, context, network)

第一个函数返回一个空的绑定索引,并且返回它是否存在。因为每一个NetworkDhcpAgentBinding有一个在network_id中不重复的binding_index,所以创建binding的时候,我们需要找到一个空的并且没有用过的binding_index来用。

def get_vacant_network_dhcp_agent_binding_index(
        self, context, network_id, force_scheduling):
    num_agents = agent_obj.Agent.count(
        context, agent_type=constants.AGENT_TYPE_DHCP)
    num_agents = min(num_agents, cfg.CONF.dhcp_agents_per_network)
    bindings = network.NetworkDhcpAgentBinding.get_objects(
        context, network_id=network_id)
    return base_scheduler.get_vacant_binding_index(
        num_agents, bindings, ndab_model.LOWEST_BINDING_INDEX,
        force_scheduling=force_scheduling)

第二个函数将network和agent绑定,关键做法是调用network.NetworkDhcpAgentBinding(context, dhcp_agent_id=agent_id, network_id=network_id, binding_index=binding_index).create()

为agents中的每一个创建一个绑定关系。

def bind(self, context, agents, network_id, force_scheduling=False):
    # customize the bind logic
    bound_agents = agents[:]
    for agent in agents:
        binding_index = self.get_vacant_network_dhcp_agent_binding_index(
            context, network_id, force_scheduling)
        if binding_index < ndab_model.LOWEST_BINDING_INDEX:
            LOG.debug('Unable to find a vacant binding_index for '
                      'network %(network_id)s and agent %(agent_id)s',
                      {'network_id': network_id,
                       'agent_id': agent.id})
            continue

        # saving agent_id to use it after rollback to avoid
        # DetachedInstanceError
        agent_id = agent.id
        try:
            network.NetworkDhcpAgentBinding(
                 context, dhcp_agent_id=agent_id,
                 network_id=network_id,
                 binding_index=binding_index).create()
        except exceptions.NeutronDbObjectDuplicateEntry:
            # it's totally ok, someone just did our job!
            bound_agents.remove(agent)
            LOG.info('Agent %s already present', agent_id)
        LOG.debug('Network %(network_id)s is scheduled to be '
                  'hosted by DHCP agent %(agent_id)s with binding_index '
                  '%(binding_index)d',
                  {'network_id': network_id,
                   'agent_id': agent_id,
                   'binding_index': binding_index})
    super(DhcpFilter, self).bind(context, bound_agents, network_id)

第三个函数返回可以承载网络的一组agents。它返回三个值:n_agents是应该被调度的agents个数,如果n_agents=0,说明所有网络都得到了代理,或者没有剩余agent能够再承载网络了;hostable_agents是可以承载网络的agent的集合;hosted_agents是已经承载了网络的agent的集合。

def filter_agents(self, plugin, context, network):
    agents_dict = self._get_network_hostable_dhcp_agents(
                                plugin, context, network)
    if not agents_dict['hostable_agents'] or agents_dict['n_agents'] <= 0:
        return {'n_agents': 0, 'hostable_agents': [],
                'hosted_agents': agents_dict['hosted_agents']}
    return agents_dict
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值