深入理解Openstack之Basic Use Cases
在上一篇文章中,我們了解了幾個(gè)網(wǎng)絡(luò)組件,如openvswitch/network namespace/Linux bridges/veth pairs。這篇文章中,我們將用3個(gè)簡(jiǎn)單的use case,展示這些基本網(wǎng)絡(luò)組件如何以工作從而實(shí)現(xiàn)openstack的SDN方案。
在這些use case中,我們會(huì)了解整個(gè)網(wǎng)絡(luò)配置和他們?nèi)绾我黄疬\(yùn)行。use case如下:
- 創(chuàng)建網(wǎng)絡(luò)——我們創(chuàng)建網(wǎng)絡(luò)時(shí),發(fā)生了什么。如何創(chuàng)建多個(gè)隔離的網(wǎng)絡(luò)。
- 創(chuàng)建虛擬機(jī)——一旦我們有了網(wǎng)絡(luò),我們可以創(chuàng)建虛擬機(jī)并將其接入網(wǎng)絡(luò)。
- 虛擬機(jī)的DHCP請(qǐng)求——opensack可以自動(dòng)為虛擬機(jī)配置IP。通過openstack neutron控制的DHCP服務(wù)完成。我們來了解這個(gè)服務(wù)如何運(yùn)行,DHCP請(qǐng)求和回應(yīng)是什么樣子的?
這篇文章中,我們會(huì)展示網(wǎng)絡(luò)連接的原理,我們會(huì)了解網(wǎng)絡(luò)包如何從A到B。我們先了解已經(jīng)完成的網(wǎng)絡(luò)配置是什么樣子的?然后我們討論這些網(wǎng)絡(luò)配置是如何以及何時(shí)創(chuàng)建的?我個(gè)人認(rèn)為,通過例子和具體實(shí)踐看到真實(shí)的網(wǎng)絡(luò)接口如何工作以及如何將他們連接起來是非常有價(jià)值的。然后,一切真相大白,我們知道網(wǎng)絡(luò)連接如何工作,在后邊的文章中,我將進(jìn)一步解釋neutron如何配置這些組件,從而提供這樣的網(wǎng)絡(luò)連接能力。
我推薦在你自己的環(huán)境上嘗試這些例子或者使用Oracle Openstack Tech Preview。完全理解這些網(wǎng)絡(luò)場(chǎng)景,對(duì)我們調(diào)查openstack環(huán)境中的網(wǎng)絡(luò)問題非常有幫助。
Use case #1: Create Network
創(chuàng)建network的操作非常簡(jiǎn)單。我們可以使用GUI或者命令行完成。openstack的網(wǎng)絡(luò)僅供創(chuàng)建該網(wǎng)絡(luò)的租戶使用。當(dāng)然如果這個(gè)網(wǎng)絡(luò)是“shared”,它也可以被其他所有租戶使用。一個(gè)網(wǎng)絡(luò)可以有多個(gè)subnets,但是為了演示目的和簡(jiǎn)單,我們僅為每一個(gè)network創(chuàng)建一個(gè)subnet。通過命令行創(chuàng)建network:
- # 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 |
- +---------------------------+--------------------------------------+
為這個(gè)network創(chuàng)建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 |
- +------------------+------------------------------------------------+
現(xiàn)在我們有了一個(gè)network和subnet,網(wǎng)絡(luò)拓?fù)湎襁@樣:
現(xiàn)在讓我們深入看下到底發(fā)生了什么?在控制節(jié)點(diǎn),我們一個(gè)新的namespace被創(chuàng)建:
- # ip netns list
- qdhcp-5f833617-6179-4797-b7c0-7d420d84040c
這個(gè)namespace的名字是qdhcp- (參見上邊),讓我們深入namespace中看看有什么?
- # 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
我們發(fā)下在namespace下有兩個(gè)網(wǎng)絡(luò)接口,一個(gè)是loop設(shè)備,另一個(gè)叫“tap26c9b807-7c”。這個(gè)接口設(shè)置了IP地址 10.10.10.3,他會(huì)接收dhcp請(qǐng)求(后邊會(huì)講)。接下來我們來跟蹤下“tap26c9b807-7c”的網(wǎng)絡(luò)連接性。我們從OVS上看下這個(gè)接 口所連接的OVS網(wǎng)橋"br-int"。
- # 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",這個(gè)veth pari連接兩個(gè)OVS網(wǎng)橋"br-eth2"和"br-int"。上一篇文章中,我們解釋過如何通過ethtool命令查看veth pairs的兩端。就如下邊的例子:
- # 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”連接到網(wǎng)橋"br-eth2",這個(gè)網(wǎng)橋的一個(gè)網(wǎng)口是物理網(wǎng)卡eth2。這意味著我們創(chuàng)建的網(wǎng)絡(luò)創(chuàng)建了一個(gè)連接到了物理網(wǎng)卡eth2的namespace。eth2所在的虛擬機(jī)網(wǎng)絡(luò)會(huì)連接所有的虛擬機(jī)的。
關(guān)于網(wǎng)絡(luò)隔離:
Openstack支持創(chuàng)建多個(gè)隔離的網(wǎng)絡(luò),也可以使用多種機(jī)制完成網(wǎng)絡(luò)間的彼此隔離。這些隔離機(jī)制包括 VLANs/VxLANs/GRE tunnels,這個(gè)在我們部署openstack環(huán)境時(shí)配置。本文中我們選擇了VLANs。當(dāng)使用VLAN標(biāo)簽作為隔離機(jī)制,Neutron會(huì)從預(yù)定義 好的VLAN池中選擇一個(gè)VLAN標(biāo)簽,并分配給一個(gè)新創(chuàng)建的network。通過分配VLAN標(biāo)簽給network,Neutron允許在一個(gè)物理網(wǎng)卡 上創(chuàng)建多個(gè)隔離的網(wǎng)絡(luò)。與其他的平臺(tái)的***的區(qū)別是,用戶不需要負(fù)責(zé)管理VLAN如何分配給networks。Neutron會(huì)負(fù)責(zé)管理分配VLAN標(biāo) 簽,并負(fù)責(zé)回收。在我們的例子中,net1使用VLAN標(biāo)簽1000,這意味著連接到該網(wǎng)絡(luò)的虛擬機(jī),發(fā)出的包會(huì)被打上VLAN標(biāo)簽1000然后發(fā)送到物 理網(wǎng)絡(luò)中。對(duì)namespace也是同樣的,如果我們希望namespace連接到某個(gè)特定網(wǎng)絡(luò),我們需要確保這個(gè)namespace發(fā)出的/接收的包被 正確的打上了標(biāo)簽。
在上邊的例子中,namespace中的網(wǎng)絡(luò)接口“tap26c9b807-7c”被分配了VLAN標(biāo)簽1。如果我們從 OVS觀察下,會(huì)發(fā)現(xiàn)VLAN1會(huì)被改為VLAN1000,當(dāng)包進(jìn)入eth2所在的uxniji網(wǎng)絡(luò)。反之亦然。我們通過OVS的dump-flows命 令可以看到進(jìn)入虛擬機(jī)網(wǎng)絡(luò)的網(wǎng)絡(luò)包在br-eth2上進(jìn)行了VLAN標(biāo)簽的修改:
- # 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
從網(wǎng)絡(luò)接口到namespace我們看到VLAN標(biāo)簽的修改如下:
- # 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
總之,當(dāng)用戶創(chuàng)建network,neutrong會(huì)創(chuàng)建一個(gè)namespace,這個(gè)namespace通過OVS連接到虛擬機(jī)網(wǎng)絡(luò)。OVS還負(fù) 責(zé)namespace與虛擬機(jī)網(wǎng)絡(luò)之間VLAN標(biāo)簽的修改?,F(xiàn)在,讓我們看下創(chuàng)建虛擬機(jī)時(shí),發(fā)生了什么?虛擬機(jī)是怎么連接到虛擬機(jī)網(wǎng)絡(luò)的?
#p#
Use case #2: Launch a VM
從Horizon或者命令行創(chuàng)建并啟動(dòng)一個(gè)虛擬機(jī),下圖是從Horzion創(chuàng)建的例子:
掛載網(wǎng)絡(luò)并啟動(dòng)虛擬機(jī):
一旦虛擬機(jī)啟動(dòng)并運(yùn)行,我們發(fā)下nova支持給虛擬機(jī)綁定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命令顯示虛擬機(jī)在運(yùn)行中,并被分配了IP 10.10.10.2。我們通過虛擬機(jī)定義文件,查看下虛擬機(jī)與虛擬機(jī)網(wǎng)絡(luò)之間的連接性。虛擬機(jī)的配置文件在目錄/var/lib/nova /instances//下可以找到。通過查看虛擬機(jī)定義文件,libvirt.xml,我們可以看到虛擬機(jī)連接到網(wǎng)絡(luò)接口 “tap53903a95-82”,這個(gè)網(wǎng)絡(luò)接口連接到了Linux網(wǎng)橋 “qbr53903a95-82”:
- <interface type="bridge">
- <mac address="fa:16:3e:fe:c7:87"/>
- <source bridge="qbr53903a95-82"/>
- <target dev="tap53903a95-82"/>
- </interface>
通過brctl查看網(wǎng)橋信息如下:
- # brctl show
- bridge name bridge id STP enabled interfaces
- qbr53903a95-82 8000.7e7f3282b836 no qvb53903a95-82
- tap53903a95-82
網(wǎng)橋有兩個(gè)網(wǎng)絡(luò)接口,一個(gè)連接到虛擬機(jī)(“tap53903a95-82 “),另一個(gè)( “qvb53903a95-82”)連接到OVS網(wǎng)橋”br-int"。
- # ovs-vsctl show
- 3c42f80-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網(wǎng)橋“br-int"連接到"br-eth2",通過veth pair(int-br-eth2,phy-br-eth2 ),br-eth2連接到物理網(wǎng)卡eth2。整個(gè)流入如下:
- 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.
與虛擬機(jī)相連的Linux bridage主要用于基于Iptables的安全組設(shè)置。安全組用于對(duì)虛擬機(jī)的網(wǎng)絡(luò)隔離進(jìn)行增強(qiáng),由于iptables不能用于OVS網(wǎng)橋,因此我們使用了Linux網(wǎng)橋。后邊我們會(huì)看到Linux網(wǎng)橋的規(guī)則設(shè)置。
VLAN tags:我們?cè)?**個(gè)use case中提到過,net1使用VLAN標(biāo)簽1000,通過OVS我們看到qvo41f1ebcf-7c使用VLAN標(biāo)簽3。VLAN標(biāo)簽從3到1000 的轉(zhuǎn)換在OVS中完成,通過br-eth2中實(shí)現(xiàn)。 總結(jié)如下,虛擬機(jī)通過一組網(wǎng)絡(luò)設(shè)備連入虛擬機(jī)網(wǎng)絡(luò)。虛擬機(jī)和網(wǎng)絡(luò)之間,VLAN標(biāo)簽被修改。
#p#
Use case #3: Serving a DHCP request coming from the virtual machine
之前的use case中,我們看到了一個(gè)叫dhcp-的namespace和虛擬機(jī),兩者最終連接到物理網(wǎng)絡(luò)eth2。他們都會(huì)被打上VLAN標(biāo)簽1000。我們看到該namespace中的網(wǎng)絡(luò)接口使用IP 10.10.10.3。因?yàn)樘摂M機(jī)和namespace彼此連接并在相同子網(wǎng),因此可以ping到對(duì)方。如下圖,虛擬機(jī)中網(wǎng)絡(luò)接口被分配了IP 10.10.10.2,我們嘗試ping namespace中的網(wǎng)絡(luò)接口的IP:
namespace與虛擬機(jī)之間連通,并且可以互相ping通,對(duì)于定位問題非常有用。我們可以從虛擬機(jī)ping通namespace,可以使用tcpdump或其他工具定位網(wǎng)絡(luò)中斷問題。
為了響應(yīng)虛擬機(jī)的dhcp請(qǐng)求,Neutron使用了”dnsmasq“的Linux工具,這個(gè)工具是一個(gè)輕量的DNS、DHCP服務(wù),
- 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服務(wù)在namespace中連接到了一個(gè)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
之前的console輸出可以看到虛擬機(jī)MAC為fa:16:3e:fe:c7:87 。這個(gè)mac地址與IP 10.10.10.2 關(guān)聯(lián),當(dāng)包含該MAC的DHCP請(qǐng)求到達(dá),dnsmasq返回10.10.10.2。在這個(gè)初始過程(可以重啟網(wǎng)絡(luò)服務(wù)觸發(fā))中從namespace中 看,可以看到如下的DHCP請(qǐng)求:
- # 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
總之,DHCP服務(wù)由dnsmasq提供,這個(gè)服務(wù)由Neutron配置,監(jiān)聽在DHCP namespace中的網(wǎng)絡(luò)接口上。Neutron還配置dnsmasq中的MAC/IP映射關(guān)系,所以當(dāng)DHCP請(qǐng)求時(shí)會(huì)受到分配給它的IP。
總結(jié)
本文,我們基于之前講解的各種網(wǎng)絡(luò)組件,分析了三種use case下網(wǎng)絡(luò)如何連通的。這些use cases對(duì)了解整個(gè)網(wǎng)絡(luò)棧以及了解虛擬機(jī)/計(jì)算節(jié)點(diǎn)/DHCP namespace直接如何連通很有幫助。
根據(jù)我們的分析,我們確信啟動(dòng)虛擬機(jī)、虛擬機(jī)發(fā)出DHCP請(qǐng)求、虛擬機(jī)收到正確的IP后這個(gè)網(wǎng)絡(luò)按照我們預(yù)想的工作。我們看到一個(gè)包經(jīng)過一長(zhǎng)串路徑最終到達(dá)目的地,如果這一切成功,意味著這些組件功能正常。
原文出自:http://blog.csdn.net/halcyonbaby/article/details/41578293