1. 程式人生 > >深入理解openstack網路架構(1)

深入理解openstack網路架構(1)

前言

openstack網路功能強大同時也相對更復雜。本系列文章通過Oracle OpenStack TechPreview介紹openstack的配置,通過各種場景和例子說明openstack各種不同的網路元件。本文的目的在於提供openstack網路架構的全景圖並展示各個模組是如何一起協作的。這對openstack的初學者以及希望理解openstack網路原理的人會非常有幫助。首先,我們先講解下一些基礎並舉例說明。  

根據最新的icehouse版使用者調查,基於open vswitch外掛的Neutron在生產環境和POC環境都被廣泛使用,所以在這個系列的文章中我們主要分析這種openstack網路的配置。當然,我們知道openstack網路支援很多種配置,儘管neutron+open vswitch是最常用的配置,但是我們從未說它是最好或者最高效的一種方式。Neutron+open vswitch僅僅是一個例子,對任何希望理解openstack網路的人是一個很好的切入點。即使你打算使用其他型別的網路配置比如使用不同的neutron外掛或者根本不使用neutron,這篇文章對你理解openstack網路仍是一個很好的開始。  

我們在例子中使用的配置是Oracle OpenStack Tech Preview所提供的一種配置。安裝它非常簡單,並且它是一個很好的參考。在這種配置中,我們在所有伺服器上使用eth2作為虛擬機器的網路,所有虛擬機器流量使用這個網絡卡。Oracle OpenStack Tech Preview使用VLAN進行L2隔離,進而提供租戶和網路隔離,下圖展示了我們如何進行配置和部署:  

setup2

第一篇文章會略長,我們將聚焦於openstack網路的一些基本概念。我們將討論open vswitch、network namespaces、linux bridge、veth pairs等幾個元件。注意這裡不打算全面介紹這些元件,只是為了理解openstack網路架構。可以通過網路上的其他資源進一步瞭解這些元件。

Open vSwitch (OVS)

在Oracle OpenStack Tech Preview中用於連線虛擬機器和物理網口(如上例中的eth2),就像上邊部署圖所示。OVS包含bridages和ports,OVS bridges不同於與linux bridge(使用brctl命令建立)。讓我們先看下OVS的結構,使用如下命令:

# ovs-vsctl show
7ec51567-ab42-49e8-906d-b854309c9edf
    Bridge br-int
        Port br-int
            Interface br-int
                type: internal
        Port "int-br-eth2"
            Interface "int-br-eth2"
    Bridge "br-eth2"
        Port "br-eth2"
            Interface "br-eth2"
                type: internal
        Port "eth2"
            Interface "eth2"
        Port "phy-br-eth2"
            Interface "phy-br-eth2"
ovs_version: "1.11.0"

我們看到標準的部署在compute node上的OVS,擁有兩個網橋,每個有若干相關聯的port。上邊的例子是在一個沒有任何虛擬機器的計算節點上。我們可以看到eth2連線到個叫br-eth2的網橋上,我們還看到兩個叫“int-br-eth2"和”phy-br-eth2“的port,事實上是一個veth pair,作為虛擬網線連線兩個bridages。我們會在後邊討論veth paris。

當我們建立一個虛擬機器,br-int網橋上會建立一個port,這個port最終連線到虛擬機器(我們會在後邊討論這個連線)。這裡是啟動一個虛擬機器後的OVS結構:  

# ovs-vsctl show
efd98c87-dc62-422d-8f73-a68c2a14e73d
    Bridge br-int
        Port "int-br-eth2"
            Interface "int-br-eth2"
        Port br-int
            Interface br-int
                type: internal
        Port "qvocb64ea96-9f"
            tag: 1
            Interface "qvocb64ea96-9f"
    Bridge "br-eth2"
        Port "phy-br-eth2"
            Interface "phy-br-eth2"
        Port "br-eth2"
            Interface "br-eth2"
                type: internal
        Port "eth2"
            Interface "eth2"
ovs_version: "1.11.0"

”br-int“網橋現在有了一個新的port"qvocb64ea96-9f" 連線VM,並且被標記為vlan1。虛擬機器的每個網絡卡都需要對應在"br-int”網橋上建立一個port。

OVS中另一個有用的命令是dump-flows,以下為例子: 

# ovs-ofctl dump-flows br-int
NXST_FLOW reply (xid=0x4):
cookie=0x0, duration=735.544s, table=0, n_packets=70, n_bytes=9976,idle_age=17, priority=3,in_port=1,dl_vlan=1000 actions=mod_vlan_vid:1,NORMAL
cookie=0x0, duration=76679.786s, table=0, n_packets=0, n_bytes=0,idle_age=65534, hard_age=65534, priority=2,in_port=1 actions=drop
cookie=0x0, duration=76681.36s, table=0, n_packets=68, n_bytes=7950,idle_age=17, hard_age=65534, priority=1 actions=NORMAL

如上所述,VM相連的port使用了Vlan tag 1。然後虛擬機器網路(eth2)上的port使用tag1000。OVS會修改VM和物理網口間所有package的vlan。在openstack中,OVS agent 控制open vswitch中的flows,使用者不需要進行操作。如果你想了解更多的如何控制open vswitch中的流,可以參考http://openvswitch.org中對ovs-ofctl的描述。 

Network Namespaces (netns)

網路namespace是linux上一個很cool的特性,它的用途很多。在openstack網路中被廣泛使用。網路namespace是擁有獨立的網路配置隔離容器,並且該網路不能被其他名字空間看到。網路名字空間可以被用於封裝特殊的網路功能或者在對網路服務隔離的同時完成一個複雜的網路設定。在Oracle OpenStack Tech Preview中我們使用最新的R3企業版核心,該核心提供給了對netns的完整支援。

通過如下例子我們展示如何使用netns命令控制網路namespaces。定義一個新的namespace:

# ip netns add my-ns
# ip netns list
my-ns


我們說過namespace是一個隔離的容器,我們可以在namspace中進行各種操作,比如ifconfig命令。

# ip netns exec my-ns ifconfig -a
lo        Link encap:Local Loopback
          LOOPBACK  MTU:16436 Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
          RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)

我們可以在namespace中執行任何命令,比如對debug非常有用的tcddump命令,我們使用ping、ssh、iptables命令。連線namespace和外部:連線到namespace和namespace直接連線的方式有很多,我們主要聚集在openstack中使用的方法。openstack使用了OVS和網路namespace的組合。OVS定義介面,然後我們將這些介面加入namespace中。
# ip netns exec my-ns ifconfig -a
lo        Link encap:Local Loopback
          LOOPBACK  MTU:65536 Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
          RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)

my-port   Link encap:Ethernet HWaddr 22:04:45:E2:85:21
          BROADCAST  MTU:1500 Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
          RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)

現在我們可以增加更多的ports到OVS bridge,並且連線到其他namespace或者其他裝置比如物理網絡卡。Neutron使用網路namespace來實現網路服務,如DHCP、routing、gateway、firewall、load balance等。下一篇文章我們會討論更多細節 。

Linux bridge and veth pairs

Linux bridge用於連線OVS port和虛擬機器。ports負責連通OVS bridge和linux bridge或者兩者與虛擬機器。linux bridage主要用於安全組增強。安全組通過iptables實現,iptables只能用於linux bridage而非OVS bridage。

Veth對在openstack網路中大量使用,也是debug網路問題的很好工具。Veth對是一個簡單的虛擬網線,所以一般成對出現。通常Veth對的一端連線到bridge,另一端連線到另一個bridge或者留下在作為一個網口使用。

這個例子中,我們將建立一些veth對,把他們連線到bridge上並測試聯通性。這個例子用於通常的Linux伺服器而非openstack節點:建立一個veth對,注意我們定義了兩端的名字:

# ip link add veth0 type veth peer name veth1

# ifconfig -a

.

.

veth0     Link encap:Ethernet HWaddr 5E:2C:E6:03:D0:17

          BROADCAST MULTICAST  MTU:1500 Metric:1

          RX packets:0 errors:0 dropped:0 overruns:0 frame:0

          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0

collisions:0 txqueuelen:1000

          RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)

veth1     Link encap:Ethernet HWaddr E6:B6:E2:6D:42:B8

          BROADCAST MULTICAST  MTU:1500 Metric:1

          RX packets:0 errors:0 dropped:0 overruns:0 frame:0

          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0

collisions:0 txqueuelen:1000

          RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)

.

.
為了讓例子更有意義,我們將建立如下配置:
veth0 => veth1 =>br-eth3 => eth3 ======> eth2 on another Linux server

br-eht3: 一個基本的Linux bridge,連線veth1和eth3eth3: 一個沒有設定IP的物理網口,該網口連線著斯有網路eth2: 遠端Linux伺服器上的一個物理網口,連線著私有網路並且被配置了IP(50.50.50.1)一旦我們建立了這個配置,我們將通過veth0 ping 50.50.50.1這個遠端IP,從而測試網路聯通性:
# brctl addbr br-eth3

# brctl addif br-eth3 eth3

# brctl addif br-eth3 veth1

# brctl show

bridge name     bridge id               STP enabled     interfaces

br-eth3         8000.00505682e7f6       no              eth3

                                                        veth1

# ifconfig veth0 50.50.50.50

# ping -I veth0 50.50.50.51

PING 50.50.50.51 (50.50.50.51) from 50.50.50.50 veth0: 56(84) bytes of data.

64 bytes from 50.50.50.51: icmp_seq=1 ttl=64 time=0.454 ms

64 bytes from 50.50.50.51: icmp_seq=2 ttl=64 time=0.298 ms

# ethtool -S veth1NIC statistics:peer_ifindex: 12# ip link..12: veth0: mtu 1500 qdisc pfifo_fast state UP qlen 1000

如果命名不像例子中這麼顯而易見,導致我們無法支援veth裝置的兩端,我們可以使用ethtool命令查詢。ethtool命令返回index號,通過ip link命令檢視對應的裝置:
# ethtool -S veth1

NIC statistics:

peer_ifindex: 12

# ip link

.

.

12: veth0:  mtu 1500 qdisc pfifo_fast state UP qlen 1000


總結

文章中,我們快速瞭解了OVS/網路namespaces/Linux bridges/veth對。這些元件在openstack網路架構中大量使用,理解這些元件有助於我們理解不同的網路場景。下篇文章中,我們會了解虛擬機器之間/虛擬機器與外部網路之間如何進行通訊。