Neutron分析(4)—— neutron-dhcp-agent
一.概述
neutron dhcp为租户网络提供DHCP服务,即IP地址动态分配,另外还会提供metadata请求服务。
3个主要的部件:
DHCP agent scheduler:负责DHCP agent与network的调度
DHCP agent:为租户网络提供DHCP的功能,提供metadata request服务。
DHCP driver:即dnsmasq,用于管理DHCP server。
二.REST API
neutron dhcp提供2类REST API接口,这两类API都是extension API。
一种是 Agent Management Extension API:
另一种是agent调度:
三.总体架构
根据整个dhcp处理的流程,dhcp模块主要由Neutron api、core plugin(如linux bridge plugin,ovs
plugin等)、dhcp agent scheduler、dhcp agent、dhcp driver(dnsmasq)构成。
架构图如下:
对应架构图中数字,有以下几个接口:
1.network/subnet/port的操作
2.agent management/agent scheduler的操作
3.network/subnet/port操作会发送rpc请求到dhcp agent。
4.agentscheduler db发送rpc请求到dhcp agent。
5.dhcp agent通过DhcpPluginApi发送rpc请求到core plugin,操作相应的数据库。
6.dhcp agent调用dhcp driver进行dhcp相关操作。
四.代码分析
neutron-dhcp-agent的入口为neutron.agent.dhcp_agent:main,跟l3-agent的启动方式是类似的,都是以Service启动;Manager类为DhcpAgentWithStateReport,汇报DHCPAgent的状态。
def main():
register_options()
common_config.init(sys.argv[1:])
config.setup_logging(cfg.CONF)
server = neutron_service.Service.create(
binary='neutron-dhcp-agent',
topic=topics.DHCP_AGENT,
report_interval=cfg.CONF.AGENT.report_interval,
manager='neutron.agent.dhcp_agent.DhcpAgentWithStateReport')
service.launch(server).wait()
DhcpAgentWithStateReport继承自DhcpAgent,用于汇报DHCPAgent的状态
if report_interval:
self.heartbeat = loopingcall.FixedIntervalLoopingCall(
self._report_state)
self.heartbeat.start(interval=report_interval)
_report_state就是从self.cache中取出当前状态,然后构造一个report_state的message发到q-plugin topic的消息队列上。
下面看下DhcpAgent初始化过程:
def __init__(self, host=None):
super(DhcpAgent, self).__init__(host=host)
self.needs_resync_reasons = []
self.conf = cfg.CONF
# Agent cache of the current network state
self.cache = NetworkCache()
self.root_helper = config.get_root_helper(self.conf)
# dhcp_driver currently is neutron.agent.linux.dhcp.Dnsmasq
self.dhcp_driver_cls = importutils.import_class(self.conf.dhcp_driver)
ctx = context.get_admin_context_without_session()
# init plugin rpc
self.plugin_rpc = DhcpPluginApi(topics.PLUGIN, # topic is q-plugin,提供DHCP相关的创建、查询、更新、删除接口
ctx, self.conf.use_namespaces)
# create dhcp dir to store dhcp info: /var/lib/neutron/dhcp/
# these files are used for Dnsmasq
dhcp_dir = os.path.dirname("/%s/dhcp/" % self.conf.state_path)
if not os.path.isdir(dhcp_dir):
os.makedirs(dhcp_dir, 0o755)
self.dhcp_version = self.dhcp_driver_cls.check_version()
# query existing_dhcp_networks from driver and then save them into self.cache
self._populate_networks_cache()
DhcpPluginApi创建了topic为q-plugin的处理方法,dhcp-agent外部可以通过DhcpAgentNotifyAPI来调用这些接口:
class DhcpAgentNotifyAPI(n_rpc.RpcProxy):
"""API for plugin to notify DHCP agent."""
BASE_RPC_API_VERSION = '1.0'
# It seems dhcp agent does not support bulk operation
VALID_RESOURCES = ['network', 'subnet', 'port']
VALID_METHOD_NAMES = ['network.create.end',
'network.update.end',
'network.delete.end',
'subnet.create.end',
'subnet.update.end',
'subnet.delete.end',
'port.create.end',
'port.update.end',
'port.delete.end']
neutron.agent.linux.dhcp.Dnsmasq
DhcpAgent通过self.dhcp_driver_cls = importutils.import_class(self.conf.dhcp_driver)注册了Dnsmasq这个Driver,并在需要的时候调用driver的相应接口:
def call_driver(self, action, network, **action_kwargs):
"""Invoke an action on a DHCP driver instance."""
LOG.debug(_('Calling driver for network: %(net)s action: %(action)s'),
{'net': network.id, 'action': action})
try:
# the Driver expects something that is duck typed similar to
# the base models.
driver = self.dhcp_driver_cls(self.conf,
network,
self.root_helper,
self.dhcp_version,
self.plugin_rpc) getattr(driver, action)(**action_kwargs)
return True
Dnsmasq会通过/var/lib/neutron/dhcp/目录下的配置文件启动dnsmasq进程,在DHCP更新的时候,更新这些配置文件并reload配置。
dnsmasq --no-hosts --no-resolv --strict-order
--bind-interfaces --interface=tap746570b9-2b --except-interface=lo
--pid-file=/var/lib/quantum/dhcp/3e16cd2f-c693-49b4-91a7-2a65912ec152/pid
--dhcp-hostsfile=/var/lib/quantum/dhcp/3e16cd2f-c693-49b4-91a7-2a65912ec152/host
--dhcp-optsfile=/var/lib/quantum/dhcp/3e16cd2f-c693-49b4-91a7-2a65912ec152/opts
--dhcp-script=/usr/bin/quantum-dhcp-agent-dnsmasq-lease-update --leasefile-ro
--dhcp-range=set:tag0,12.0.0.192,static,120s
--conf-file= --domain=openstacklocal
--bind-interfaces --interface=tap746570b9-2b 主要选项:
--except-interface=lo 使多个dnsmasq实例可以同时运行在同一台主机上并监听不同的interface
--dhcp-hostsfile=/var/lib/quantum/dhcp/3e16cd2f-c693-49b4-91a7-2a65912ec152/host 读取IP与虚拟机的静态映射关系,该文件改变后dnsmasq会自动重新加载,不需要重启
--dhcp-optsfile=/var/lib/quantum/dhcp/3e16cd2f-c693-49b4-91a7-2a65912ec152/opts 指定DNS服务器地址等选项
--dhcp-script=/usr/bin/quantum-dhcp-agent-dnsmasq-lease-update --leasefile-ro lease信息更新与通知
--dhcp-range=set:tag0,12.0.0.192,static,120s 重点在于static参数,该参数限制dnsmasq只能为dhcp-hostsfile包含的主机提供DHCP服务
既然Dnsmasq是根据/var/lib/neutron/dhcp/目录下的配置文件启动的,那么这些配置文件是如何创建和更新的呢?
(1)创建过程
dhcp agent在收到network_create_end后,会启动一个dhcp(dnsmasq)进程服务这个新网络。
(2)更新过程
- port_update_end
- port_delete_end
- subnet_update_end
- subnet_delete_end
上面这些通知消息在neturon rest API的前端实现中发出,具体代码在neutron.api.v2.base.py中
#Controller notifier_method = self._resource + '.create.end'
notifier_method = self._resource + '.delete.end'
notifier_method = self._resource + '.update.end'
可以看到针对每种resource(network, subnet, port),都会有相应的消息发出。dhcp agent根据这些消息来决定何时重新加载dnsmasp配置文件。
dhcp agent scheduler
通过dhcp agent scheduler,系统中可以部署多个dhcp agent:
1)增加可用性(HA, high availability),避免单点失败(SOF, single point of failure)
2)增加性能,多个dhcp agent可以安装在多台机器上,同时服务。
如何调度dhcp agent
调度算法通过network_scheduler_driver配置,默认是neutron.scheduler.dhcp_agent_scheduler.ChanceScheduler
class ChanceScheduler(object):
"""Allocate a DHCP agent for a network in a random way.
More sophisticated scheduler (similar to filter scheduler in nova?)
can be introduced later.
"""
可以看出,这个实现采用了随机分配算法。
如何调用dhcp agent scheduler
通过neutron.api.rpc.agentnotifiers.dhcp_rpc_agent_api.py中
def notify(self, context, data, method_name): 发送消息时,会调用
self._notify_agents,有代码
schedule_required = method == 'port_create_end'
if schedule_required:
agents = self._schedule_network(admin_ctx, network, agents)
可以看到当系统中有新的port创建后,会调用dhcp agent scheduler分配dhcp agent。
dhcp服务的启动
def after_start(self):
self.run()
LOG.info(_("DHCP agent started")) def run(self):
"""Activate the DHCP agent."""
# 根据系统中的网络配置,启动dhcp服务器进程(dnsmasq)。
# sync_state()在dhcp agent启动后运行一次。
self.sync_state()
# 周期性调用sync_state()
# dhcp agent会缓存一些网路的信息,通过该任务和neutron同步网络信息,更新本地缓存。
self.periodic_resync()
neutron的各种插件实现(core plugin or service plugin)都继承于db包下的对象,这些object实现了对相应资源数据模型的操作。
五.类图
六.数据库
DHCP agent的信息会存放在neutron数据库的agents表中:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
mysql> desc agents; +---------------------+---------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +---------------------+---------------+------+-----+---------+-------+ | id | varchar(36) | NO | PRI | NULL | | | agent_type | varchar(255) | NO | | NULL | | | binary | varchar(255) | NO | | NULL | | | topic | varchar(255) | NO | | NULL | | | host | varchar(255) | NO | | NULL | | | admin_state_up | tinyint(1) | NO | | NULL | | | created_at | datetime | NO | | NULL | | | started_at | datetime | NO | | NULL | | | heartbeat_timestamp | datetime | NO | | NULL | | | description | varchar(255) | YES | | NULL | | | configurations | varchar(4095) | NO | | NULL | | +---------------------+---------------+------+-----+---------+-------+ |
DHCP agent和network绑定关系存储在networkdhcpagentbindings中:
1
2
3
4
5
6
7
|
mysql> desc networkdhcpagentbindings; +---------------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +---------------+-------------+------+-----+---------+-------+ | network_id | varchar(36) | NO | PRI | NULL | | | dhcp_agent_id | varchar(36) | NO | PRI | NULL | | +---------------+-------------+------+-----+---------+-------+ |
agents和networkdhcpagentbindings通过dhcp agent id建立引用关系。
网络,子网和端口信息分别存储在数据库的networks,subnets和ports表中。dhcp agent需要获取这些信息生成dnsmasq的配置信息,并将这些信息存储在/var/lib/neutron/dhcp/目录下。 当neutron-server有需要添加/修改/删除dhcp相关配置时,会将消息发送到队列dhcp_agent.hostname或dhcp_agent_fanout_id,dhcp agent收到消息后进行相应dhcp的配置。
参考:
http://squarey.me/cloud-virtualization/neutron-dhcp-analyse.html
http://blog.csdn.net/matt_mao/article/details/19552381
http://blog.csdn.net/anyaas/article/details/17322085
Neutron分析(4)—— neutron-dhcp-agent的更多相关文章
- openstack Neutron分析(3)—— neutron-dhcp-agent源码分析
1.neutron dhcp3个主要部件分别为什么?2.dhcp模块包含哪些内容?3.Dnsmasq配置文件是如何创建和更新的?4.DHCP agent的信息存放在neutron数据库的哪个表中? 扩 ...
- Neutron分析(5)—— neutron-l3-agent中的iptables
一.iptables简介 1.iptables数据包处理流程 以本机为目的的包,由上至下,走左边的路 本机产生的包,从local process开始走左边的路 本机转发的包,由上至下走右边的路 简化流 ...
- Neutron分析(7)—— neutron-l3-agent HA solutions
1. keepalived vrrp/conntrackd High availability features will be implemented as extensions or driver ...
- Neutron分析(3)—— neutron-l3-agent
一.Layer-3 Networking Extension neutron l3作为一种API扩展,向租户提供了路由和NAT功能. l3扩展包含两种资源: router:在不同内部子网中转发数据包: ...
- Neutron分析(2)——neutron-server启动过程分析
neutron-server启动过程分析 1. /etc/init.d/neutron-server DAEMON=/usr/bin/neutron-server DAEMON_ARGS=" ...
- Neutron 理解 (1): Neutron 所实现的虚拟化网络 [How Netruon Virtualizes Network]
学习 Neutron 系列文章: (1)Neutron 所实现的虚拟化网络 (2)Neutron OpenvSwitch + VLAN 虚拟网络 (3)Neutron OpenvSwitch + GR ...
- Neutron 理解 (4): Neutron OVS OpenFlow 流表 和 L2 Population [Netruon OVS OpenFlow tables + L2 Population]
学习 Neutron 系列文章: (1)Neutron 所实现的虚拟化网络 (2)Neutron OpenvSwitch + VLAN 虚拟网络 (3)Neutron OpenvSwitch + GR ...
- Neutron 理解 (6): Neutron 是怎么实现虚拟三层网络的 [How Neutron implements virtual L3 network]
学习 Neutron 系列文章: (1)Neutron 所实现的虚拟化网络 (2)Neutron OpenvSwitch + VLAN 虚拟网络 (3)Neutron OpenvSwitch + GR ...
- Neutron 理解 (7): Neutron 是如何实现负载均衡器虚拟化的 [LBaaS V1 in Juno]
学习 Neutron 系列文章: (1)Neutron 所实现的虚拟化网络 (2)Neutron OpenvSwitch + VLAN 虚拟网络 (3)Neutron OpenvSwitch + GR ...
随机推荐
- 多平台下Modbus通信协议库的设计(一)
1.背景 1.1.范围 MODBUS 是 OSI 模型第 7 层上的应用层报文传输协议, 它在连接至不同类型总线或网络的设备之间提供客户机/服务器通信. 自从 1979 年出现工业串行链路的事实标准以 ...
- 使用 WordPress 插件模板开发高质量插件
WordPress 插件样板是标准化的,有组织的,面向对象的基础,用于构建高品质的 WordPress 插件.样板遵循编码标准和文件标准,所以你不必自己学习这些,根据注释编写代码即可. 官方网站 ...
- Titanium中调用ios组件时语言不是本地化的解决方法
用Titanium开发的ios应用中,当调用系统组件时,尽管手机已经设置了系统语言为中文,但那些组件的界面却仍为英文.比如调用iphone中的相册组件,其界面为: 那么怎么让它跟系统语言保持一致呢? ...
- [deviceone开发]-UI组件的动画示例
一.简介 自定义组件模版(头部,按钮,加减数量,加载,底部弹出,开关(文字/无文字),选项卡(2-4), radio)全部带自定义动画效果,需从组件商店中添加:do_Animator组件 二.效果图 ...
- Shapely中的几何图形操作
Geometric Objects object.area Returns the area (float) of the object. object.bounds Returns a (minx, ...
- [SharePoint] SharePoint 错误集 1
1. Delete a site collection · Run command : Remove-SPSite –Identity http://ent132.sharepoint.hp.com/ ...
- DevExpress VCL 13.1.4支持Delphi /C++Builder XE5
DevExpress VCL 13.1.4支持Delphi /C++Builder XE5 重大变化 ExpressLibrary dxHalfOfPi常数声明已经从cxGeometry单元移到了cx ...
- Web服务器具体开发流程
下面是我个人对Web服务器开发流程的一点理解,下面做出了大概的模型,实现了基本的功能,下面也有所有的代码可以提供参考: 一开始学的时候不要把网站想的太复杂了,把网站的流程和大概的原理框架搞清楚,在通过 ...
- Linux内核--C语言中内嵌汇编 asm __volatile__
在内嵌汇编中,可以将C语言表达式指定为汇编指令的操作数,而且不用去管如何将C语言表达式的值读入哪个寄存器,以及如何将计算结果写回C 变量,你只要告诉程序中C语言表达式与汇编指令操作数之间的对应关系即可 ...
- Android NDK目录介绍
交叉编译 在一个平台上去编译另一个平台上可以执行的本地代码 cpu平台---arm x86 mips 操作系统平台---windows linux mac os 原理 模拟不同平台的特性去编译代码 j ...