Neutron 理解 (4): Neutron OVS OpenFlow 流表 和 L2 Population

Neutron 理解 (1): Neutron 所實現的虛擬化網絡
Neutron 理解 (2): 使用 Open vSwitch + VLAN 組網
Neutron 理解 (3): Open vSwitch + GRE/VxLAN 組網

OVS bridge 有兩種模式:“normal” 和 “flow”。“normal” 模式的 bridge 同普通的 Linux 橋,而 “flow” 模式的 bridge 是根據其流表(flow tables) 來進行轉發的。Neutron 使用兩種 OVS bridge:br-int 和 br-tun。其中,br-int 是一個 “normal” 模式的虛擬網橋,而 br-tun 是 “flow” 模式的,它比 br-int 複雜得多。

1. 基礎知識

1.1 OpenFlow 結構、流表和數據包處理

下面一圖是 Open vSwitch 中流表的結構。二圖這個流程圖詳細描述了數據包流通過一個 OpenFlow 交換機的過程。

圖片描述

圖一

圖片描述

圖二

更詳細的描述請參見這裏

1.2 ARP Proxy

Proxy ARP 就是通過一個主機(通常是Router)來作爲指定的設備對另一個設備作出 ARP 的請求進行應答。

舉個例子:主機A,IP地址是192.168.0.11/24;主機B,IP地址是192.168.1.22/24。主機A和主機B通過路由器R相連接,並且路由器R啓用了Proxy ARP,並配置有路由。網絡拓撲如下:

 eth0                eth0       eth1                        eth0
A------------------------Router R----------------------B

192.168.0.11/24 192.168.0.0/24 eth0 192.168.1.22/24
192.168.1.0/24 eth1

這樣做的好處就是,主機A上不需要設置任何默認網關或路由策略,不管路由器R的IP地址怎麼變化,主機A都能通過路由器B到達主機B,也就是實現了所謂的透明代理。相反,若主機A上設置有默認網關或路由策略時,當主機A向192.168.1.22發送報文,首先要查找路由表,而主機A所在的網段是192.168.0.0/24,主機B所在網段是192.168.1.0/24,主機A只能通過默認網關將報文發送出去,這樣代理ARP也就失去了作用。

優點: 最主要的一個優點就是能夠在不影響其他router的路由表的情況下在網絡上添加一個新的router,這樣使得子網的變化對主機是透明的。 proxy ARP應該使用在主機沒有配置默認網關或沒有任何路由策略的網絡上

缺點:
  1.增加了某一網段上 ARP 流量
  2.主機需要更大的 ARP table 來處理IP地址到MAC地址的映射
  3.安全問題,比如 ARP 欺騙(spoofing)
  4.不會爲不使用 ARP 來解析地址的網絡工作
  5.不能夠概括和推廣網絡拓撲

2. 不使用 ARP Responder 和 DVR 時 br-tun 中的流表(flow tables)

OpenStack 中,Neutron 作爲 OVS 的 Controller,向 OVS 發出管理 tunnel port 的指令,以及提供流表。

2.1 流表分析

Neutron 定義了多種流表。以下面的配置(配置了 GRE 和 VXLAN 兩種 tunnel types)爲例:

1(patch-int): addr:a6:d4:dd:37:00:52
2(vxlan-0a000127): addr:36:ec:de:b4:b9:6b {in_key=flow, local_ip="10.0.1.31", out_key=flow, remote_ip="10.0.1.39"} 計算節點2
3(vxlan-0a000115): addr:4a:c8:21:3c:3f:f1 {in_key=flow, local_ip="10.0.1.31", out_key=flow, remote_ip="10.0.1.21"} 網絡節點
4(gre-0a000115): addr:4a:8b:0f:9d:59:52  {in_key=flow, local_ip="10.0.1.31", out_key=flow, remote_ip="10.0.1.21"} 網絡節點
5(gre-0a000127): addr:aa:58:6d:0a:f7:6a  {in_key=flow, local_ip="10.0.1.31", out_key=flow, remote_ip="10.0.1.39"} 計算節點2

其中,10.0.1.31 是計算節點1, 10.0.1.21 是網絡節點, 10.0.1.39 是計算節點2。

計算節點1 上 ML2 Agent 啓動後的 br-tun 的 flows:

來個圖簡單些:

圖片描述

其中比較有意思的是:

(1)爲什麼從 VXLAN 過來的流量都被丟棄了,最後發出去也用的是 GRE 端口。看來同時有 GRE 和 VXLAN 隧道的話,OVS 只會選擇 GRE。具體原因待查。

(2)MAC 地址學習:Table 10 會將學習到的規則(Local VLAN id + Src MAC Addr => IN_Port)放到 table 20。當表格20 發現一個單播地址是已知的時候,直接從一個特定的 GRE 端口發出;未知的話,視同組播地址從所有 GRE 端口發出。

2.2 MAC 地址學習

學習規則:

table=20,hard_timeout=300,priority=1,NXM_OF_VLAN_TCI[0..11],NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[],load:0->NXM_OF_VLAN_TCI[],load:NXM_NX_TUN_ID[]->NXM_NX_TUN_ID[],output:NXM_OF_IN_PORT[]

這語法不是很好理解,這裏有詳細解釋。

  • table=20:修改 table 20。這是個 MAC 學習流表。
  • hard_timeout:該 flow 的過期時間。
  • NXM_OF_VLAN_TCI[0..11] :記錄 vlan tag,所以學習結果中有 dl_vlan=1
  • NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[] :將 mac source address 記錄,所以結果中有 dl_dst=fa:16:3e:7e:ab:cc
  • load:0->NXM_OF_VLAN_TCI[]:在發送出去的時候,vlan tag設爲0,所以結果中有 actions=strip_vlan
  • load:NXM_NX_TUN_ID[]->NXM_NX_TUN_ID[] :發出去的時候,設置 tunnul id,所以結果中有set_tunnel:0x3e9
  • output:NXM_OF_IN_PORT[]:指定發送給哪個port,由於是從 port2 進來的,因而結果中有output:2。

學到的規則:

table=20, n_packets=1239, n_bytes=83620, idle_age=735, hard_age=65534, priority=2,dl_vlan=1,dl_dst=fa:16:3e:7e:ab:cc actions=strip_vlan,set_tunnel:0x3e9,output:2 

這裏可以看到,通過 MAC 地址學習機制,Neutron 可以一定程度地優化網絡流向,但是這種機制需要等待從別的節點的流量進來,只能算是一種被動的機制,效率不高。而且,這種機制只對單播幀有效,而對於多播和組播依然無效。其結果是網絡成本依然很高。下圖中,A 的廣播包其實只對 3 和 4 有用,但是 2 和 5 也收到了。

圖片描述

3. ARP Responder

arp_responder 的原理不復雜。Neutorn DB 中保存了所有的端口的 MAC 和 IP 地址數據。而 ARP 就是一個虛機要根據另一個虛機的 IP 地址查詢它的 MAC。因此,只需要 Neutron server 通過 RPC 告訴每個計算節點上的 ML2 agent 所有活動端口的 MAC 和 IP,那麼就可以將 br-tun 變成一個供本機適用的 ARP Proxy,這樣本機上的虛機的 ARP 請求的響應就可以由 br-tun 在本地解決。Assaf Meller有篇文章來闡述 ARP Responder。

使用 ARP Responder 需要滿足兩個條件:

(1)設置 arp_responder = true 來使用 OVS 的ARP 處理能力 。這需要 OVS 2.1 (運行 ovs-vswitchd –version 來查看 OVS 版本) 和 ML2 l2population 驅動的支持。當使用隧道方式的時候,OVS 可以處理一個 ARP 請求而不是使用廣播機制。如果 OVS 版本不夠的話,Neutorn 是無法設置 arp responder entry 的,你會在 openvswitch agent 日誌中看到“Stderr: ‘2015-07-11T04:57:32Z|00001|meta_flow|WARN|destination field arp_op is not writable\novs-ofctl: -:2: actions are invalid with specified match (OFPBAC_BAD_SET_ARGUMENT)\n’”這樣的錯誤,你也就不會在 ”ovs-ofctl dump-flows br-tun“命令的輸出中看到相應的 ARP Responder 條目了。

(2)設置 l2_population = true。同時添加 mechanism_drivers = openvswitch,l2population。OVS需要 Neutron 作爲 SDN Controller 向其輸入 ARP Table flows。

3.1 升級 OVS

殺掉 neutron openvswitch, ovs-* 各種進程

編譯安裝

http://openvswitch.org/download/ 下載最新版本的代碼,解壓,進入解壓後的目錄

安裝依賴包,比如 gcc,make

uname -r

./configure --with-linux=/lib/modules/3.13.0-51-generic/build

make && make install

查看安裝的版本

root@compute2:/home/s1# ovs-vsctl --version
ovs-vsctl (Open vSwitch) 2.3.2
Compiled Jul 12 2015 09:09:42
DB Schema 7.6.2

處理 db

rm /etc/openvswitch/conf.db (老的db要刪除掉,否則會報錯)

ovsdb-tool create /etc/openvswitch/conf.db vswitchd/vswitch.ovsschema

啓動 ovs

cp /usr/local/bin/ovs-* /usr/bin

ovsdb-server /etc/openvswitch/conf.db -vconsole:emer -vsyslog:err -vfile:info --remote=punix:/usr/local/var/run/openvswitch/db.sock --private-key=db:Open_vSwitch,SSL,private_key --certificate=db:Open_vSwitch,SSL,certificate --bootstrap-ca-cert=db:Open_vSwitch,SSL,ca_cert --no-chdir --log-file=/var/log/openvswitch/ovsdb-server.log --pidfile=/var/run/openvswitch/ovsdb-server.pid --detach --monitor

ovs-vswitchd unix:/usr/local/var/run/openvswitch/db.sock -vconsole:emer -vsyslog:err -vfile:info --mlockall --no-chdir --log-file=/var/log/openvswitch/ovs-vswitchd.log --pidfile=/var/run/openvswitch/ovs-vswitchd.pid --detach --monitor

啓動 neutron openvswitch agent,確保log 文件中 ovs-vsctl 和 ovs-ofctl 調用沒有錯誤

修改 /usr/share/openvswitch/scripts/ovs-lib 文件,保證機器重啓後 OVS 正常運行

rundir=${OVS_RUNDIR-'/var/run/openvswitch'}改爲rundir=${OVS_RUNDIR-'/usr/local/var/run/openvswitch'}

3.2 ARP Responder

有了 arp_responder 以後,br-tun 的流表增加了幾項和處理:

(1)table 2 中增加一條 flow,是的從本地虛機來的 ARP 廣播幀轉到table 21

# ARP broadcast-ed request go to the local ARP_RESPONDER table to be locally resolved
table=2, n_packets=0, n_bytes=0, idle_age=3, priority=1,arp,dl_dst=ff:ff:ff:ff:ff:ff actions=resubmit(,21)

(2)在 table 21 中增加一條 flow 將其發發往 table 22

# If none of the ARP entries correspond to the requested IP, the broadcast-ed packet is resubmitted to the flooding table
table=21, n_packets=0, n_bytes=0, idle_age=4, priority=0 actions=resubmit(,22)

如果下面第 (3)步增加的 flow rule 都處理不了這條 request,那麼轉到table 22 去 flood 到所有端口。

(3)由 L2 population 發來的 entry 來更新 table 21。

table 21 是在新的 l2pop 地址進來的時候更新的。比如說,compute C 上增加了新的虛機 VM3,然後計算節點 A 和 B 收到一條 l2pop 消息說 VM3 (IP 是***,MAC是***) 在 Host C 上,在 network “Z“ 中。然後,Compute A 和 B 會在 table 21 中增加相應的 flows。

br.add_flow(table=21, priority=1, proto='arp', dl_vlan=local_vid, nw_dst= ip, actions=actions)
其中action爲: (這裏有詳細解釋)

ARP_RESPONDER_ACTIONS = ('move:NXM_OF_ETH_SRC[]->NXM_OF_ETH_DST[],'
                         'mod_dl_src:%(mac)s,'
                         'load:0x2->NXM_OF_ARP_OP[],'
                         'move:NXM_NX_ARP_SHA[]->NXM_NX_ARP_THA[],'
                         'move:NXM_OF_ARP_SPA[]->NXM_OF_ARP_TPA[],'
                         'load:%(mac)#x->NXM_NX_ARP_SHA[],'
                         'load:%(ip)#x->NXM_OF_ARP_SPA[],'
                         'in_port')

(4)table 21 的處理過程

table 21 中的每一條 flow,會和進來的幀的數據做匹配(ARP 協議,network,虛機的 IP)。如果匹配成功,則構造一個 ARP 響應包,其中包括了 IP 和 MAC,從原來的 port 發回到虛機。如果沒有吻合的,那麼轉發到 table 22 做泛洪。

增加的 flow tables 在紅色部分:

圖片描述

因此,通過使用 l2-pop mechanism driver 和 OVS 2.1, Neutorn 可以在本地回答虛機的 ARP 請求,從而避免了昂貴的 ARP 廣播。這個功能給 GRE 和 VXLAN 的實現是在 Juno 版本中完成的。 這個blueprint似乎在支持VLAN 中的這個功能,但是看起來沒有完成。

4. L2 population

根據這篇文檔,l2pop 目前支持 VXLAN with Linux bridge 和 GRE/VXLAN with OVS,其blueprint在這裏

4.1 原理

l2pop 的原理也不復雜。Neutron 中保存每一個端口的狀態,而端口保存了網絡相關的數據。虛機啓動過程中,其端口狀態會從 down 到build 到 active。因此,在每次端口發生狀態變化時,函數 update_port_postcommit 都將會被調用:

{'status': 'DOWN/BUILD/ACTIVE', 'binding:host_id': u'compute1', 'allowed_address_pairs': [], 'extra_dhcp_opts': [], 'device_owner': u'compute:nova', 'binding:profile': {}, 'fixed_ips': [{'subnet_id': u'4ec65731-35a5-4637-a59b-a9f2932099f1', 'ip_address': u'81.1.180.15'}], 'id': u'1167e9ac-e10f-4cf5-bd09-6649eab38b32', 'security_groups': [u'f5377a66-803d-481b-b4c3-a6631e8ab456'], 'device_id': u'30580ea7-c456-416b-a01e-0fe645edf5dc', 'name': u'', 'admin_state_up': True, 'network_id': u'86c0d29b-4880-4739-bd68-eb3c392f5099', 'tenant_id': u'74c8ada23a3449f888d9e19b76d13aab', 'binding:vif_details': {u'port_filter': True, u'ovs_hybrid_plug': True}, 'binding:vnic_type': u'normal', 'binding:vif_type': u'ovs', 'mac_address': u'fa:16:3e:4f:59:9d'} 

在某些狀態變化下:

  • update_port_postcommit (down to active) -> _update_port_up -> add_fdb_entries -> fdb_add -> fdb_add_tun -> setup_tunnel_port (如果 tunnel port 不存在,則創建 tunnel port), add_fdb_flow -> add FLOOD_TO_TUN flow (如果是 Flood port,則將端口添加到 Flood output ports); setup_entry_for_arp_reply(‘add’。如果不是 Flood port,那麼 添加 ARP Responder entry (MAC -> IP)) 以及 add UCAST_TO_TUN flow Unicast Flow entry (MAC -> Tunnel port number)。
  • update_port_postcommit (active to down) -> _update_port_down -> remove_fdb_entries
  • delete_port_postcommit (active to down) -> _update_port_down -> remove_fdb_entries -> fdb_remove -> fdb_remove_tun -> cleanup_tunnel_port, del_fdb_flow -> mod/del FLOOD_TO_TUN flow; setup_entry_for_arp_reply (‘remove’), delete UCAST_TO_TUN flow
  • update_port_postcommit (fixed ip changed) -> _fixed_ips_changed -> update_fdb_entries

通過這種機制,每個節點上的如下數據得到了實時更新,從而避免了不必要的隧道連接和廣播。

  • Tunnel port
  • FLOOD_TO_TUN (table 22)flow
  • ARP responder flow
  • UCAST_TO_TUN (table 20) flow

有和沒有 l2pop 的效果:

圖片描述

4.2 過程實驗

1.def tunnel_sync(self) 函數除了上報自己的 local_ip 外不再自己見 tunnels,一切等 l2pop 的通知。

2.在 compute1 上添加第一個虛機 81.1.180.8

neutron-server:

  • 通知 compute1:{‘segment_id’: 6L, ‘ports’: {u’10.0.1.21’: [[‘00:00:00:00:00:00’, ‘0.0.0.0’], [u’fa:16:3e:87:40:f3’, u’81.1.180.1’]]}, ‘network_type’: u’gre’}}
  • 通知所有 agent: {‘segment_id’: 6L, ‘ports’: {u’10.0.1.31’: [[‘00:00:00:00:00:00’, ‘0.0.0.0’], [u’fa:16:3e:b3:e7:7a’, u’81.1.180.8’]]}, ‘network_type’: u’gre’}}

compute1:

  • 添加和網絡節點的tunnel options: {df_default=”true”, in_key=flow, local_ip=”10.0.1.31”, out_key=flow, remote_ip=”10.0.1.21”}
  • 添加到網段網關的 Unicast flow:table=20, n_packets=0, n_bytes=0, idle_age=130, priority=2,dl_vlan=2,dl_dst=fa:16:3e:87:40:f3 actions=strip_vlan,set_tunnel:0x6,output:4
  • 增加網段 81.1.180.1 網關的 ARP flows:table=21, n_packets=0, n_bytes=0, idle_age=130, priority=1,arp,dl_vlan=2,arp_tpa=81.1.180.1 actions=move:NXM_OF_ETH_SRC[]->NXM_OF_ETH_DST[],mod_dl_src:fa:16:3e:87:40:f3,load:0x2->NXM_OF_ARP_OP[],move:NXM_NX_ARP_SHA[]->NXM_NX_ARP_THA[],move:NXM_OF_ARP_SPA[]->NXM_OF_ARP_TPA[],load:0xfa163e8740f3->NXM_NX_ARP_SHA[],load:0x5101b401->NXM_OF_ARP_SPA[],IN_PORT
  • 修改 Flood flow

compute 2 節點:因爲它上面還沒有運行虛機,所以不做操作。

3.在 compute 2 上添加一個虛機 81.1.180.9

neutron server:

  • 通知 compute 2 : {‘segment_id’: 6L, ‘ports’: {u’10.0.1.31’: [[‘00:00:00:00:00:00’, ‘0.0.0.0’], [u’fa:16:3e:b3:e7:7a’, u’81.1.180.8’]], u’10.0.1.21’: [[‘00:00:00:00:00:00’, ‘0.0.0.0’], [u’fa:16:3e:87:40:f3’, u’81.1.180.1’]]}, ‘network_type’: u’gre’}}
  • 通知所有 agent:{‘segment_id’: 6L, ‘ports’: {u’10.0.1.39’: [[‘00:00:00:00:00:00’, ‘0.0.0.0’], [u’fa:16:3e:73:49:41’, u’81.1.180.9’]]}, ‘network_type’: u’gre’}

compute1:

  • 建立 tunnel(ID 5):{df_default=”true”, in_key=flow, local_ip=”10.0.1.31”, out_key=flow, remote_ip=”10.0.1.39”}
  • 增加 arp responder flow(compute2 上新的虛機 IP -> MAC):table=21, n_packets=0, n_bytes=0, idle_age=79, priority=1,arp,dl_vlan=2,arp_tpa=81.1.180.9 actions=move:NXM_OF_ETH_SRC[]->NXM_OF_ETH_DST[],mod_dl_src:fa:16:3e:73:49:41,load:0x2->NXM_OF_ARP_OP[],move:NXM_NX_ARP_SHA[]->NXM_NX_ARP_THA[],move:NXM_OF_ARP_SPA[]->NXM_OF_ARP_TPA[],load:0xfa163e734941->NXM_NX_ARP_SHA[],load:0x5101b409->NXM_OF_ARP_SPA[],IN_PORT
  • 增加 unicast flow (新虛機的 MAC -> Tunnel port):table=20, n_packets=0, n_bytes=0, idle_age=79, priority=2,dl_vlan=2,dl_dst=fa:16:3e:73:49:41 actions=strip_vlan,set_tunnel:0x6,output:5
  • 添加新的 Tunnel port 到 Flood flow:table=22, n_packets=13, n_bytes=1717, idle_age=255, hard_age=78, dl_vlan=2 actions=strip_vlan,set_tunnel:0x6,output:5,output:4

compute2:

  • 建立和計算節點以及compute1的tunnel:options: {df_default=”true”, in_key=flow, local_ip=”10.0.1.39”, out_key=flow, remote_ip=”10.0.1.21”},options: {df_default=”true”, in_key=flow, local_ip=”10.0.1.39”, out_key=flow, remote_ip=”10.0.1.31”}
  • 增加 ARP flow(compute 1 上的虛機的 MAC -> IP):table=21, n_packets=0, n_bytes=0, idle_age=268, priority=1,arp,dl_vlan=2,arp_tpa=81.1.180.8 actions=move:NXM_OF_ETH_SRC[]->NXM_OF_ETH_DST[],mod_dl_src:fa:16:3e:b3:e7:7a,load:0x2->NXM_OF_ARP_OP[],move:NXM_NX_ARP_SHA[]->NXM_NX_ARP_THA[],move:NXM_OF_ARP_SPA[]->NXM_OF_ARP_TPA[],load:0xfa163eb3e77a->NXM_NX_ARP_SHA[],load:0x5101b408->NXM_OF_ARP_SPA[],IN_PORT
  • 增加 Unicast flow (compute 1 上的虛機 MAC -> Tunnel port):table=20, n_packets=0, n_bytes=0, idle_age=268, priority=2,dl_vlan=2,dl_dst=fa:16:3e:b3:e7:7a actions=strip_vlan,set_tunnel:0x6,output:4
  • 增加 ARP flow(新虛機的網關的 MAC -> IP) table=21, n_packets=0, n_bytes=0, idle_age=268, priority=1,arp,dl_vlan=2,arp_tpa=81.1.180.1 actions=move:NXM_OF_ETH_SRC[]->NXM_OF_ETH_DST[],mod_dl_src:fa:16:3e:87:40:f3,load:0x2->NXM_OF_ARP_OP[],move:NXM_NX_ARP_SHA[]->NXM_NX_ARP_THA[],move:NXM_OF_ARP_SPA[]->NXM_OF_ARP_TPA[],load:0xfa163e8740f3->NXM_NX_ARP_SHA[],load:0x5101b401->NXM_OF_ARP_SPA[],IN_PORT
  • 修改 Flood flow(添加到 Compute 1 的 port):table=22, n_packets=13, n_bytes=1717, idle_age=128, dl_vlan=2 actions=strip_vlan,set_tunnel:0x6,output:5,output:4

4.刪除 compute1 上的一個vm(也是唯一的一個)

neutron server:

  • 通知所有 agent: {‘segment_id’: 6L, ‘ports’: {u’10.0.1.31’: [[‘00:00:00:00:00:00’, ‘0.0.0.0’], [u’fa:16:3e:b3:e7:7a’, u’81.1.180.8’]]}, ‘network_type’: u’gre’}

compute 1:

  • 因爲沒有別的虛機了,刪除所有 tunnel ports
  • 修改或者刪除 ARP, Unicast 和 Flood flows

compute 2:

  • 刪除了 compute1 的 tunnel
  • 刪除該虛機對應的 ARP flow

    1. 在 compute1 上創建第一個不同網絡的虛機

neutron server:

  • 通知 compute 1: {u’e2022937-ec2a-467a-8cf1-f642a3f777b6’: {‘segment_id’: 4L, ‘ports’: {u’10.0.1.21’: [[‘00:00:00:00:00:00’, ‘0.0.0.0’], [u’fa:16:3e:90:e5:50’, u’91.1.180.1’], [u’fa:16:3e:17:c9:26’, u’90.1.180.1’], [u’fa:16:3e:69:92:30’, u’90.1.180.3’], [u’fa:16:3e:69:92:30’, u’91.1.180.2’]]}, ‘network_type’: u’gre’}}
  • 通知所有 agent:{u’e2022937-ec2a-467a-8cf1-f642a3f777b6’: {‘segment_id’: 4L, ‘ports’: {u’10.0.1.31’: [[‘00:00:00:00:00:00’, ‘0.0.0.0’], [u’fa:16:3e:e9:ee:0c’, u’91.1.180.9’]]}, ‘network_type’: u’gre’}}

compute 1:建立和網絡節點的 tunnel port;更新 Flood flows;添加 ARP flows

compute 2:沒什麼action,因爲該節點上沒有新建虛機的網絡內的虛機

過程的大概說明:

  • 虛機在收到 fannout FDB entries 後,檢查其中每個 port 的 network_id(即 “segment_id”)。如果本機上有該 network 內的 port,那麼就處理 entries 中的 “ports”部分;否則,不處理該 entries。
  • 因此,當計算節點上沒有運行任何虛機時,不會建立任何 tunnel。如果兩個虛機上有相同網絡內的虛機,那麼建立會建立 tunnel。
  • 這種機制能實時建立 tunnel port,Flood entry (創建 Tunnel port 同時添加到 Flood output ports 列表), Unicast flow (虛機和網關 MAC -> Tunnel port) 和 ARP Responder entry (虛機和網關 MAC -> IP)。下圖中的藍色部分的流表都會被及時更新。
  • Neutron server 在端口創建/刪除/修改時,如果是該節點上的第一個虛機,首先發送直接消息;然後發通知消息給所有的計算和網絡節點。

圖片描述

4.3 性能

4.3.1 MQ 性能問題

應該說 l2pop 的原理和實現都很直接,但是在大規模部署環境中,這種通知機制(通知所有的 ML2 Agent 節點)可能會給 MQ 造成很大的負擔。一旦 MQ 不能及時處理消息,虛機之間的網絡將受到影響。下面是 l2pop 中通知機制代碼:

def __init__(self, topic=topics.AGENT):
        super(L2populationAgentNotifyAPI, self).__init__(
            topic=topic, default_version=self.BASE_RPC_API_VERSION)
        self.topic_l2pop_update = topics.get_topic_name(topic, topics.L2POPULATION, topics.UPDATE)

    def _notification_fanout(self, context, method, fdb_entries):
        self.fanout_cast(context, self.make_msg(method, fdb_entries=fdb_entries), topic=self.topic_l2pop_update)

    def _notification_host(self, context, method, fdb_entries, host):
        self.cast(context, self.make_msg(method, fdb_entries=fdb_entries), topic='%s.%s' % (self.topic_l2pop_update, host))

    def add_fdb_entries(self, context, fdb_entries, host=None):
        if fdb_entries:
            if host:
                self._notification_host(context, 'add_fdb_entries',fdb_entries, host) #cast 給指定 host
            else: 
                self._notification_fanout(context, 'add_fdb_entries', fdb_entries) #fanout 給所有計算和網絡節點

這段代碼是說,l2pop 採用的 MQ topic 是 “L2POPULATION”,消息通知採用 fanout 或者 cast 機制。如果是 fanout 的話,消息將發到所有的 ML2 agent 節點。這樣的話,其覆蓋面就有些過於廣泛了,就這個問題有人提了一個 ticket,官方答覆是 work as design,要改的話只能是添加 new feature 了。

4.3.2 大規模網絡環境中節點上的 OpenFlow flows 過多

不知道這個數目有沒有上限?數目很多的情況下會不會有性能問題?OVS 有沒有處理能力上限?這些問題也許得在實際的生產環境中才能得到證實和答案。

作者信息:劉世民(Sammy Liu),IBM 雲架構師,十餘年IT行業從業經歷,在電信、企業軟件、存儲以及雲計算等領域做過研發、管理和架構設計等工作。從 2012 年開始學習 OpenStack,對其核心模塊有較深入的瞭解;帶領過團隊開發OpenStack模塊。

責編:陳晨,關注雲計算,聯繫請添加微信:violace95 備註公司+職位+姓名。尋求報道或投稿,請聯繫 [email protected]


2016年5月13日-15日,由CSDN重磅打造的2016中國雲計算技術大會(CCTC 2016)將於5月13日-15日在北京舉辦,今年大會特設“中國Spark技術峯會”、“Container技術峯會”、“OpenStack技術峯會”、“大數據核心技術與應用實戰峯會”四大技術主題峯會,以及“雲計算核心技術架構”、“雲計算平臺構建與實踐”等專場技術論壇。大會講師陣容囊括Intel、微軟、IBM、AWS、Hortonworks、Databricks、Elastic、百度、阿里、騰訊、華爲、樂視、京東、小米、微博、迅雷、國家電網、中國移動、長安汽車、廣發證券、民生銀行、國家超級計算廣州中心等60+頂級技術講師,CCTC必將是中國雲計算技術開發者的頂級盛會。目前會議門票限時7折(截止至4月29日24點),詳情訪問CCTC 2016官網。

發佈了88 篇原創文章 · 獲贊 6 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章