Neutron DHCP-Agent问题分析定位(6)

 作者:闫兴安

1.5.11  测试dhcp-agent的同步-停掉mysql

启动3个dhcp-agent,对应节点分别称为network1, network2, network3。

将neutron.conf中的dhcp_agents_per_network配置为2。重启neutron-server。

创建网络,观察网络创建成功,dhcp-port创建成功。

neutron port-show,看到dhcp port绑定在network2和network3上。

停掉全部mysqld,使得neutron-server无法更新port的属性。

 

查看dhcp-agent log,


出现无法report state的错误,即上报agent状态失败。

 

此时重启network1的dhcp-agent,因为无法上报agent状态,无法开始同步。

等待约10分钟,恢复1个mysqld服务。

查看dhcp-agent日志,发现并没有任何新的日志出现。【这里有bug】


neutron agent-list查看,各个agent已经为up状态。

 

此时查看两个dhcp-port所在的节点,分别在network1和network2。

分别在network1, network2, network3上查看namespace和dnsmasq的状态。


 

成功复现了bug。

 

进一步确认现象是否一致。

在namespace里互相ping,发现ping不通,这是因为出现了地址冲突。

 

新创建网络,查看功能是否正常。

网络创建正常。

到网络节点上查看dhcp namespace和dnsmasq服务,都正常。

至此,问题确认成功复现了。

 

 

1.5.12 tap未删除的原因分析

这里我们来分析一下,对于已经创建好的网络,为什么重启mysql,会导致出现多余tap。

 

网络创建是成功的,网络成功调度某些dhcp-agent上。

此时,如果myql失联,Agent周期性上报状态就会失败(因为远端需要写db)。

之后mysql恢复,Agent上报成功,status会被标记为AGENT_REVIVED返回给Agent。

Agent收到AGENT_REVIVED的状态,会进行全量同步,向plugin去请求自己所需承载的所有的网络。

 

Plugin中,在默认开启network_auto_schedule的情况下,会进行网络重新调度,因为此时所有agent都down了,所以网络会重新调度。

这里,如果agent数目和dhcp_agents_per_network数目一致,所有agent都会承载所有的网络,重新调度没影响;

如果dhcp_agents_per_network小于agent数目,那么就会出现之前没调度到agent被调度到。

 

Agent收到自己需要承载的网络列表后,挨个网络进行处理。

对于每个网络,首先向plugin请求该网络的子网、端口详情。

然后从端口中找到曾经调度到自己agent的dhcp端口,然后进行端口状态更新。

如果找不到,那么就找device_id未赋值的dhcp port(这种端口表示承载该端口的agent down了,Plugin中通过定时器实现)

 

因为mysqld挂掉,导致全部agent都被标记为down,所以dhcp-port全部重新分配。

 

DHCP Agent使能网络时,有如下几种可能:

1. 该网络的namespace存在,并且dnsmasq进程还在。此时不删除namespace和tap口,只删除dnsmasq进程,替换或重新插入tap口到namespace和br-int,启动dnsmasq。

2. 该网络的namespace存在,但是dnsmasq进程不存在。直接替换或重新插入tap口到namespace和br-int,启动dnsmasq。

3. 该网络为第一次调度到改agent。创建namespace,添加tap口,tap加入br-int,启动dnsmasq。

 

 

对于前两种情况,因为dhcp port很可能不是原来的dhcp port,所以会出现旧port不能删除,从而出现两个tap的现象。

 

如果dhcp_agents_per_network配置为与dhcp-agent的数目一致,是否还会出现这个问题呢?

 

从前面的原理分析可以看出,出现多余tap口的关键是多个agent同时down,导致dhcp-port被重新分配,而dhcp-agent在处理namespace和tap时未能删除残留的port。

 

所以,即使dhcp_agents_per_network与dhcp-agent配置成一致的数目,也仍然出出现此问题。

 

1.5.13 进一步复现问题

从上面的分析可以看出,问题的原因是mysql导致的agent同时down。

如果我们不是停掉mysql,直接将所有agent down掉,然后打乱顺序重启呢?

 

环境:3个dhcp-agent,dhcp_agents_per_network配置为3.

创建网络:

dhcp port的ip地址分别是2,3,4。

通过neutron port-show,看到分别在network2,network3,network1上。

 

停掉全部的dhcp-agent。等待agent状态变为XXX。

然后继续等待dhcp-port 的device_id变为reserved_dhcp_port。

 

此时将network3上的dhcp-agent重启。


可以看到network3上承载的dhcp-port由4.5.6.3变为4.5.6.2了。

 

查看namespace:


也可以复现。

 

1.5.14 问题出现时,如何恢复

当出现这个问题时,我们重启dhcp-agent看能否恢复。

 

经确认,并没有恢复。

 

执行neutron-netns-cleanup呢?

也没有恢复。

 

停掉dhcp-agent,然后执行neutron-netns-cleanup,也没有恢复。

 

 

经测试可以手动删除:

ps aux |grep dnsmasq |grep NET

kill -9 PID

ip netns delete qdhcp-NET

然后重启dhcp-agent,恢复namespace和dnsmasq。

 

 

1.5.15 解决问题

查看最新master代码发现dhcp-agent在启动dnsmasq后会删除多余的tap口。

对应函数:_cleanup_stale_devices

查询提交记录,找到如下patch:

Author: Eugene Nikanorov <[email protected]>  2015-10-25 19:47:38

Committer: Eugene Nikanorov <[email protected]>  2015-11-13 23:55:01

Parent: 44d73d1ad3073958c8d5cce933deedc7e6ea5f83 (Updated from global requirements)

Child:  eccb3d3f872ce2833cb76253653f2cf27857a0ed (Merge "Cleanup dhcp namespace upon dhcp setup.")

Branches: master, remotes/gerrit/master, remotes/origin/master, remotes/origin/stable/mitaka

Follows: 7.0.0, 7.0.0.0rc3

Precedes: 8.0.0.0b1

 

    Cleanup dhcp namespace upon dhcp setup.

   

    In some cases when more than 1 DHCP agents were assigned

    to a network and then they became dead, their DHCP ports

    become reserved. Later, when those agents revive or start

    again, they acquire reserved ports, but it's not guaranteed

    that they get exactly same ports. In such case DHCP agent

    may create interface in the namespaces despite that another

    interface already exist. In such case there will be two

    hosts with dhcp namespaces each containing duplicate ports,

    e.g. one port will be present on two hosts. This breaks

    DHCP.

   

    Closes-Bug: #1509959

    Change-Id: I34eb1ad5c44dd3528c9910462e26536186e7a4fb

这个描述与研发区出现的问题现象一致。

 

 

合并后,问题解决。

 

1.5.16 测试dhcp server IP冲突

如果agent down了,dhcp server会迁移到其他agent,但是该agent上的dnsmasq进程还在,tap口对于虚机还是可达的。这样就会出现两个相同IP的dhcp server,存在地址冲突。

 

如果dhcp_agents_per_network小于等于dhcp agent数目的一半,而恰巧承载某个网络的agent都down了,IP迁移到另外的dhcp agent上,会导致该网络所有的dhcp server IP都存在冲突,对dhcp 提供服务可能存在影响。

 

我们来验证一下:

将dhcp_agents_per_network配置为1,创建网络

承载在network3上。



 

创建虚机,确认可自动获取IP地址。

 

停掉network3上的dhcp-agent,等待1分钟,确认agent状态变为down,

再等几分钟,device_id变为reserved_dhcp_port,然后发生迁移:



迁移到network2上了。

 

 

重新创建虚机,可以成功,虚机可以自动获取IP地址。

 

所以,dhcp协议比较健壮,有相同IP地址时仍然功能工作。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章