在前幾天,我們在OpenStack上建立了二個Network,在同一個Network裡的VM能互相通信。不意外地,在二個不同Network裡的VM, 則是無法通訊。要讓二個不同Network上的VM能夠通訊,必需建立一個Route,將二個Network連接起來。今天,就讓我們來看一下,在OpenStack裡建立Router時,OpenStack會對OVN做出那些相對應的操作吧。
今天我們想要完成的網路拓樸,就是建立一個Router,將前二天建立的Network連接起來。嚴格來說,OpenStack裡是將二個Subnet連接起來,而這二個subnet都是之前建立後,已經指定給Network。要用到的指令如下:
openstack router create r
openstack router add subnet r n1subnet
openstack router add subnet r n2subnet
一旦二個Network連上Router後,會發現在OpenStack裡多了二個屬於network:router_interface
類型的port,而這二個port分配到的IP,就是Router在每一個Network所使用的IP。
openstack port list --device-owner network:router_interface | abbrev
+--------+------+-------------------+------------------------------------------------+--------+
| ID | Name | MAC Address | Fixed IP Addresses | Status |
+--------+------+-------------------+------------------------------------------------+--------+
| 186849 | | fa:16:3e:2a:f8:4e | ip_address='192.168.200.1', subnet_id='5d07b9' | ACTIVE |
| 1c52f2 | | fa:16:3e:41:b2:20 | ip_address='172.16.100.1', subnet_id='372e02' | ACTIVE |
+--------+------+-------------------+------------------------------------------------+--------+
e80dc6
, 對應的OVN router 名稱為neutron-e80dc6
openstack router list -f yaml | abbrev
- ID: e80dc6
Name: r
Project: 5360fa127fda40e18d8ebe5901cb49ee
State: true
Status: ACTIVE
$ ovn-nbctl show |abbrev
...
router 11042c (neutron-e80dc6) (aka r)
186849
& 1c52f2
port。在二個OVN logical switch 上,也產生相同名稱的logical switch port$ ovn-nbctl show | abbrev
switch 932e1b (neutron-76af9b) (aka n1)
port 1c52f2
type: router
router-port: lrp-1c52f2
...
switch ffc4b4 (neutron-4914b0) (aka n2)
port 186849
type: router
router-port: lrp-186849
...
lrp-186849
& lrp-1c52f2
. 和openstack network 上的port相對應。另外,switch port會和router port相連。
router 11042c (neutron-6b81fe) (aka r)
port lrp-1c52f2
mac: "fa:16:3e:41:b2:20"
networks: ["172.16.100.1/24"]
port lrp-186849
mac: "fa:16:3e:2a:f8:4e"
networks: ["192.168.200.1/24"]
vm1和vm3在不同的network上,會透過router將二個network上的instance做路由,可以連通二個不同Network上的instance。除了直接讓二個instance互ping外,我們可以用ovn-trace來做確認。
# 由openstack network name 查OVN logical switch id
$ NETWORK1_NAME=n1
$ NETWORK2_NAME=n2
$ ROUTER_NAME=r
$ VM1_NAME=vm_1
$ VM2_NAME=vm_2
$ VM3_NAME=vm_3
$ lsw=neutron-`openstack network list --name ${NETWORK1_NAME} -f value -c ID`
$ lsp=`openstack port list --network ${NETWORK1_NAME} --server ${VM1_NAME} -f value -c ID`
$ vm1_mac=`openstack port list --network ${NETWORK1_NAME} --server ${VM1_NAME} -f value -c mac_address`
$ lrp_mac=`openstack port list --network ${NETWORK1_NAME} --device-owner network:router_interface -f value -c mac_address`
$ vm1_ip=`openstack server show ${VM1_NAME} -f json | jq -cr .addresses.${NETWORK1_NAME}[0]`
$ vm3_ip=`openstack server show ${VM3_NAME} -f json | jq -cr .addresses.${NETWORK2_NAME}[0]`
$ ovn-trace ${lsw} \
"inport == \"${lsp}\" &&
eth.src == ${vm1_mac} &&
eth.dst == ${lrp_mac} &&
ip4.src == ${vm1_ip} &&
ip4.dst == ${vm3_ip} &&
ip.ttl == 64 &&
icmp4.type == 8"
n1
由171d5d
port 收到由vm1 來的packet後,由1c52f2
port 出去送往r
的lrp-1c52f2
ingress(dp="n1", inport="171d5d")
-----------------------------
...
23. ls_in_l2_lkup (northd.c:8468): eth.dst == fa:16:3e:34:81:f9, priority 50, uuid 7a67c14d
outport = "16cd7b";
output;
egress(dp="n1", inport="171d5d", outport="1c52f2")
----------------------------------------------
...
9. ls_out_apply_port_sec (northd.c:5511): 1, priority 0, uuid dbad5beb
output;
/* output to "1c52f2", type "patch" */
r
lrp-1c52f2
收到,轉往lrp-186849
,由lrp-186849
出去後,送往n2
的186849
ingress(dp="r", inport="lrp-1c52f2")
------------------------------------
...
egress(dp="r", inport="lrp-1c52f2", outport="lrp-186849")
---------------------------------------------------------
...
6. lr_out_delivery (northd.c:12226): outport == "lrp-186849", priority 100, uuid 9f2379e4
output;
/* output to "lrp-186849", type "patch" */
n2
由186849
port 進來後,由8852af
port 出去送給vm_3
ingress(dp="n2", inport="186849")
---------------------------------
...
23. ls_in_l2_lkup (northd.c:8397): eth.dst == fa:16:3e:73:34:d2, priority 50, uuid 48c09d9c
outport = "8852af";
output;
egress(dp="n2", inport="186849", outport="8852af")
--------------------------------------------------
...
9. ls_out_apply_port_sec (northd.c:5511): 1, priority 0, uuid dbad5beb
output;
/* output to "8852af", type "" */
從ovn-trace的結果,可以看到由vm_1出發的packet,最終會由8852af
這個與vm_3相連的port送出;反之,ping的response也會延原路送回給vm_1。所以vm_1和vm_3之間是可以通訊的。
至此,我們已經看過一次OpenStack是如何透過OVN完成網路相關的功能,但是,目前都還是在一個all-in-one的OpenStack上,明天開始,我們要建置一個多節點的OpenStack的環境,再來理解一些OpenStack高級的網路功能吧。