OpenStack DVR 原理深入分析

一、DVR實驗環境

一套vlan模式的openstack環境,interface_driver使用openvswitch,並在計算節點添加br-ex,用於計算節點虛擬機出外網。

二、DVR配置

1、控制節點

a、編輯/etc/neutron/neutron.conf
[DEFAULT]
router_distributed = True

b、重啓neutron-server服務

2、網絡節點

a、編輯/etc/neutron/l3_agent.ini
[DEFAULT]
agent_mode = dvr_snat

b、編輯
/etc/neutron/plugins/ml2/openvswitch_agent.ini
[agent]
enable_distributed_routing = True

c、重啓neutron-l3-agent和neutron-openvswitch-agent服務

3、計算節點

a、編輯/etc/sysctl.conf
net.ipv4.ip_forward=1
net.ipv4.conf.all.rp_filter = 0
net.ipv4.conf.default.rp_filter = 0

b、執行命令sysctl –p

c、編輯/etc/neutron/l3_agent.ini
[DEFAULT]
interface_driver=neutron.agent.linux.interface.OVSInterfaceDriver
external_network_bridge =
agent_mode = dvr

d、編輯
/etc/neutron/plugins/ml2/openvswitch_agent.ini
[agent]
enable_distributed_routing = True

e、重啓neutron-l3-agent和neutron-openvswitch-agent服務

三、啓用dhcp實現metadata功能

1、默認情況下,metadata功能通過l3實現,在dvr模式下,如果使用l3實現的話,需要額外配置metadata agent,爲了簡化,該實驗啓用dhcp agent來實現metadata功能。

a、在網絡節點上編輯/etc/neutron/dhcp_agent.ini
[DEFAULT]
force_metadata = True

b、重啓neutron-dhcp-agent服務。

四、DVR到網關流表分析

1、創建router,關聯到test1網絡(網關192.168.1.1),並在test1網絡內創建instance(192.168.1.9),網絡模型如下:

OpenStack DVR 原理深入分析

執行上述操作之後,neutron會在網絡節點和計算節點(有instance運行)上都創建一個router的namespace,且配置完全一樣。

也就是說,平臺中會出現多個相同的router namespace,那麼neutron如何實現虛擬機到網關的流量只到本地的router namespace呢?答案是flow table

2、舉個例子:

a、在test1內ping網關(192.168.1.1),虛擬機會先發送arp請求去學習網關的mac地址,arp報文會從qvo-xxx端口進入br-int的table0,匹配arp和in_port,根據流表項,resubmit到table24。

b、在table24中匹配arp、in_port和arp_spa,命中之後,resubmit到table25。

c、在table25中匹配in_port和dl_src,命中之後,resubmit到table60。

d、在table60中,命中table-miss flow entry,根據action執行NORMAL。

e、網關地址是配置在router namespace中的qr-xxx上,而qr-xxx是br-int上的。

端口,所以qr-xxx會收到arp請求,並進行相應,arp相應報文會從qr-xxx端口再次進入br-int table0,命中table-miss flow entry,從而進行NORMAL轉發,將報文轉發給虛擬機的qvo-xxx。

f、虛擬機學到網關的mac地址之後,將icmp報文通過流表,轉發給網關,ping流程完成。

3、現在分析neutron如何通過flow table 實現虛擬機到網關的流量只到本地的router namespace。

在上述的d步驟中,命中table-miss flow entry,根據action執行NORMAL,報文可能通過正常轉發,到達br-vlan。

a、報文到達br-vlan後,會進入table=0,匹配in_port,命中後,resubmit到table1

b、在table1中,匹配dl_vlan、arp_tpa(arp報文)或者dl_dst,從而把到網關的報文,全部drop。

c、通過上述流表,保證到達網關的報文全部終結在宿主機本地。

五、虛擬機內網通信分析

DVR模式下,虛擬機的內網通信一般有四種場景:同網絡同宿主機,同網絡不同宿主機,不同網絡同宿主機,不同網絡不同宿主機,下面將對這四種場景逐一進行分析:

1、同網絡同宿主機,不需要通過router,實驗模型如下:

OpenStack DVR 原理深入分析

test1和test2運行在同一臺宿主上,執行test1 ping test2。

a、test1通過arp學習到test2的mac地址,流表匹配過程和步驟4(DVR到網關流表分析)中arp學習相同,然後封裝icmp報文,從qvo-xxx port進入br-int的table0,匹配in_port,命中後,resubmit到table25。

b、在table25中,匹配in_port和dl_src,命中後,resubmit到table60。

c、在table60,命中table-miss,執行NORMAL轉發。

d、test2的qvo-yyy port也在br-int上,報文通過qvo-yyy發送到test2,test2回包給test流程和test1到test2相同。ping流程結束。

2、同網絡不同宿主機,不需要router,實驗模型如下:

OpenStack DVR 原理深入分析

test1和test2運行在不同宿主上,執行test1 ping test2。

此場景下,步驟a,b,c和同網絡同宿主機場景步驟完全相同,報文會在br-int的table60執行NORMAL,此處不再贅述。

d、執行NORMAL後,報文會從phy-br-vlan port進入br-vlan的table0,匹配in_port,命中後,resubmit到table1。

e、在table1中,命中table-miss,resubmit table2。

f、在table2中,匹配in_port和dl_vlan,命中後,修改local vlan 1爲全局vlan 196,然後執行NORMAL,此時報文會離開宿主機,從業務口發出去。

g、報文會被送到運行test2的宿主機業務口,然後進入br-vlan的table0,命中後,resubmit到table3。

h、在table3中,命中後,執行NORMAL,報文被送到br-int。

i、在br-int的table0中,匹配in_port和dl_vlan,命中後,修改全局vlan 196 爲local vlan 1,然後執行NORMAL,報文會從qvo-yyy進入虛擬機test2。

j、test2回包和test1發包過程相同,至此,ping操作完成。

3、不同網絡同宿主機,需要router,實驗模型如下:

OpenStack DVR 原理深入分析

創建router分別連接兩個網絡,每個網絡上個各創建一臺instance,執行上述操作之後,neutron會在網絡節點和計算節點(有instance運行)上都創建一個router的namespace,且配置完全一樣,qr-設備會被配置上對應網關ip地址。

test1和test2運行在同宿主上,執行test1 ping test2。

a、test1 通過計算知道要到達test2需要走三層,它會先發arp請求,學習網關的mac地址,然後封裝icmp報文(目的ip是test2的ip,目的mac是網關的mac地址),通過默認路由,將報文送到本地的router namespace。
(學習網關過程中匹配流表的過程請參考 <4、DVR到網關流表分析>章節)。

b、報文從qr-test1進入router的PREROUTING鏈,然後查找到test2的路由,命中之後,進入POSTROUTING鏈,並從qr-test2重新進入br-int的table0。

c、在table0中,命中table-miss,resubmit到table60。

d、在table60中,命中後,執行NORMAL,將報文從qvo-xxx送到test2。

e、test2回包的過程和test1發包過程相同,至此,ping操作完成。

4、不同網絡不同宿主機,需要router,實驗模型如下:

OpenStack DVR 原理深入分析

test1和test2運行在不同宿主上,執行test1 ping test2。

此場景下,步驟a,b,c和不同網絡同宿主機場景步驟完全相同,
報文從qr-test2出來之後,在br-int的table60執行NORMAL,此處不再贅述。

d、在c中執行NORMAL之後,報文通過int-br-vlan port進入br-vlan的table0。

e、在table0中,匹配in_port,命中之後,resubmit到table1。

f、在table1中,匹配dl_vlan和dl_src,命中之後,修改源mac地址爲neutron分配給宿主機mac,resubmit到table2。

注:開啓DVR之後,neutron會給每個compute節點分配一個唯一的mac地址,避免物理交換機出現mac地址衝突的問題。

g、在table2中,匹配in_port和dl_vlan,命中之後,修改local vlan 2爲全局
vlan 148,執行NORMAL,此時報文會從業務口eth1離開宿主機。

h、報文會進入運行test2的宿主機的業務口eth1進入br-vlan的table0。

i、在table0中,命中之後,resubmit到table3。

j、在table3中,匹配dl_src(neutron分配給宿主機的mac),將報文從phy-br-vlan送出給br-int table0。

k、在br-int的table0中,匹配in_port和dl_src(neturon分配給宿主機的mac),resubmit給table2。

l、在table2中,匹配dl_vlan和dl_dst,修改源mac爲test2網關的mac,resubmit到table60。

m、在table60中,匹配dl_vlan和dl_dst ,剝去vlan,通過output將報文直接送到test2。

n、test2回包的過程和test1發包過程相同,至此,ping操作完成。

六、虛擬機出外網原理分析

1、創建一個router,並綁定內部網絡test1,設置路由器的網關外網爲external,在內網,外網上各創建一臺虛擬機,用於測試,實驗模型如下:

OpenStack DVR 原理深入分析

執行上述操作之後,neutron會在網絡節點創建三個namespace:qrouter-xxx、fip-yyy、snat-xxx。

計算節點(instance運行)創建qrouter-xxx、fip-yyy。

ps:各節點的namespace會在接下來的分析中說明其作用。

2、虛擬機test1的報文被送到本宿主機router namespace的qr-xxx設備上(上述已經說明,此處不再贅述),進入PREROUTING鏈(未命中,不做任何修改),查看策略路由,使用默認路由準備進行轉發,然後進入POSTROUTING鏈(未命中),報文從qr-xxx發出,送往192.168.1.11進行處理(流表全部命中NORMAL)。

3、可能有人會有疑問,這裏的192.168.1.11是啥?

事實上這個ip地址是neutron分配給snap-yyy namespace的一個ip,被配置在sg-zzz上,snap-yyy namespace在網絡節點上,neutron通過策略路由和sg-zzz port將計算節點router namespace中的報文,轉發到網絡節點的snat-yyy中。

4、此時報文到達網絡節點的snat-yyy namespace中的sg-zzz port上,在路由之前報文會進入PREROUTING鏈(未命中),然後查找路由。

隨後進入POSTROUTING鏈,進行snat,並做連接跟蹤,之後報文進行轉發。

5、經過上述操作,虛擬機通過snat-yyy中的qg-設備出外網,通過連接跟蹤返回(流表命中NORMAL)。

七、Floating ip原理分析

1、在章節6的基礎上,從外網分配一個floating ip(10.100.0.7),並關聯到虛擬機test1(192.168.1.9)上,並需要自行配置br-ex,用於虛擬機出外網,實驗模型如下:

OpenStack DVR 原理深入分析

執行上述操作之後,neutron會在對應的namespace裏面添加若干策略,下面的分析中會逐一說明:

1、虛擬機test1的報文被送到本宿主機router namespace的qr-xxx設備上(上述已經說明,此處不再贅述),進入PREROUTING鏈(未命中,不做任何修改),查看策略路由。

通過策略路由,將報文通過rfp-6347c62b-2轉發給169.254.109.47處理,隨後進入POSTROUTING鏈,做snat修改。

2、到這裏,大家可能會有一個疑問,這個rfp-6347c62b-2設備是啥?
事實上這個是veth pair的一端,它的另一端在fip-xxx namespace裏面

neutron 使用這對veth pair,將報文從router的namespace裏面,通過策略路由,轉發到fip-yyy的namespace裏。

3、至此,報文到達fip-yyy namespace,進入PREROUTING鏈(未命中),查看路由。

再進入POSTROUTING鏈(未命中),從而將報文從fg-7ec56cee-b5設備轉發到外網。

4、至此,報文順利從fg port發送到外網(流表命中NORMAL)。

5、現在開始分析外網設備通過floating ip進入虛擬機的情況。

假設存在一臺外網設備external(10.100.0.14)去ping floating ip(10.100.0.7),外網設備首先會通過arp學習10.100.0.7的mac地址,而上述描述中,neutron並沒有配置10.100.0.7的ip地址在任何設備上,也就是說,10.100.0.7並不存在,那報文是如何準確的送到fg口的呢?

事實上,neutron在fg port上開啓了arp_haproxy功能,相當於進行了arp欺騙,這樣,外網設備就將fg的mac地址學習成10.100.0.7的mac,並更新到自己的mac表中。

6、外網報文到達fg口之後,進入PREROUTING鏈(未命中),查看route表,準備將目的ip爲floating ip的報文從fpr-6347c62b-2發送169.254.109.46。

隨後進入POSTROUTING鏈(未命中),報文轉發到router的namespace中。

7、報文到達router的namespace中的rfp-6347c62b-2設備,進入PREROUTING鏈,進行dnat操作。將目的ip從floating ip轉換成內部fix ip(192.168.1.9)

隨後查看route,準備將報文從qr-xxx port轉發。

然後進入POSTROUTING鏈(未命中),將報文從qr- port轉發到虛擬機test1。

8、至此,實現外網設備到內部ip的轉發完成。

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