問題導讀
1.什么是VETH、qvb、qvo?
2.qbr的存在的作用是什么?
3.router服務的作用是什么?
如果不具有Linux網絡基礎,比如防火牆如何過濾ip、端口或則對openstack ovs了解不多,下面比較難懂一些。最好查看本站openstack網絡基礎知識。
openstack基礎之防火牆:Linux防火牆iptables入門教程
openstack集群網絡必備:路由知識補充
集群網絡必備:防火牆基礎知識補充
openstack安全組(防火牆)入門1——安全組之架構篇
OpenStack中的Security Group實現
有了這些基礎下面看的更容易一些,本文最起碼能夠學到一些基本的概念
概述
Neutron 的設計目標是實現“網絡即服務”,為了達到這一目標,在設計上遵循了基於“軟件定義網絡”實現網絡虛擬化的原則,在實現上充分利用了 Linux 系統上的各種網絡相關的技術。
理解了 Linux 系統上的這些概念將有利於快速理解 Neutron 的原理和實現。
涉及的 Linux 網絡技術
- bridge:網橋,Linux中用於表示一個能連接不同網絡設備的虛擬設備,linux中傳統實現的網橋類似一個hub設備,而ovs管理的網橋一般類似交換機。
- br-int:bridge-integration,綜合網橋,常用於表示實現主要內部網絡功能的網橋。
- br-ex:bridge-external,外部網橋,通常表示負責跟外部網絡通信的網橋。
- GRE:General Routing Encapsulation,一種通過封裝來實現隧道的方式。在openstack中一般是基於L3的gre,即original pkt/GRE/IP/Ethernet
- VETH:虛擬ethernet接口,通常以pair的方式出現,一端發出的網包,會被另一端接收,可以形成兩個網橋之間的通道。
- qvb:neutron veth, Linux Bridge-side
- qvo:neutron veth, OVS-side
- TAP設備:模擬一個二層的網絡設備,可以接受和發送二層網包。
- TUN設備:模擬一個三層的網絡設備,可以接受和發送三層網包。
- iptables:Linux 上常見的實現安全策略的防火牆軟件。
- Vlan:虛擬 Lan,同一個物理 Lan 下用標簽實現隔離,可用標號為1-4094。
- VXLAN:一套利用 UDP 協議作為底層傳輸協議的 Overlay 實現。一般認為作為 VLan 技術的延伸或替代者。
- namespace:用來實現隔離的一套機制,不同 namespace 中的資源之間彼此不可見。
基本概念
Neutron管理下面的實體:
- 網絡:隔離的 L2 域,可以是虛擬、邏輯或交換,同一個網絡中的主機彼此 L2 可見。
- 子網:隔離的 L3 域,IP 地址塊。其中每個機器有一個 IP,同一個子網的主機彼此 L3 可見。
- 端口:網絡上虛擬、邏輯或交換端口。 所有這些實體都是虛擬的,擁有自動生成的唯一標示id,支持CRUD功能,並在數據庫中跟蹤記錄狀態。
網絡
隔離的 L2 廣播域,一般是創建它的用戶所有。用戶可以擁有多個網絡。網絡是最基礎的,子網和端口都需要關聯到網絡上。
網絡上可以有多個子網。同一個網絡上的主機一般可以通過交換機或路由器連通起來。
子網
隔離的 L3 域,子網代表了一組分配了 IP 的虛擬機。每個子網必須有一個 CIDR 和關聯到一個網絡。IP 可以從 CIDR 或者用戶指定池中選取。
子網可能會有一個網關、一組 DNS 和主機路由。不同子網之間 L2 是互相不可見的,必須通過一個三層網關(即路由器)經過 L3 上進行通信。
端口
可以進出流量的接口,往往綁定上若干 MAC 地址和 IP 地址,以進行尋址。一般為虛擬交換機上的虛擬接口。
虛擬機掛載網卡到端口上,通過端口訪問網絡。當端口有 IP 的時候,意味着它屬於某個子網。
抽象系統架構
無論哪種具體的網絡虛擬化實現,在啟用 DVR 特性(J 版本以后支持)之前,所有流量(東西向、南北向)都需要經過網絡節點的轉發;DVR 特性則允許東西向流量和帶有 Floating IP 的南北向流量不經過網絡節點的轉發,直接從計算節點的外部網絡出去。
GRE 模式
下圖給出了在OpenStack中網絡實現的一個簡化的架構示意。
一般的,OpenStack中網絡實現包括vlan、gre、vxlan 等模式,此處以gre模式為例。

在OpenStack中,所有網絡有關的邏輯管理均在Network節點中實現,例如DNS、DHCP以及路由等。Compute節點上只需要對所部屬的虛擬機提供基本的網絡功能支持,包括隔離不同租戶的虛擬機和進行一些基本的安全策略管理(即security group)。
計算節點
qbr
br-int
Compute節點上包括兩台虛擬機VM1和VM2,分別經過一個網橋(如qbr-XXX)連接到 br-int 網橋上。br-int 網橋再經過 br-tun 網橋(物理網絡是 GRE 實現)連接到物理主機外部網絡。
對於物理網絡通過vlan來隔離的情況,則一般會存在一個br-eth網橋,替代 br-tun 網橋。
在VM1中,虛擬機的網卡實際上連接到了物理機的一個TAP設備(即A,常見名稱如tap-XXX)上,A則進一步通過VETH pair(A-B)連接到網橋qbr-XXX的端口vnet0(端口B)上,之后再通過VETH pair(C-D)連到br-int網橋上。一般C的名字格式為qvb-XXX,而D的名字格式為qvo-XXX。注意它們的名稱除了前綴外,后面的id都是一樣的,表示位於同一個虛擬機網絡到物理機網絡的連接上。
之所以TAP設備A沒有直接連接到網橋br-int上,是因為OpenStack需要通過iptables實現security group的安全策略功能。目前openvswitch並不支持應用iptables規則的Tap設備。
因為qbr的存在主要是為了輔助iptables來實現security group功能,有時候也被稱為firewall bridge。詳見security group部分的分析【后面篇章會給出】。
一個典型的br-int的端口如下所示:
[Shell]
純文本查看 復制代碼
01 |
# ovs-vsctl show |
02 |
Bridge br-int |
03 |
Port "qvo-XXX" |
04 |
tag: 1 |
05 |
Interface "qvo-XXX" |
06 |
Port patch-tun |
07 |
Interface patch-tun |
08 |
type : patch |
09 |
options: {peer=patch-int} |
10 |
Port br-int |
11 |
Interface br-int |
12 |
type : internal |
其中br-int為內部端口。
端口patch-tun(即端口E,端口號為1)連接到br-tun上,實現到外部網絡的隧道。 端口qvo-XXX(即端口D,端口號為2)帶有tag1,說明這個口是一個1號vlan的access端口。虛擬機發出的從該端口到達br-int的網包將被自動帶上vlan tag 1,而其他帶有vlan tag 1的網包則可以在去掉vlan tag后從該端口發出(具體請查詢vlan access端口)。這個vlan tag是用來實現不同網絡相互隔離的,比如租戶創建一個網絡(neutron net-create),則會被分配一個唯一的vlan tag。
br-int在GRE模式中作為一個NORMAL交換機使用,因此有效規則只有一條正常轉發。如果兩個在同一主機上的vm屬於同一個tenant的(同一個vlan tag),則它們之間的通信只需要經過br-int即可。
[Shell]
純文本查看 復制代碼
01 |
# ovs-ofctl dump-flows br-int |
02 |
NXST_FLOW reply (xid=0x4): |
03 |
cookie=0x0, duration=10727.864s, table=0, n_packets=198, n_bytes=17288, idle_age=13, priority=1 actions=NORMAL |
br-tun
一個典型的br-tun上的端口類似:
[Shell]
純文本查看 復制代碼
01 |
Bridge br-tun |
02 |
Port patch-int |
03 |
Interface patch-int |
04 |
type : patch |
05 |
options: {peer=patch-tun} |
06 |
Port "gre-1" |
07 |
Interface "gre-1" |
08 |
type : gre |
09 |
options: {in_key=flow, local_ip= "10.0.0.101" , out_key=flow, remote_ip= "10.0.0.100" } |
10 |
Port br-tun |
11 |
Interface br-tun |
12 |
type : internal |
其中patch-int(即端口F,端口號為1)是連接到br-int上的veth pair的端口,gre-1口(即端口G,端口號為2)對應vm到外面的隧道。
gre-1端口是虛擬gre端口,當網包發送到這個端口的時候,會經過內核封包,然后從10.0.0.101發送到10.0.0.100,即從本地的物理網卡(10.0.0.101)發出。
br-tun將帶有vlan tag的vm跟外部通信的流量轉換到對應的gre隧道,這上面要實現主要的轉換邏輯,規則要復雜,一般通過多張表來實現。
典型的轉發規則為:
[Shell]
純文本查看 復制代碼
01 |
# ovs-ofctl dump-flows br-tun |
02 |
NXST_FLOW reply (xid=0x4): |
03 |
cookie=0x0, duration=10970.064s, table=0, n_packets=189, n_bytes=16232, idle_age=16, priority=1,in_port=1 actions=resubmit(,1) |
04 |
cookie=0x0, duration=10906.954s, table=0, n_packets=29, n_bytes=5736, idle_age=16, priority=1,in_port=2 actions=resubmit(,2) |
05 |
cookie=0x0, duration=10969.922s, table=0, n_packets=3, n_bytes=230, idle_age=10962, priority=0 actions=drop |
06 |
cookie=0x0, duration=10969.777s, table=1, n_packets=26, n_bytes=5266, idle_age=16, priority=0,dl_dst=00:00:00:00:00:00/01:00:00:00:00:00 actions=resubmit(,20) |
07 |
cookie=0x0, duration=10969.631s, table=1, n_packets=163, n_bytes=10966, idle_age=21, priority=0,dl_dst=01:00:00:00:00:00/01:00:00:00:00:00 actions=resubmit(,21) |
08 |
cookie=0x0, duration=688.456s, table=2, n_packets=29, n_bytes=5736, idle_age=16, priority=1,tun_id=0x1 actions=mod_vlan_vid:1,resubmit(,10) |
09 |
cookie=0x0, duration=10969.488s, table=2, n_packets=0, n_bytes=0, idle_age=10969, priority=0 actions=drop |
10 |
cookie=0x0, duration=10969.343s, table=3, n_packets=0, n_bytes=0, idle_age=10969, priority=0 actions=drop |
11 |
cookie=0x0, duration=10969.2s, table=10, n_packets=29, n_bytes=5736, idle_age=16, priority=1 actions=learn(table=20,hard_timeout=300,priority=1,NXM_OF_VLAN_TCI[0..11],NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[],load:0->NXM_OF_VLAN_TCI[],load:NXM_NX_TUN_ID[]->NXM_NX_TUN_ID[],output:NXM_OF_IN_PORT[]),output:1 |
12 |
cookie=0x0, duration=682.603s, table=20, n_packets=26, n_bytes=5266, hard_timeout=300, idle_age=16, hard_age=16, priority=1,vlan_tci=0x0001/0x0fff,dl_dst=fa:16:3e:32:0d:db actions=load:0->NXM_OF_VLAN_TCI[],load:0x1->NXM_NX_TUN_ID[],output:2 |
13 |
cookie=0x0, duration=10969.057s, table=20, n_packets=0, n_bytes=0, idle_age=10969, priority=0 actions=resubmit(,21) |
14 |
cookie=0x0, duration=688.6s, table=21, n_packets=161, n_bytes=10818, idle_age=21, priority=1,dl_vlan=1 actions=strip_vlan,set_tunnel:0x1,output:2 |
15 |
cookie=0x0, duration=10968.912s, table=21, n_packets=2, n_bytes=148, idle_age=689, priority=0 actions=drop |
其中,表0中有3條規則:從端口1(即patch-int)來的,扔到表1,從端口2(即gre-1)來的,扔到表2。
[Shell]
純文本查看 復制代碼
01 |
cookie=0x0, duration=10970.064s, table=0, n_packets=189, n_bytes=16232, idle_age=16, priority=1,in_port=1 actions=resubmit(,1) |
02 |
cookie=0x0, duration=10906.954s, table=0, n_packets=29, n_bytes=5736, idle_age=16, priority=1,in_port=2 actions=resubmit(,2) |
03 |
cookie=0x0, duration=10969.922s, table=0, n_packets=3, n_bytes=230, idle_age=10962, priority=0 actions=drop |
表1有2條規則:如果是單播(00:00:00:00:00:00/01:00:00:00:00:00),則扔到表20;如果是多播等(01:00:00:00:00:00/01:00:00:00:00:00),則扔到表21。
[Shell]
純文本查看 復制代碼
01 |
cookie=0x0, duration=10969.777s, table=1, n_packets=26, n_bytes=5266, idle_age=16, priority=0,dl_dst=00:00:00:00:00:00/01:00:00:00:00:00 actions=resubmit(,20) |
02 |
cookie=0x0, duration=10969.631s, table=1, n_packets=163, n_bytes=10966, idle_age=21, priority=0,dl_dst=01:00:00:00:00:00/01:00:00:00:00:00 actions=resubmit(,21) |
表2有2條規則:如果是tunnel 1的網包,則修改其vlan id為1,並扔到表10;非tunnel 1的網包,則丟棄。
[Shell]
純文本查看 復制代碼
01 |
cookie=0x0, duration=688.456s, table=2, n_packets=29, n_bytes=5736, idle_age=16, priority=1,tun_id=0x1 actions=mod_vlan_vid:1,resubmit(,10) |
02 |
cookie=0x0, duration=10969.488s, table=2, n_packets=0, n_bytes=0, idle_age=10969, priority=0 actions=drop |
表3只有1條規則:丟棄。
表10有一條規則,基於learn行動來創建反向(從gre端口抵達,且目標是到vm的網包)的規則。learn行動並非標准的openflow行動,是openvswitch自身的擴展行動,這個行動可以根據流內容動態來修改流表內容。這條規則首先創建了一條新的流(該流對應vm從br-tun的gre端口發出的規則):其中table=20表示規則添加在表20;NXM_OF_VLAN_TCI[0..11]表示匹配包自帶的vlan id;NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[]表示L2目標地址需要匹配包的L2源地址;load:0->NXM_OF_VLAN_TCI[],去掉vlan,load:NXM_NX_TUN_ID[]->NXM_NX_TUN_ID[],添加tunnel號為原始tunnel號;output:NXM_OF_IN_PORT[],發出端口為原始包抵達的端口。最后規則將匹配的網包從端口1(即patch-int)發出。
[Shell]
純文本查看 復制代碼
01 |
cookie=0x0, duration=10969.2s, table=10, n_packets=29, n_bytes=5736, idle_age=16, priority=1 actions=learn(table=20,hard_timeout=300,priority=1,NXM_OF_VLAN_TCI[0..11],NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[],load:0->NXM_OF_VLAN_TCI[],load:NXM_NX_TUN_ID[]->NXM_NX_TUN_ID[],output:NXM_OF_IN_PORT[]),output:1 |
表20中有兩條規則,其中第一條即表10中規則利用learn行動創建的流表項,第2條提交其他流到表21。
[Shell]
純文本查看 復制代碼
01 |
cookie=0x0, duration=682.603s, table=20, n_packets=26, n_bytes=5266, hard_timeout=300, idle_age=16, hard_age=16, priority=1,vlan_tci=0x0001/0x0fff,dl_dst=fa:16:3e:32:0d:db actions=load:0->NXM_OF_VLAN_TCI[],load:0x1->NXM_NX_TUN_ID[],output:2 |
02 |
cookie=0x0, duration=10969.057s, table=20, n_packets=0, n_bytes=0, idle_age=10969, priority=0 actions=resubmit(,21) |
表21有2條規則,第一條是匹配所有目標vlan為1的網包,去掉vlan,然后從端口2(gre端口)發出。第二條是丟棄。
[Shell]
純文本查看 復制代碼
01 |
cookie=0x0, duration=688.6s, table=21, n_packets=161, n_bytes=10818, idle_age=21, priority=1,dl_vlan=1 actions=strip_vlan,set_tunnel:0x1,output:2 |
02 |
cookie=0x0, duration=10968.912s, table=21, n_packets=2, n_bytes=148, idle_age=689, priority=0 actions=drop |
這些規則所組成的整體轉發邏輯如下圖所示。

網絡節點
br-tun
[Shell]
純文本查看 復制代碼
01 |
Bridge br-tun |
02 |
Port br-tun |
03 |
Interface br-tun |
04 |
type : internal |
05 |
Port patch-int |
06 |
Interface patch-int |
07 |
type : patch |
08 |
options: {peer=patch-tun} |
09 |
Port "gre-2" |
10 |
Interface "gre-2" |
11 |
type : gre |
12 |
options: {in_key=flow, local_ip= "10.0.0.100" , out_key=flow, remote_ip= "10.0.0.101" } |
Compute節點上發往GRE隧道的網包最終抵達Network節點上的br-tun,該網橋的規則包括:
[Bash shell]
純文本查看 復制代碼
01 |
# ovs-ofctl dump-flows br-tun |
02 |
NXST_FLOW reply (xid=0x4): |
03 |
cookie=0x0, duration=19596.862s, table=0, n_packets=344, n_bytes=66762, idle_age=4, priority=1,in_port=1 actions=resubmit(,1) |
04 |
cookie=0x0, duration=19537.588s, table=0, n_packets=625, n_bytes=125972, idle_age=4, priority=1,in_port=2 actions=resubmit(,2) |
05 |
cookie=0x0, duration=19596.602s, table=0, n_packets=2, n_bytes=140, idle_age=19590, priority=0 actions=drop |
06 |
cookie=0x0, duration=19596.343s, table=1, n_packets=323, n_bytes=65252, idle_age=4, priority=0,dl_dst=00:00:00:00:00:00/01:00:00:00:00:00 actions=resubmit(,20) |
07 |
cookie=0x0, duration=19596.082s, table=1, n_packets=21, n_bytes=1510, idle_age=5027, priority=0,dl_dst=01:00:00:00:00:00/01:00:00:00:00:00 actions=resubmit(,21) |
08 |
cookie=0x0, duration=9356.289s, table=2, n_packets=625, n_bytes=125972, idle_age=4, priority=1,tun_id=0x1 actions=mod_vlan_vid:1,resubmit(,10) |
09 |
cookie=0x0, duration=19595.821s, table=2, n_packets=0, n_bytes=0, idle_age=19595, priority=0 actions=drop |
10 |
cookie=0x0, duration=19595.554s, table=3, n_packets=0, n_bytes=0, idle_age=19595, priority=0 actions=drop |
11 |
cookie=0x0, duration=19595.292s, table=10, n_packets=625, n_bytes=125972, idle_age=4, priority=1 actions=learn(table=20,hard_timeout=300,priority=1,NXM_OF_VLAN_TCI[0..11],NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[],load:0->NXM_OF_VLAN_TCI[],load:NXM_NX_TUN_ID[]->NXM_NX_TUN_ID[],output:NXM_OF_IN_PORT[]),output:1 |
12 |
cookie=0x0, duration=9314.338s, table=20, n_packets=323, n_bytes=65252, hard_timeout=300, idle_age=4, hard_age=3, priority=1,vlan_tci=0x0001/0x0fff,dl_dst=fa:16:3e:cb:11:f6 actions=load:0->NXM_OF_VLAN_TCI[],load:0x1->NXM_NX_TUN_ID[],output:2 |
13 |
cookie=0x0, duration=19595.026s, table=20, n_packets=0, n_bytes=0, idle_age=19595, priority=0 actions=resubmit(,21) |
14 |
cookie=0x0, duration=9356.592s, table=21, n_packets=9, n_bytes=586, idle_age=5027, priority=1,dl_vlan=1 actions=strip_vlan,set_tunnel:0x1,output:2 |
15 |
cookie=0x0, duration=19594.759s, table=21, n_packets=12, n_bytes=924, idle_age=5057, priority=0 actions=drop |
這些規則跟Compute節點上br-tun的規則相似,完成tunnel跟vlan之間的轉換。
br-int
[Bash shell]
純文本查看 復制代碼
01 |
Bridge br-int |
02 |
Port "qr-ff19a58b-3d" |
03 |
tag: 1 |
04 |
Interface "qr-ff19a58b-3d" |
05 |
type : internal |
06 |
Port br-int |
07 |
Interface br-int |
08 |
type : internal |
09 |
Port patch-tun |
10 |
Interface patch-tun |
11 |
type : patch |
12 |
options: {peer=patch-int} |
13 |
Port "tap4385f950-8b" |
14 |
tag: 1 |
15 |
Interface "tap4385f950-8b" |
16 |
type : internal |
該集成網橋上掛載了很多進程來提供網絡服務,包括路由器、DHCP服務器等。這些進程不同的租戶可能都需要,彼此的地址空間可能沖突,也可能跟物理網絡的地址空間沖突,因此都運行在獨立的網絡名字空間中。 規則跟computer節點的br-int規則一致,表現為一個正常交換機。
[Bash shell]
純文本查看 復制代碼
01 |
# ovs-ofctl dump-flows br-int |
02 |
NXST_FLOW reply (xid=0x4): |
03 |
cookie=0x0, duration=18198.244s, table=0, n_packets=849, n_bytes=164654, idle_age=43, priority=1 actions=NORMAL |
網絡名字空間
在linux中,網絡名字空間可以被認為是隔離的擁有單獨網絡棧(網卡、路由轉發表、iptables)的環境。網絡名字空間經常用來隔離網絡設備和服務,只有擁有同樣網絡名字空間的設備,才能看到彼此。 可以用ip netns list命令來查看已經存在的名字空間。
[Bash shell]
純文本查看 復制代碼
01 |
# ip netns |
02 |
qdhcp-88b1609c-68e0-49ca-a658-f1edff54a264 |
03 |
qrouter-2d214fde-293c-4d64-8062-797f80ae2d8f |
qdhcp開頭的名字空間是dhcp服務器使用的,qrouter開頭的則是router服務使用的。 可以通過 ip netns exec namespaceid command 來在指定的網絡名字空間中執行網絡命令,例如
[Bash shell]
純文本查看 復制代碼
01 |
# ip netns exec qdhcp-88b1609c-68e0-49ca-a658-f1edff54a264 ip addr |
02 |
71: ns-f14c598d-98: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 |
03 |
link/ether fa:16:3e:10:2f:03 brd ff:ff:ff:ff:ff:ff |
04 |
inet 10.1.0.3/24 brd 10.1.0.255 scope global ns-f14c598d-98 |
05 |
inet6 fe80::f816:3eff:fe10:2f03/64 scope link |
06 |
valid_lft forever preferred_lft forever |
可以看到,dhcp服務的網絡名字空間中只有一個網絡接口“ns-f14c598d-98”,它連接到br-int的tapf14c598d-98接口上。
dhcp 服務
dhcp服務是通過dnsmasq進程(輕量級服務器,可以提供dns、dhcp、tftp等服務)來實現的,該進程綁定到dhcp名字空間中的br-int的接口上。可以查看相關的進程。
[Bash shell]
純文本查看 復制代碼
01 |
# ps -fe | grep 88b1609c-68e0-49ca-a658-f1edff54a264 |
02 |
nobody 23195 1 0 Oct26 ? 00:00:00 dnsmasq --no-hosts --no-resolv --strict-order --bind-interfaces --interface=ns-f14c598d-98 --except-interface=lo --pid- file =/var/lib/neutron/dhcp/88b1609c-68e0-49ca-a658-f1edff54a264/pid --dhcp-hostsfile=/var/lib/neutron/dhcp/88b1609c-68e0-49ca-a658-f1edff54a264/host --dhcp-optsfile=/var/lib/neutron/dhcp/88b1609c-68e0-49ca-a658-f1edff54a264/opts --dhcp-script=/usr/bin/neutron-dhcp-agent-dnsmasq-lease-update --leasefile-ro --dhcp-range=tag0,10.1.0.0,static,120s --conf- file = --domain=openstacklocal |
03 |
root 23196 23195 0 Oct26 ? 00:00:00 dnsmasq --no-hosts --no-resolv --strict-order --bind-interfaces --interface=ns-f14c598d-98 --except-interface=lo --pid- file =/var/lib/neutron/dhcp/88b1609c-68e0-49ca-a658-f1edff54a264/pid --dhcp-hostsfile=/var/lib/neutron/dhcp/88b1609c-68e0-49ca-a658-f1edff54a264/host --dhcp-optsfile=/var/lib/neutron/dhcp/88b1609c-68e0-49ca-a658-f1edff54a264/opts --dhcp-script=/usr/bin/neutron-dhcp-agent-dnsmasq-lease-update --leasefile-ro --dhcp-range=tag0,10.1.0.0,static,120s --conf- file = --domain=openstacklocal |
router服務
首先,要理解什么是router,router是提供跨subnet的互聯功能的。比如用戶的內部網絡中主機想要訪問外部互聯網的地址,就需要router來轉發(因此,所有跟外部網絡的流量都必須經過router)。目前router的實現是通過iptables進行的。 同樣的,router服務也運行在自己的名字空間中,可以通過如下命令查看:
[Bash shell]
純文本查看 復制代碼
01 |
# ip netns exec qrouter-2d214fde-293c-4d64-8062-797f80ae2d8f ip addr |
02 |
66: qg-d48b49e0-aa: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 |
03 |
link/ether fa:16:3e:5c:a2:ac brd ff:ff:ff:ff:ff:ff |
04 |
inet 172.24.4.227/28 brd 172.24.4.239 scope global qg-d48b49e0-aa |
05 |
inet 172.24.4.228/32 brd 172.24.4.228 scope global qg-d48b49e0-aa |
06 |
inet6 fe80::f816:3eff:fe5c:a2ac/64 scope link |
07 |
valid_lft forever preferred_lft forever |
08 |
68: qr-c2d7dd02-56: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 |
09 |
link/ether fa:16:3e:ea:64:6e brd ff:ff:ff:ff:ff:ff |
10 |
inet 10.1.0.1/24 brd 10.1.0.255 scope global qr-c2d7dd02-56 |
11 |
inet6 fe80::f816:3eff:feea:646e/64 scope link |
12 |
valid_lft forever preferred_lft forever |
可以看出,該名字空間中包括兩個網絡接口。
第一個接口qg-d48b49e0-aa(即K)是外部接口(qg=q gateway),將路由器的網關指向默認網關(通過router-gateway-set命令指定),這個接口連接到br-ex上的tapd48b49e0-aa(即L)。
第二個接口qr-c2d7dd02-56(即N,qr=q bridge)跟br-int上的tapc2d7dd02-56口(即M)相連,將router進程連接到集成網橋上。
查看該名字空間中的路由表:
[Bash shell]
純文本查看 復制代碼
01 |
# ip netns exec qrouter-2d214fde-293c-4d64-8062-797f80ae2d8f ip route |
02 |
172.24.4.224/28 dev qg-d48b49e0-aa proto kernel scope link src 172.24.4.227 |
03 |
10.1.0.0/24 dev qr-c2d7dd02-56 proto kernel scope link src 10.1.0.1 |
04 |
default via 172.24.4.225 dev qg-d48b49e0-aa |
其中,第一條規則是將到172.24.4.224/28段的訪問都從網卡qg-d48b49e0-aa(即K)發出。
第二條規則是將到10.1.0.0/24段的訪問都從網卡qr-c2d7dd02-56(即N)發出。 最后一條是默認路由,所有的通過qg-d48b49e0-aa網卡(即K)發出。 floating ip服務同樣在路由器名字空間中實現,例如如果綁定了外部的floating ip 172.24.4.228到某個虛擬機10.1.0.2,則nat表中規則為:
[Bash shell]
純文本查看 復制代碼
01 |
# ip netns exec qrouter-2d214fde-293c-4d64-8062-797f80ae2d8f iptables -t nat -S |
02 |
-P PREROUTING ACCEPT |
03 |
-P POSTROUTING ACCEPT |
04 |
-P OUTPUT ACCEPT |
05 |
-N neutron-l3-agent-OUTPUT |
06 |
-N neutron-l3-agent-POSTROUTING |
07 |
-N neutron-l3-agent-PREROUTING |
08 |
-N neutron-l3-agent-float-snat |
09 |
-N neutron-l3-agent-snat |
10 |
-N neutron-postrouting-bottom |
11 |
-A PREROUTING -j neutron-l3-agent-PREROUTING |
12 |
-A POSTROUTING -j neutron-l3-agent-POSTROUTING |
13 |
-A POSTROUTING -j neutron-postrouting-bottom |
14 |
-A OUTPUT -j neutron-l3-agent-OUTPUT |
15 |
-A neutron-l3-agent-OUTPUT -d 172.24.4.228/32 -j DNAT --to-destination 10.1.0.2 |
16 |
-A neutron-l3-agent-POSTROUTING ! -i qg-d48b49e0-aa ! -o qg-d48b49e0-aa -m conntrack ! --ctstate DNAT -j ACCEPT |
17 |
-A neutron-l3-agent-PREROUTING -d 169.254.169.254/32 -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 9697 |
18 |
-A neutron-l3-agent-PREROUTING -d 172.24.4.228/32 -j DNAT --to-destination 10.1.0.2 |
19 |
-A neutron-l3-agent-float-snat -s 10.1.0.2/32 -j SNAT --to- source 172.24.4.228 |
20 |
-A neutron-l3-agent-snat -j neutron-l3-agent-float-snat |
21 |
-A neutron-l3-agent-snat -s 10.1.0.0/24 -j SNAT --to- source 172.24.4.227 |
22 |
-A neutron-postrouting-bottom -j neutron-l3-agent-snat |
其中SNAT和DNAT規則完成外部floating ip到內部ip的映射:
[Bash shell]
純文本查看 復制代碼
01 |
-A neutron-l3-agent-OUTPUT -d 172.24.4.228/32 -j DNAT --to-destination 10.1.0.2 |
02 |
-A neutron-l3-agent-PREROUTING -d 172.24.4.228/32 -j DNAT --to-destination 10.1.0.2 |
03 |
-A neutron-l3-agent-float-snat -s 10.1.0.2/32 -j SNAT --to- source 172.24.4.228 |
另外有一條SNAT規則把所有其他的內部IP出來的流量都映射到外部IP 172.24.4.227。這樣即使在內部虛擬機沒有外部IP的情況下,也可以發起對外網的訪問。
[Bash shell]
純文本查看 復制代碼
01 |
-A neutron-l3-agent-snat -s 10.1.0.0/24 -j SNAT --to- source 172.24.4.227 |
br-ex
[Bash shell]
純文本查看 復制代碼
01 |
Bridge br-ex |
02 |
Port "eth1" |
03 |
Interface "eth1" |
04 |
Port br-ex |
05 |
Interface br-ex |
06 |
type : internal |
07 |
Port "qg-1c3627de-1b" |
08 |
Interface "qg-1c3627de-1b" |
09 |
type : internal |
br-ex上直接連接到外部物理網絡,一般情況下網關在物理網絡中已經存在,則直接轉發即可。
# ovs-ofctl dump-flows br-exNXST_FLOW reply (xid=0x4): cookie=0x0, duration=23431.091s, table=0, n_packets=893539, n_bytes=504805376, idle_age=0, priority=0 actions=NORMAL
如果對外部網絡的網關地址配置到了br-ex(即br-ex作為一個網關):
[Bash shell]
純文本查看 復制代碼
01 |
# ip addr add 172.24.4.225/28 dev br-ex |
需要將內部虛擬機發出的流量進行SNAT,之后發出。
[Bash shell]
純文本查看 復制代碼
01 |
# iptables -A FORWARD -d 172.24.4.224/28 -j ACCEPT |
02 |
# iptables -A FORWARD -s 172.24.4.224/28 -j ACCEPT |
03 |
# iptables -t nat -I POSTROUTING 1 -s 172.24.4.224/28 -j MASQUERADE |
原文 http://www.aboutyun.com/thread-13008-1-1.html