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節點




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