作者:闫兴安
本文描述某OpenStack测试环境vxlan隧道数目错误问题的原因定位及解决办法。
节点类型 |
|
控制节点(起dhcp-agent) |
3 |
网络节点(起vRouter) |
2 |
计算节点(ovs-agent) |
70 |
该环境曾经有73个计算节点,删除了3个计算节点。
确认各分组数目:
Salt 配置文件中指定vxlannode分组为: vxlannode: N@controller or N@network or N@compute
需要建立隧道的节点数目 salt -N vxlannode cmd.run "ovs-vsctl show |grep vxlan |grep Port|wc -l" |grep scq |wc -l 应该是75个。
节点的隧道数目: salt -N controller cmd.run "ovs-vsctl show |grep vxlan |grep Port|wc -l" |grep scq |wc -l 应该是3个。
salt -N network cmd.run "ovs-vsctl show |grep vxlan |grep Port|wc -l" |grep scq |wc -l 应该是2个。
salt -N compute cmd.run "ovs-vsctl show |grep vxlan |grep Port|wc -l" |grep scq |wc -l 应该是70个。 |
查看各节点的vxlan隧道数目。
salt -N controller cmd.run "ovs-vsctl show |grep remote|wc -l" salt -N network cmd.run "ovs-vsctl show |grep remote |wc -l" salt -N compute cmd.run "ovs-vsctl show |grep remote |wc -l" salt -N vxlannode cmd.run "ovs-vsctl show |grep remote |wc -l" |
看到有些节点是70个隧道,有些是78个隧道(未贴图)。
期望行为:每个节点都建立74个vxlan隧道。
查看agent状态,全为UP:
# neutronagent-list |grep Open |wc -l
75
mysql> use neutron; Database changed mysql> mysql> select * from ml2_vxlan_endpoints; +--------------+----------+-------------------+ | ip_address | udp_port | host | +--------------+----------+-------------------+ | A.B.C.D | 4789 | NAME | +--------------+----------+-------------------+ 70 rows in set (0.00 sec) |
这里应该是75个才对,说明有agent没有成功上报vxlan endpint信息。
对比db和节点信息,找出db中丢失的6个节点信息。
|
主机名 |
管理网IP |
业务网IP |
Controller2 |
|
||
Controller3 |
|
||
计算节点13 |
|
||
计算节点41 |
|
||
计算节点68 |
|
||
Network2 |
|
以及多余的一个节点信息:
计算节点65 |
|
|
|
其他endpoint,host和ip都是正确的。
下面主要分析,为什么这5个节点没有注册endpoint到neutron db中。
找一个节点Controller2,进行分析原因
查看配置文件中local_ip和hostname:
# cat /etc/neutron/plugin.ini |grep local_ip local_ip = A.B.C.D # hostname |
没有异常。
这个日志后面分析一下原因。
Agent中tunnel_sync触发条件:
agent刚启动,或者检测到ovs重启。
一旦同步完成,只要ovs不重启,tunnel就始终不会同步了。
tunnel信息注册:
Agent在tunnel_sync时,将本机的tunnel信息(tunnel_ip,tunnel_type, host name)上报plugin,并请求所有的tunnel列表,然后在本地建立vxlan隧道和流表。
Plugin 处理tunnel注册过程:(host,tunnel_ip)
1) 如果db中tunnel_ip被其他agent使用,删除其他agent注册的tunnel信息。并且打log:Tunnel IP %(ip)s was used by host %(host)s and will be assigned to%(new_host)s。
2) 如果db中有这个host,但是tunnel_ip与DB不同,删除db中这个tunnel_ip的隧道信息,并且通知其他agent。
3) 更新DB,然后通知其他Agent。
举个例子:
当前db中有两个隧道信息:
host_A, 1.1.1.2
host_B, 1.1.1.3
此时,
如果agent上报的是host_C, 1.1.1.2, 就删除(host_A, 1.1.1.2),并打印Log。
如果agent上报的是host_B, 1.1.1.2, 同上,删除(host_A, 1.1.1.2) ,并打印Log。
如果agent上报的是host_B, 1.1.1.4, 就删除(host_B, 1.1.13),然后通知所有agent,将1.1.1.3删除。
在Plugin中,收到某Agent(比如A)上报的tunnel信息之后,会主动通知其他Agent(其他agent可能已经完成了tunnel sync,如果不通知,会缺失 Agent A的隧道),让其他Agent与Agent A建立隧道。
从代码看,只要ovs-agent上报两次tunnel sync,就会出现这个Log。
我们找个正常的ovs-agent,然后重启Ovs-agent。
果然出现了:
2016-09-12 17:57:16.199 23537 WARNING neutron.plugins.ml2.drivers.type_vxlan [req-c05da8d6-d8ef-48d3-9eb3-d7191a1764a6 ] Vxlan endpoint with ip A.B.C.D already exists |
所以这个日志不是问题。
节点上vxlan隧道错误包括如下几种情况:
1) 缺失隧道。没有到达某个Agent的隧道。
2) 多余隧道。某个Agent被删除了,但是还有到达这个Agent的隧道。
3) 错误隧道。某个Agent的local_ip更改了,旧ip没有被使用,但是还有到达旧local_ip的隧道。
根据代码分析,有如下可能会导致上述问题。
1. 部署/运维直接从neutrondb中将某个agent的ml2_vxlan_endpoint删除。
因为ovs agent不会周期上报tunnel信息,所以db无法恢复。
其他agent无法建立到这个agent的隧道。
解决办法:
重启ovs agent
2. 某个Agent被剔除了(主机挪作他用),此时db中 endpoint还是存在的。
这样,其他agent到这个agent的隧道不会被删除。
解决办法:
手动在Neutron db中删除这条entry,然后重启所有ovs-agent。
3. 某Agent tunnel_ip错误地配置为其他agent的ip,然后再改回来。
该操作会导致neutrondb中tunnel信息丢失(会有error log),原因同1,也无法恢复。
解决办法:
重启neutron db中隧道被误删的ovs-agent,使其重新上报tunnel信息。
4. 某Agent tunnel_ip配置为错误ip,其他agent建立了到这个ip的隧道,然后Agent恢复IP配置。plugin在通知其他Agent删除配置时失败(比如agent与plugin失联了)。
通知失败时,错误IP的隧道就会残留在Agent里。
解决办法:
重启隧道错误的ovsagent。
5. 部署阶段清除整个neutron db,但是没有重启全部ovs-agent。
这个同1,ovs-agent 中的tunnel不会进行同步。
解决办法:
重启所有的ovs-agent。
经确认,环境中出现问题的原因是上面的第5种情况。
综上,本质原因:ovs-agent 不会定期同步tunnel(上报tunnel和同步本机的隧道)。
导致出现隧道信息错误的原因有:
1. 新增或删除节点。
2. 修改neutronml2_vxlan_endpoints db。
3. 修改主机hostname或者tunnel_ip。
4. 上述操作时plugin与agent失联。
可以看出,上述操作基本都是在部署阶段。
手动恢复方法:
1) 确认neutron ml2_vxlan_endpoints是否正确,有问题修复DB。
2) 重启全部ovs-agent。
如果要修改代码,支持周期同步,如何修改?
步骤如下:
1) 向Plugin上报本机的tunnel信息
2) Plugin返回全部的tunnel信息
3) 与本地ovs br-tun中的tunnel对比:
4) 添加缺失的tunnel port和流表
5) 删除多余的tunnel port和流表
目前代码中没有主动删除endpoint的地方。
如何修改代码支持自动删除neutron db中残留的ml2_vxlan_endpoint?
1) 在删除agent时,去删除endpoint。
该改动可能会导致agent上vxlan隧道频繁变动。
是否修改代码,定期进行tunnel同步?
1) 问题是在部署阶段、环境发生改动时出现的,对于稳定环境不会出现。
2) neutron db中可能存在残留endpoint,必须人工干预删除,仅仅在ovs-agent中定期同步tunnel,不能解决此问题。
综上,不修改代码进行解决,在部署/运维阶段监控隧道数目,出现问题时人工恢复。