1. 程式人生 > >SDN控制器之OVN實驗三:從OVN虛擬網路訪問物理網路

SDN控制器之OVN實驗三:從OVN虛擬網路訪問物理網路

概覽

基於我的前2篇文章中的實驗環境,我現在將一個OVN閘道器路由器(OVN Gateway Router)新增進來。 此閘道器路由器將提供從我們的overlay網路訪問物理網路的能力。

實驗環境

為了演示閘道器路由器,我們需要向Ubuntu主機新增另一個物理網路:在每臺主機eth1網絡卡新增網路10.127.0.128/25。
最終的物理網路拓撲如下圖所示:

 

OVN L3 Gateway介紹

OVN閘道器用作overlay網路和物理網路之間的上行/下行通道。它有兩個功能:

  • L2將OVN邏輯交換機橋接到VLAN中;

  • L3在OVN路由器和物理網路之間提供三層鏈路。

為了達成實驗的目標,我們將重點介紹如何建立一個三層閘道器,其會作為我們的物理網路和邏輯網路之間的分界點。
與分散式邏輯路由器(DLR)不同,OVN閘道器路由器集中在單個主機(chassis)上,因此它可以提供尚不支援分散式的服務(NAT,負載平衡等)。

但是OVN閘道器釋出的時候,還存在著某些限制:

  • 閘道器路由器僅可以經由邏輯交換機連線到其他路由器,而DLR已經可以經由一條鏈路直連路由器。社群正在進行相關工作來解決掉這個限制。

  • OVN支援多個閘道器路由器繫結到環境中,這意味著可以邏輯空間執行入站ECMP路由。然而,OVN當前不支援閘道器路由器之間的出站ECMP。這個特性也同樣是OVN未來需要加強的。

使ubuntu1成為OVN主機

我們使用ubuntu1作為OVN閘道器路由器主機,而不是虛擬機器。

首先為相應主機角色安裝正確的OVN包:

 

dpkg -i ovn-host_2.6.0-1_amd64.deb

然後註冊到OVN Central(ubuntu1自身):

 

ovs-vsctl set open . external-ids:ovn-remote=tcp:127.0.0.1:6642

ovs-vsctl set open . external-ids:ovn-encap-type=geneve

ovs-vsctl set open . external-ids:ovn-encap-ip=10.127.0.2

測試網路連通性:

 

[email protected]:~# netstat -antp | grep 127.0.0.1

tcp        0      0 127.0.0.1:6642          127.0.0.1:55566         ESTABLISHED 4999/ovsdb-server

tcp        0      0 127.0.0.1:55566         127.0.0.1:6642          ESTABLISHED 15212/ovn-controlle

此外,如果OVN沒有自動建立整合網橋,還需要手工建立整合網橋:

 

ovs-vsctl add-br br-int -- set Bridge br-int fail-mode=secure

OVN 邏輯網路拓撲

讓我們在開始配置之前看一下為本次實驗設計的網路架構。

我們建立的OVN邏輯網路拓撲如下圖所示:

正如您所看到的,我們添加了以下新元件:

  • OVN閘道器路由器(edge1)

  • 邏輯交換機(transit),用於連線edge1和tenant1路由器

  • 邏輯交換機(outside),用於將edge1連線到實驗室網路

新增L3 Gateway

如上圖所述,gatway路由器將繫結到一個特定的 chassis(在我們的例子中是ubuntu1)。 為了完成這個繫結,我們需要找到ubuntu1的 chassis ID。 使用ubuntu1中的ovn-sbctl show命令,您應該能看到類似於此的輸出:

 

ovn-sbctl show

Chassis "833ae1bd-ced3-494a-a95b-f2dc54172b71"

        hostname: "ubuntu1"

        Encap geneve

                ip: "10.127.0.2"

                options: {csum="true"}

Chassis "239f2c28-90ff-468f-a701-655585c630bf"

        hostname: "ubuntu3"

        Encap geneve

                ip: "10.127.0.3"

                options: {csum="true"}

        Port_Binding "dmz-vm2"

        Port_Binding "inside-vm4"

Chassis "517d558e-158a-4cb2-8870-283e9d39685e"

        hostname: "ubuntu2"

        Encap geneve

                ip: "10.127.0.129"

                options: {csum="true"}

        Port_Binding "inside-vm3"

        Port_Binding "dmz-vm1"

複製ubuntu1主機的chassis UUID供下文使用。

建立新的邏輯路由器。 請務必使用有效的UUID替換{chassis_id}。

在ubuntu1進行如下操作:

 

# 建立 router edge1

ovn-nbctl create Logical_Router name=edge1 options:chassis={chassis_uuid}

 

#建立連線edge1和tenant1 routers的邏輯交換機transit

ovn-nbctl ls-add transit

 

# edge1 到 the transit switch

ovn-nbctl lrp-add edge1 edge1-transit 02:ac:10:ff:00:01 172.16.255.1/30

ovn-nbctl lsp-add transit transit-edge1

ovn-nbctl lsp-set-type transit-edge1 router

ovn-nbctl lsp-set-addresses transit-edge1 02:ac:10:ff:00:01

ovn-nbctl lsp-set-options transit-edge1 router-port=edge1-transit

 

# tenant1 到the transit switch

ovn-nbctl lrp-add tenant1 tenant1-transit 02:ac:10:ff:00:02 172.16.255.2/30

ovn-nbctl lsp-add transit transit-tenant1

ovn-nbctl lsp-set-type transit-tenant1 router

ovn-nbctl lsp-set-addresses transit-tenant1 02:ac:10:ff:00:02

ovn-nbctl lsp-set-options transit-tenant1 router-port=tenant1-transit

 

#新增靜態路由

ovn-nbctl lr-route-add edge1 "172.16.255.128/25" 172.16.255.2

ovn-nbctl lr-route-add tenant1 "0.0.0.0/0" 172.16.255.1

 

ovn-sbctl show

注意ubuntu1主機上的埠繫結。
現在可以測試從ubuntu2上的vm1到edge1的網路連通性:

 

[email protected]:~# ip netns exec vm1 ping 172.16.255.1

PING 172.16.255.1 (172.16.255.1) 56(84) bytes of data.

64 bytes from 172.16.255.1: icmp_seq=1 ttl=253 time=1.07 ms

64 bytes from 172.16.255.1: icmp_seq=2 ttl=253 time=1.13 ms

64 bytes from 172.16.255.1: icmp_seq=3 ttl=253 time=1.00 ms

連線到 “data”網路

我們將使用ubuntu1的eth1介面作為我們在edge1路由器和“資料”網路之間的連線點。 為了實現這一點,我們需要將OVN設定為通過專用OVS橋直接使用eth1介面。 這種型別的連線在OVN中稱為“localnet”。

在ubuntu1進行如下操作:

 

#在路由器 'edge1'建立新的埠

ovn-nbctl lrp-add edge1 edge1-outside 02:0a:7f:00:01:29 10.127.0.129/25

 

# 新建邏輯交換機,並將它連線到edge1

ovn-nbctl ls-add outside

ovn-nbctl lsp-add outside outside-edge1

ovn-nbctl lsp-set-type outside-edge1 router

ovn-nbctl lsp-set-addresses outside-edge1 02:0a:7f:00:01:29

ovn-nbctl lsp-set-options outside-edge1 router-port=edge1-outside

 

# 為 eth1新建OVS網橋

ovs-vsctl add-br br-eth1

 

# 為 eth1建立網橋對映: 把 "dataNet" 對映到 br-eth1

ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=dataNet:br-eth1

 

#在 'outside'交換機建立localnet埠。把網路名稱設定為"dataNet"

ovn-nbctl lsp-add outside outside-localnet

ovn-nbctl lsp-set-addresses outside-localnet unknown

ovn-nbctl lsp-set-type outside-localnet localnet

ovn-nbctl lsp-set-options outside-localnet network_name=dataNet

 

# 將 eth1 連線到 br-eth1

ovs-vsctl add-port br-eth1 eth1

從vm1測試到edge1-outside的網路連通性

 

[email protected]:~# ip netns exec vm1 ping 10.127.0.129

PING 10.127.0.129 (10.127.0.129) 56(84) bytes of data.

64 bytes from 10.127.0.129: icmp_seq=1 ttl=253 time=1.74 ms

64 bytes from 10.127.0.129: icmp_seq=2 ttl=253 time=0.781 ms

64 bytes from 10.127.0.129: icmp_seq=3 ttl=253 time=0.582 ms

讓Ubuntu主機訪問“data”網路

對於ubuntu2 / ubuntu3,實際上只需要配置一個引數:給它們的物理網絡卡(本文中的eth1)設定一個IP。

對於ubuntu1,我們將在br-eth1介面上設定一個IP。

在ubuntu1上:

 

ip addr add 10.127.0.130/24 dev br-eth1

ip link set br-eth1 up

在ubuntu2上:

 

ip addr add 10.127.0.131/24 dev eth1

ip link set eth1 up

在ubuntu3上:

 

ip addr add 10.127.0.132/24 dev eth1

ip link set eth1 up

在ubuntu1 上測試到 edge1的網路連通性:

 

[email protected]:~# ping 10.127.0.129  

PING 10.127.0.129 (10.127.0.129) 56(84) bytes of data.

64 bytes from 10.127.0.129: icmp_seq=1 ttl=254 time=0.563 ms

64 bytes from 10.127.0.129: icmp_seq=2 ttl=254 time=0.290 ms

64 bytes from 10.127.0.129: icmp_seq=3 ttl=254 time=0.333 ms

配置NAT

讓我們看看從vm1 ping ubuntu1時會發生什麼:

 

[email protected]:~# ip netns exec vm1 ping 10.127.0.130

PING 10.127.0.130 (10.127.0.130) 56(84) bytes of data.

^C

--- 10.127.0.130 ping statistics ---

3 packets transmitted, 0 received, 100% packet loss, time 2016ms

不出所料,果然ping不通。 為什麼不通? 讓我們看一下來自ubuntu1的tcpdump的輸出結果:

 

[email protected]:~# tcpdump -i br-eth1

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode

listening on br-eth1, link-type EN10MB (Ethernet), capture size 262144 bytes

14:41:53.057993 IP 172.16.255.130 > 10.127.0.130: ICMP echo request, id 19359, seq 1, length 64

14:41:54.065696 IP 172.16.255.130 > 10.127.0.130: ICMP echo request, id 19359, seq 2, length 64

14:41:55.073667 IP 172.16.255.130 > 10.127.0.130: ICMP echo request, id 19359, seq 3, length 64

我們可以看到請求進來,但是我們的響應通過不同的介面返回(在tcpdump輸出中看不到)。

這是因為ubuntu1沒有到172.16.255.130的路由,並且通過其自己的預設閘道器進行響應。

我們有2種方法來解決這個問題:

  • 在Ubuntu主機上新增靜態路由

  • 在OVN閘道器路由器上設定NAT

我們將選擇第2種方法,因為它比管理靜態路由更容易些。

OVN有3種類型的NAT可以配置:

  • DNAT ——用於將請求從外部可見的IP轉換為內部IP

  • SNAT ——用於將請求從一個或多個內部IP轉換為外部可見的IP

  • SNAT-DNAT ——用於建立“靜態NAT”,將外部IP對映到內部IP,反之亦然

由於我們不需要(或希望)公共網路能夠直接訪問我們的內部虛擬機器,因此我們將重點放在允許從我們的虛擬機器進行出站SNAT。 為了建立NAT規則,我們需要直接操縱OVN北向資料庫。 語法有點奇怪,但我稍後會解釋的。

在ubuntu1上:

 

# create snat rule which will nat to the edge1-outside interface

ovn-nbctl -- [email protected] create nat type="snat" logical_ip=172.16.255.128/25

external_ip=10.127.0.129 -- add logical_router edge1 nat @nat

簡而言之,此命令在北向資料庫的“nat”表中建立一個條目,再將同時產生的UUID儲存在ovsdb的變數“@nat”中。

然後將儲存在@nat中的UUID新增到北向資料庫的“logical_router”表中的“edge1”條目的“nat”欄位。

如果你想知道北向資料庫的細節,那麼一定要去查閱ovn-nb的手冊頁。ovn-nbctl的手冊頁還解釋了上面使用的命令語法。

從vm1測試網路連通性:

 

[email protected]:~# ip netns exec vm1 ping 10.127.0.130

PING 10.127.0.130 (10.127.0.130) 56(84) bytes of data.

64 bytes from 10.127.0.130: icmp_seq=40 ttl=62 time=2.39 ms

64 bytes from 10.127.0.130: icmp_seq=41 ttl=62 time=1.61 ms

64 bytes from 10.127.0.130: icmp_seq=42 ttl=62 time=1.28 ms

如上所示,我們現在可以從內部虛擬機器ping通外部網路。

結語

純overlay網路幾乎是完全沒有用的,除非你能將它們連線到外部世界。 OVN閘道器提供用於進行這種連線的手段。在下一篇文章中,我將介紹OVN的另一個重要功能:OVN負載均衡器。

原文:https://blog.csdn.net/zhengmx100/article/details/72822530?utm_source=blogxgwz1