1. 程式人生 > >openstack學習之neutron_linuxbridge_agent分析

openstack學習之neutron_linuxbridge_agent分析

 linuxbridge是和linuxbridge plugin匹配的core agent,主要實現L2層的功能和security group的功能。security group的功能逐漸會被neutron firewall取代。 linuxbridge的啟動命令在linuxbridge_neutron_agent.py中 啟動的時候需要提供neutron.conf和linuxbridge_conf.ini配置檔案 主要配置項: linuxbridge_conf.ini [vlans] network_vlan_ranges = physnet1,physnet2:1000:2999 tenant_network_type = vlan [linux_bridge] physical_interface_mappings = physnet1:eth0,physnet2:eth1 其中physnet1和physnet2表示該節點可用的物理網路名字(physical network, 名字可以隨便定義),physical_interface_mappings用來把名字和該網路使用的物理網絡卡對應起來。 physical_interface_mappings的作用
physical_interface_mappings是linuxbridge中最重要的配置項。用來定義節點中的物理網路,可以有多個。openstack中的節點(按功能不同,可分為計算節點,dhcp節點,L3節點等)通過物理網路實現互聯。這個物理網路用來實現neutron中定義的虛擬網路拓撲,和openstack的管理網路不是一個,是不同的概念。 虛擬網路的流量需要通過物理網路承載,而物理網路其實就是該節點上的網絡卡。在linuxbridge實現中,每個網路對應一個bridge,每個網路又會有一個物理網路(provider:physical_network屬性)來承載,與該物理網路對應的網絡卡(physical_interface_mappings中配置,如physnet1對應eth1),會被加入這個bridge中,這樣該網路就可以和外部系統通訊了。 如果虛擬機器中需要和外網相連(訪問Internet),需要在L3節點(負責路由功能)上配置可以訪問外部的物理網路,然後建立一個provider網路和這個物理網路對應起來。把該provider網路和需要訪問外網的虛擬機器所在網路加入同一個路由器,即可實現訪問外網的功能。 例子:
建立provider網路,public01是該網路的名字,physnet1是物理網路的名字。physical_interface_mappings需要配置physnet1對應的物理網絡卡,如eth0。 $ neutron router-create router01 $ neutron net-create --tenant-id $tenant public01 \           --provider:network_type flat \           --provider:physical_network physnet1 \           --router:external=True $ neutron subnet-create --tenant-id $tenant --name public01_subnet01 \           --gateway 10.64.201.254 public01 10.64.201.0/24 --disable-dhcp $ neutron router-gateway-set router01 public01 建立可訪問外網的網路net01(vlan型別),該網路的物理網路是physnet2。physical_interface_mappings需要配置physnet2對應的物理網絡卡,如eth1。 $ neutron net-create --tenant-id $tenant net01 \           --provider:network_type vlan \           --provider:physical_network physnet2 \           --provider:segmentation_id 101 $ neutron subnet-create --tenant-id $tenant --name net01_subnet01 net01 192.168.101.0/24 $ neutron router-interface-add router01 net01_subnet01 建立另外一個可訪問外網的網路net02  $ neutron net-create --tenant-id $tenant net02 \           --provider:network_type vlan \           --provider:physical_network physnet2 \           --provider:segmentation_id 102 $ neutron subnet-create --tenant-id $tenant --name net02_subnet01 net02 192.168.102.0/24 $ neutron router-interface-add router01 net02_subnet01 這兩個網路中的VM就可以訪問外網,通過SNAT方式。如果需要外部網路直接訪問VM,需要給VM分配一個floating IP地址。 關於網路的概念可以參考博文《openstack學習之白話Openstack》中關於網路的介紹。 linuxbridge agent功能
主要有三個任務: 1)報告狀態。 2)處理RPC API。 3)在本節點實現neutron中定義的網路拓撲。 1)報告狀態 在def _report_state(self)中實現,這個函式被週期呼叫:             heartbeat = loopingcall.FixedIntervalLoopingCall(                 self._report_state)             heartbeat.start(interval=report_interval) _report_state主要是通過REST API將自己的狀態傳送給core plugin。可以參看程式碼。 2)處理RPC API 處理RPC的程式碼在LinuxBridgeRpcCallbacks中,主要有2個API: def network_delete(self, context, **kwargs): def port_update(self, context, **kwargs): network_delete主要用來刪除該節點上的bridge裝置。 port_update處理對port的屬性更新:segmentation_id,network_type和physical_network。 這裡邊還有和FDB相關的API,實現population功能。 3)實現網路拓撲。 實現網路拓撲的主要功能就是: a)建立bridge,將相應物理網路的網絡卡介面加入該bridge。 b)將TAP裝置加入到bridge中。每個neturon port會有一個tap裝置建立,port是一個邏輯概念,tap是port的物理實現。openstack中使用port的裝置主要有:虛擬機器,DHCP agent和L3 agent。 虛擬機器上每個網絡卡對應一個port,也就是一個tap裝置。 dhcp agent針對每個服務網路(使用該agent提供DHCP服務)都會建立一個port。 L3 agent上的每個路由器(router)也會有相應的port接入不同的網路。 每種裝置會針對每個port建立一個tap裝置。linuxbridge agent負責將這些tap裝置接入到相應的bridge中。 程式碼實現主要在def daemon_loop(self)中。程式碼的主要流程是: a 掃描該節點上的TAP裝置:device_info = self.br_mgr.update_devices(devices) b 處理掃描的TAP裝置:process_network_devices(device_info) 掃描裝置通過遍歷目錄/sys/devices/virtual/net實現。 處理裝置主要有兩種情況:增加和刪除。(更新操作由前面的RPC API處理) treat_devices_added treat_devices_removed 在treat_devices_added中,會把port的狀態更新成ACTIVE;在treat_devices_removed會把port的狀態變成DOWN。狀態更新會發給core plugin。在nova boot後,VM PORT是DOWN狀態,只有當相應的linux bridge將其port狀態變成ACTIVE時,boot才會成功。 boot過程中會等待port變成ACTIVE狀態:wait_for_instance_event 某些型別的Hypervisor driver會將tap裝置直接加入到bridge(也會建立相應的bridge)中,如libvirt的driver。這個不影響linuxagent的處理。 建立bridge的程式碼:         if network_type == p_const.TYPE_FLAT:             return self.ensure_flat_bridge(network_id, physical_interface)         elif network_type == p_const.TYPE_VLAN:             return self.ensure_vlan_bridge(network_id, physical_interface,                                            segmentation_id) 流程比較清晰,可以參考程式碼實現。 其他 linuxbridge的配置不是持久化(persistent),每次重啟OS後,所有的配置都會消失。 linuxbridge只有在裝置使用了某個port時,才會在該節點上建立相應的bridge並加入tap裝置。如果只是建立了網路或者該節點上沒有裝置使用該網路,並不會有bridge創建出來。這就是所說的"OpenStack provisions networks “on demand”。 源自網路的2張圖:第一張是計算節點;第二張是DHCP + L3節點