Neutron dhcp实现了为虚机提供动态分配IP的服务,dhcp功能由neutron-server和dhcp-agent配合实现。其中server负责接收请求并向agent发送网络、子网、端口等数据;agent接收数据,创建、配置dhcp实例。社区的dhcp功能由dnsmasq软件实现,即由该软件充当dhcp server。
表1 neutron-server所使用的dhcp配置(/etc/neutron/neutron.conf)
配置项 |
用途 |
默认值 |
dhcp_lease_duration |
IP租期,-1为IP永久有效 |
86400 (24小时) |
dhcp_agent_notification |
是否向dhcp-agent发送消息 |
true |
network_scheduler_driver |
Dhcp-agent的调度算法 |
neutron.scheduler.dhcp_agent_scheduler.ChanceScheduler |
dhcp_load_type |
调度dhcp-agent时的依据,一般使用WeightScheduler算法时使用的配置 |
networks(number of networks hosted on the agent) |
allow_automatic_dhcp_failover |
Dhcp down时,网络时候重新调度 |
true |
dhcp_agents_per_network |
为网络提供dhcp服务的dhcp-agent数量,通过冗余的方式,为一个网络提供多个dhcp namespace |
1 |
表2 dhcp-agent使用的配置(/etc/neutron/ dhcp_agent.ini)
配置项 |
用途 |
默认值 |
dhcp_driver |
底层实现dhcp功能所用的驱动 |
neutron.agent.linux.dhcp.Dnsmasq |
interface_driver |
为dhcp提供二层接口的驱动 |
neutron.agent.linux.interface.BridgeInterfaceDriver |
在创建子网的时候,用户通过选择dhcp功能,来决定是否为网络创建dhcp-server。
图1 创建带dhcp功能的子网
图2展示了在Neutron-server中涉及创建子网、dhcp功能的类,主要有Controller类和Ml2plugin类。其中Controller类中包含了一个_plugin类,该类是Ml2plugin。Controller主要执行用户发送的rest请求,对于创建二层资源的操作,一般会调用Ml2plugin的create_RESOURCE方法(RESOURCE有network、subnet、port等)。对于创建子网的请求,最终会调用ml2plugin的create_subnet函数。
图2 neutron-server中与dhcp功能有关的类
如图3展示了创建子网的流程,主要包括controller接受rest请求并调用ml2plugin的具体函数;ml2plugin对象操作数据库,创建相关资源的数据;选择一定数量的dhcp-agent,向它们发送subnet_create_end消息。
图3 创建子网的过程
实现dhcp功能的时候,还涉及到dhcp-agent的调度问题,这是因为在一套openstack系统中,为了保证dhcp功能的可靠,需要部署多个dhcp-agent。Ml2plugin根据配置的dhcp_agents_per_network值和实际可用的dhcp-agents数量(数据库中active的agent个数),确定能够实现dhcp功能的agent个数(Min(dhcp_agents_per_network,active agents)),然后使用调度算法,决定最终在哪些dhcp agent启动dhcp实例。常用的调度算法有:
ChanceScheduler:随机选择可用的agents。
WeightScheduler:选择负载最少的agents。
Dhcp-agent接受到subnet_create_end消息,首先会向neutron-server请求子网所属网络的信息,然后创建qdhcp namespace并启动dnsmasq进程。图4展示了这一过程中涉及到的类,图5展示了这一过程的主要调用流程。
图4 dhcp-agent类结构
图5 dhcp-agent创建dnsmasq的流程
Dhcp-agent根据dhcp_driver配置,加载实现dhcp-server功能的驱动;根据interface_driver的配置,加载为dhcp提供二层服务的驱动,这里我们使用ovsinterfacedriver,它会执行ovs命令,配置dhcp namespace的tap端口。
neutron的dhcp功能借助于dnsmasq软件和networknamespace技术。
Dnsmasq是一个开源的轻量级DNS和DHCP服务器,针对小型局域网设计,资源占用低,易于配置。
Network namespace主要实现了网络资源的隔离,网络资源包括网络设备、IPv4和IPv6协议栈、IP路由表、防火墙、socket等。给一个或多个进程私有的网络资源。
使用namespace实现dhcp的原因是,使一个dnsmasq进程独立的为一个租户网络提供dhcp服务。
Dhcp-agent收到neutron-server的消息后,会构建一个名为qdhcp-networkid的namespace,并使用veth pair将其和ovs br-int网桥相连。图6展示了一个dhcpnamespace。
图6 dhcp namespace
最后在namespace中启动一个dnsmasq程序:
ip netns exec qdhcp-3d722176-f319-4afe-b26b-025fead744a1dnsmqsqdnsmasq --no-hosts --no-resolv --strict-order --bind-interfaces--interface=tap523e7156-00 --except-interface=lo--pid-file=/var/lib/neutron/dhcp/3d722176-f319-4afe-b26b-025fead744a1/pid --dhcp-hostsfile=/var/lib/neutron/dhcp/3d722176-f319-4afe-b26b-025fead744a1/host--addn-hosts=/var/lib/neutron/dhcp/3d722176-f319-4afe-b26b-025fead744a1/addn_hosts--dhcp-optsfile=/var/lib/neutron/dhcp/3d722176-f319-4afe-b26b-025fead744a1/opts--dhcp-leasefile=/var/lib/neutron/dhcp/3d722176-f319-4afe-b26b-025fead744a1/leases--dhcp-range=set:tag1,10.190.91.0,static,infinite --dhcp-lease-max=256--conf-file=/etc/neutron/dnsmasq-neutron.conf
其中bind-interfaces指dnsmasq进程监听的端口,进程可以通过该端口接受和发送dhcp报文。host文件包含了虚机的ip和mac对应信息,为虚机dhcp请求提供了依据。图7展示了一个host文件的内容。
图7 dnsmasq host文件
图8展示了一个dnsmasq进程。
图8 dnsmasq进程
当新建port时,dhcp-agent会在相应的dnsmasq host文件中增加一条记录,并给dnsmasq进程发送一个HUP信号,dnsmasq会重新读取host文件。当VM发出DHCP-request后,dnsmasq根据host文件的内容为VM分配IP地址。