原文地址: https://blogs.oracle.com/ronen/entry/diving_into_openstack_network_architecture1
html
在上一篇文章中,咱們瞭解了幾個網絡組件,如openvswitch/network namespace/Linux bridges/veth pairs。這篇文章中,咱們將用3個簡單的use case,展現這些基本網絡組件如何以工做從而實現openstack的SDN方案。
在這些use case中,咱們會了解整個網絡配置和他們如何一塊兒運行。use case以下: git
這篇文章中,咱們會展現網絡鏈接的原理,咱們會了解網絡包如何從A到B。咱們先了解已經完成的網絡配置是什麼樣子的?而後咱們討論這些網絡配置是如何以及什麼時候建立的?我我的認爲,經過例子和具體實踐看到真實的網絡接口如何工做以及如何將他們鏈接起來是很是有價值的。而後,一切真相大白,咱們知道網絡鏈接如何工做,在後邊的文章中,我將進一步解釋neutron如何配置這些組件,從而提供這樣的網絡鏈接能力。github
我推薦在你本身的環境上嘗試這些例子或者使用Oracle Openstack Tech Preview。徹底理解這些網絡場景,對咱們調查openstack環境中的網絡問題很是有幫助。 安全
建立network的操做很是簡單。咱們可使用GUI或者命令行完成。openstack的網絡僅供建立該網絡的租戶使用。固然若是這個網絡是「shared」,它也能夠被其餘全部租戶使用。一個網絡能夠有多個subnets,可是爲了演示目的和簡單,咱們僅爲每個network建立一個subnet。經過命令行建立network:
cookie
# neutron net-create net1 Created a new network: +---------------------------+--------------------------------------+ | Field | Value | +---------------------------+--------------------------------------+ | admin_state_up | True | | id | 5f833617-6179-4797-b7c0-7d420d84040c | | name | net1 | | provider:network_type | vlan | | provider:physical_network | default | | provider:segmentation_id | 1000 | | shared | False | | status | ACTIVE | | subnets | | | tenant_id | 9796e5145ee546508939cd49ad59d51f | +---------------------------+--------------------------------------+
爲這個network建立subnet::
# neutron subnet-create net1 10.10.10.0/24 Created a new subnet: +------------------+------------------------------------------------+ | Field | Value | +------------------+------------------------------------------------+ | allocation_pools | {"start": "10.10.10.2", "end": "10.10.10.254"} | | cidr | 10.10.10.0/24 | | dns_nameservers | | | enable_dhcp | True | | gateway_ip | 10.10.10.1 | | host_routes | | | id | 2d7a0a58-0674-439a-ad23-d6471aaae9bc | | ip_version | 4 | | name | | | network_id | 5f833617-6179-4797-b7c0-7d420d84040c | | tenant_id | 9796e5145ee546508939cd49ad59d51f | +------------------+------------------------------------------------+
如今咱們有了一個network和subnet,網絡拓撲像這樣:網絡
如今讓咱們深刻看下到底發生了什麼?在控制節點,咱們一個新的namespace被建立:
oracle
# ip netns list qdhcp-5f833617-6179-4797-b7c0-7d420d84040c
這個namespace的名字是qdhcp- (參見上邊),讓咱們深刻namespace中看看有什麼?
dom
# ip netns exec qdhcp-5f833617-6179-4797-b7c0-7d420d84040c ip addr 1: lo: mtu 65536 qdisc noqueue state UNKNOWN link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo inet6 ::1/128 scope host valid_lft forever preferred_lft forever 12: tap26c9b807-7c: mtu 1500 qdisc noqueue state UNKNOWN link/ether fa:16:3e:1d:5c:81 brd ff:ff:ff:ff:ff:ff inet 10.10.10.3/24 brd 10.10.10.255 scope global tap26c9b807-7c inet6 fe80::f816:3eff:fe1d:5c81/64 scope link valid_lft forever preferred_lft forever
咱們發下在namespace下有兩個網絡接口,一個是loop設備,另外一個叫「tap26c9b807-7c」。這個接口設置了IP地址10.10.10.3,他會接收dhcp請求(後邊會講)。接下來咱們來跟蹤下「tap26c9b807-7c」的網絡鏈接性。咱們從OVS上看下這個接口所鏈接的OVS網橋"br-int"。tcp
# ovs-vsctl show 8a069c7c-ea05-4375-93e2-b9fc9e4b3ca1 Bridge "br-eth2" Port "br-eth2" Interface "br-eth2" type: internal Port "eth2" Interface "eth2" Port "phy-br-eth2" Interface "phy-br-eth2" Bridge br-ex Port br-ex Interface br-ex type: internal Bridge br-int Port "int-br-eth2" Interface "int-br-eth2" Port "tap26c9b807-7c" tag: 1 Interface "tap26c9b807-7c" type: internal Port br-int Interface br-int type: internal ovs_version: "1.11.0"
由上可知,veth pair的兩端「int-br-eth2」 和 "phy-br-eth2",這個veth pari鏈接兩個OVS網橋"br-eth2"和"br-int"。上一篇文章中,咱們解釋過如何經過ethtool命令查看veth pairs的兩端。就以下邊的例子:
ide
# ethtool -S int-br-eth2 NIC statistics: peer_ifindex: 10 . . #ip link . . 10: phy-br-eth2: mtu 1500 qdisc pfifo_fast state UP qlen 1000 . .
注意「phy-br-eth2」鏈接到網橋"br-eth2",這個網橋的一個網口是物理網卡eth2。這意味着咱們建立的網絡建立了一個鏈接到了物理網卡eth2的namespace。eth2所在的虛擬機網絡會鏈接全部的虛擬機的。
Openstack支持建立多個隔離的網絡,也可使用多種機制完成網絡間的彼此隔離。這些隔離機制包括VLANs/VxLANs/GRE tunnels,這個在咱們部署openstack環境時配置。本文中咱們選擇了VLANs。當使用VLAN標籤做爲隔離機制,Neutron會從預約義好的VLAN池中選擇一個VLAN標籤,並分配給一個新建立的network。經過分配VLAN標籤給network,Neutron容許在一個物理網卡上建立多個隔離的網絡。與其餘的平臺的最大的區別是,用戶不須要負責管理VLAN如何分配給networks。Neutron會負責管理分配VLAN標籤,並負責回收。在咱們的例子中,net1使用VLAN標籤1000,這意味着鏈接到該網絡的虛擬機,發出的包會被打上VLAN標籤1000而後發送到物理網絡中。對namespace也是一樣的,若是咱們但願namespace鏈接到某個特定網絡,咱們須要確保這個namespace發出的/接收的包被正確的打上了標籤。
在上邊的例子中,namespace中的網絡接口「tap26c9b807-7c」被分配了VLAN標籤1。若是咱們從OVS觀察下,會發現VLAN1會被改成VLAN1000,當包進入eth2所在的uxniji網絡。反之亦然。咱們經過OVS的dump-flows命令能夠看到進入虛擬機網絡的網絡包在br-eth2上進行了VLAN標籤的修改:
# ovs-ofctl dump-flows br-eth2 NXST_FLOW reply (xid=0x4): cookie=0x0, duration=18669.401s, table=0, n_packets=857, n_bytes=163350, idle_age=25, priority=4,in_port=2,dl_vlan=1 actions=mod_vlan_vid:1000,NORMAL cookie=0x0, duration=165108.226s, table=0, n_packets=14, n_bytes=1000, idle_age=5343, hard_age=65534, priority=2,in_port=2 actions=drop cookie=0x0, duration=165109.813s, table=0, n_packets=1671, n_bytes=213304, idle_age=25, hard_age=65534, priority=1 actions=NORMAL
從網絡接口到namespace咱們看到VLAN標籤的修改以下:
# ovs-ofctl dump-flows br-int NXST_FLOW reply (xid=0x4): cookie=0x0, duration=18690.876s, table=0, n_packets=1610, n_bytes=210752, idle_age=1, priority=3,in_port=1,dl_vlan=1000 actions=mod_vlan_vid:1,NORMAL cookie=0x0, duration=165130.01s, table=0, n_packets=75, n_bytes=3686, idle_age=4212, hard_age=65534, priority=2,in_port=1 actions=drop cookie=0x0, duration=165131.96s, table=0, n_packets=863, n_bytes=160727, idle_age=1, hard_age=65534, priority=1 actions=NORMAL
總之,當用戶建立network,neutrong會建立一個namespace,這個namespace經過OVS鏈接到虛擬機網絡。OVS還負責namespace與虛擬機網絡之間VLAN標籤的修改。如今,讓咱們看下建立虛擬機時,發生了什麼?虛擬機是怎麼鏈接到虛擬機網絡的?
從Horizon或者命令行建立並啓動一個虛擬機,下圖是從Horzion建立的例子:
掛載網絡並啓動虛擬機:
一旦虛擬機啓動並運行,咱們發下nova支持給虛擬機綁定IP:
# nova list +--------------------------------------+--------------+--------+------------+-------------+-----------------+ | ID | Name | Status | Task State | Power State | Networks | +--------------------------------------+--------------+--------+------------+-------------+-----------------+ | 3707ac87-4f5d-4349-b7ed-3a673f55e5e1 | Oracle Linux | ACTIVE | None | Running | net1=10.10.10.2 | +--------------------------------------+--------------+--------+------------+-------------+-----------------+
nova list命令顯示虛擬機在運行中,並被分配了IP 10.10.10.2。咱們經過虛擬機定義文件,查看下虛擬機與虛擬機網絡之間的鏈接性。虛擬機的配置文件在目錄/var/lib/nova/instances//下能夠找到。經過查看虛擬機定義文件,libvirt.xml,咱們能夠看到虛擬機鏈接到網絡接口「tap53903a95-82」,這個網絡接口鏈接到了Linux網橋 「qbr53903a95-82」:
<interface type="bridge"> <mac address="fa:16:3e:fe:c7:87"/> <source bridge="qbr53903a95-82"/> <target dev="tap53903a95-82"/> </interface>
# brctl show bridge name bridge id STP enabled interfaces qbr53903a95-82 8000.7e7f3282b836 no qvb53903a95-82 tap53903a95-82
網橋有兩個網絡接口,一個鏈接到虛擬機(「tap53903a95-82 「),另外一個( 「qvb53903a95-82」)鏈接到OVS網橋」br-int"。
# ovs-vsctl show 83c42f80-77e9-46c8-8560-7697d76de51c Bridge "br-eth2" Port "br-eth2" Interface "br-eth2" type: internal Port "eth2" Interface "eth2" Port "phy-br-eth2" Interface "phy-br-eth2" Bridge br-int Port br-int Interface br-int type: internal Port "int-br-eth2" Interface "int-br-eth2" Port "qvb53903a95-82" tag: 3 Interface "qvb53903a95-82" ovs_version: "1.11.0"
咱們以前看過,OVS網橋「br-int"鏈接到"br-eth2",經過veth pair(int-br-eth2,phy-br-eth2 ),br-eth2鏈接到物理網卡eth2。整個流入以下:
VM -> tap53903a95-82 (virtual interface) -> qbr53903a95-82 (Linux bridge) -> qvb53903a95-82 (interface connected from Linux bridge to OVS bridge br-int) -> int-br-eth2 (veth one end) -> phy-br-eth2 (veth the other end) -> eth2 physical interface.
VLAN tags:咱們在第一個use case中提到過,net1使用VLAN標籤1000,經過OVS咱們看到qvo41f1ebcf-7c使用VLAN標籤3。VLAN標籤從3到1000的轉換在OVS中完成,經過br-eth2中實現。 總結以下,虛擬機經過一組網絡設備連入虛擬機網絡。虛擬機和網絡之間,VLAN標籤被修改。
以前的use case中,咱們看到了一個叫dhcp-的namespace和虛擬機,二者最終鏈接到物理網絡eth2。他們都會被打上VLAN標籤1000。咱們看到該namespace中的網絡接口使用IP 10.10.10.3。由於虛擬機和namespace彼此鏈接並在相同子網,所以能夠ping到對方。以下圖,虛擬機中網絡接口被分配了IP 10.10.10.2,咱們嘗試ping namespace中的網絡接口的IP:
namespace與虛擬機之間連通,而且能夠互相ping通,對於定位問題很是有用。咱們能夠從虛擬機ping通namespace,可使用tcpdump或其餘工具定位網絡中斷問題。
爲了響應虛擬機的dhcp請求,Neutron使用了」dnsmasq「的Linux工具,這個工具是一個輕量的DNS、DHCP服務,更多的信息請查看(http://www.thekelleys.org.uk/dnsmasq/docs/dnsmasq-man.html)。咱們能夠在控制節點經過PS命令看到:
dnsmasq --no-hosts --no-resolv --strict-order --bind-interfaces --interface=tap26c9b807-7c --except-interface=lo --pid-file=/var/lib/neutron/dhcp/5f833617-6179-4797-b7c0-7d420d84040c/pid --dhcp-hostsfile=/var/lib/neutron/dhcp/5f833617-6179-4797-b7c0-7d420d84040c/host --dhcp-optsfile=/var/lib/neutron/dhcp/5f833617-6179-4797-b7c0-7d420d84040c/opts --leasefile-ro --dhcp-range=tag0,10.10.10.0,static,120s --dhcp-lease-max=256 --conf-file= --domain=openstacklocal
DHCP服務在namespace中鏈接到了一個tap接口(「--interface=tap26c9b807-7c」),從hosts文件咱們能夠看到:
# cat /var/lib/neutron/dhcp/5f833617-6179-4797-b7c0-7d420d84040c/host fa:16:3e:fe:c7:87,host-10-10-10-2.openstacklocal,10.10.10.2
# ip netns exec qdhcp-5f833617-6179-4797-b7c0-7d420d84040c tcpdump -n 19:27:12.191280 IP 0.0.0.0.bootpc > 255.255.255.255.bootps: BOOTP/DHCP, Request from fa:16:3e:fe:c7:87, length 310 19:27:12.191666 IP 10.10.10.3.bootps > 10.10.10.2.bootpc: BOOTP/DHCP, Reply, length 325
本文,咱們基於以前講解的各類網絡組件,分析了三種use case下網絡如何連通的。這些use cases對了解整個網絡棧以及瞭解虛擬機/計算節點/DHCP namespace直接如何連通頗有幫助。根據咱們的分析,咱們確信啓動虛擬機、虛擬機發出DHCP請求、虛擬機收到正確的IP後這個網絡按照咱們預想的工做。咱們看到一個包通過一長串路徑最終到達目的地,若是這一切成功,意味着這些組件功能正常。下一篇文章中,咱們會學習更復雜的neutron服務並分析他們如何工做。