Openstack Neutron Dhcp 没法获取IP地址问题

原文地址:css

http://www.choudan.net/2014/03/10/OpenStack-Neutron-DHCP-%E9%97%AE%E9%A2%98.html
html


OpenStack在网络上的坑一个接一个,层出不穷,仍是接着上面的两篇博客中描述的网络环境,OpenStack Havana + Neutron + LinuxBridge + 多个vlan。在前期测试阶段,经过dashboard建立一两台虚拟机,查看其网络状况,由于有了以前的打磨,这种状况下虚拟机获取ip地址,访问外网,经过浮点ip地址访问虚拟机都已不是个事。然而,若是尝试去反复批量的建立虚拟机,删除虚拟机,十有八九,网络又要开始让你忧伤了。一次批量建立的虚拟机中间可能大部分没法获取到ip地址,若虚拟机是多网卡的,还多是部分网卡获取到了ip地址,部分没法获取。node


这个状况,简单的描述是:使用neutron dhcp agent来分配ip,在反复屡次的批量建立虚拟机删除虚拟机的场景下,虚拟机很大几率没法获取到ip地址。在dnsmasq的日志中,记录了这一现象的缘由:网络

dnsmasq-dhcp[13578]: DHCPDISCOVER(ns-ea864f58-69) 192.168.101.14 fa:16:3e:07:e2:8d no
address available

日志记录的缘由是no address available。实际上该网段还有大量可用的ip地址。在尝试解决的过程当中,重启虚拟机的网络或重启虚拟机都无效,但能够经过简单的重启neutron-dhcp-agent来解决问题。可是,当下次重复上面的操做时,问题又出现。less


google后发现社区已经在讨论这一问题了,能够看下面的帖子:测试

  • DHCP problem in Grizzly : 这个帖子有点长,前面的回合在定位问题,后面的回合将问题锁定在dnsmasq这个组件上,可是没有确证,而后就没有而后了。
  • DHCP Problem in Grizzly : 这个和上面的同样,可是有结果,能够直接拖到最后。时隔一个多月,大神终于找到了真正的缘由。google

  • Dnsmasq-disucss Possible Bug: DHCPDISCOVER no address available: 开始时怀疑是dnsmasq的问题,就报告到dnsmasq社区,讨论了一番,dnsmasq的开发者以为这问题是openstack的代码致使的。可是这个帖子能够对neutron-dhcp-agent的工做方式有个深刻了解DNSMASQ工做方式

从第三个连接,咱们了解到neutron会建立dnsmasq daemon来提供dhcp服务,dnsmasq的工做方式主要是:当有新的ip地址项(能够查看/var/lib/neutron/dhcp/xxx/hosts文件)添加到hosts文件来,或者旧的ip地址项从该文件删除后,那么neutron就会像dnsmasq发送一个SIGHUP的信号给dnsmasqd,该daemon则从新读取该hosts文件,这样就能够完成client的dhcp-discover了。spa

没法获取IP地址缘由.net

而当dhcp-agent负载很重时,就是须要不停的更新hosts文件,还有ip地址的lease更新,这样就致使dhcp-agent发送给neutron-server的report延迟了,从而进一步致使neutron server认为dhcp-agent已经down了,就不会将port creation发送给dhcp-agent,最终,dnsmasq host file没有获得更新,就没法为新建立的虚拟机提供ip地址了。日志

解决办法:

根据上面的帖子,我尝试更改了neutron.conf中的report_interval=15(默认值是4) agent_down_time = 30(默认值是9),而后重启neutron的服务,通过大量测试,如今变的正常了。

# Seconds to regard the agent as down; should be at least twice
# report_interval, to be sure the agent is down for good
# agent_down_time = 9


# seconds between nodes reporting state to server; should be less than # agent_down_time, best if it is half or less than agent_down_time # report_interval = 4