作者:閆興安
1 vxlan隧道問題定位
本文描述某OpenStack測試環境vxlan隧道數目錯誤問題的原因定位及解決辦法。
1.1 環境信息
節點類型 |
|
控制節點(起dhcp-agent) |
3 |
網絡節點(起vRouter) |
2 |
計算節點(ovs-agent) |
70 |
該環境曾經有73個計算節點,刪除了3個計算節點。
1.2 問題現象
確認各分組數目:
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
1.3 問題定位
1.3.1 查看neutron vxlan endpoint db
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,進行分析原因
1.3.2 查看配置文件
查看配置文件中local_ip和hostname:
# cat /etc/neutron/plugin.ini |grep local_ip local_ip = A.B.C.D # hostname |
沒有異常。
1.3.3 查看neutron-server日誌
這個日誌後面分析一下原因。
1.4 代碼流程分析
1.4.1 ovs-agent 如何註冊vxlanendpoint
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建立隧道。
1.5 問題分析測試
1.5.1 neutron-server中報Vxlanendpoint已存在的日誌
從代碼看,只要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 |
所以這個日誌不是問題。
1.5.2 節點vxlan隧道錯誤的原因分析
節點上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.5.3 問題恢復方法
手動恢復方法:
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,不能解決此問題。
綜上,不修改代碼進行解決,在部署/運維階段監控隧道數目,出現問題時人工恢復。