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地址時仍然功能工作。

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