在前幾天,我們已經學到了logical switch、logical router,也讓虛擬網路上的namespace可以互相通信。但大家應該有注意到,在目前,這些namespace是沒辦法和實體網路通信。我們什麼時候會有虛擬機器要和實體機器溝通的需求呢? 常見有二個情況:
我們今天先透過第一個情境,讓大家理解,OVN是如何透過localnet port,連通虛擬網路與實體網路。
一樣先來看看今天打算完成的架構。和[[Day-04_Multiple-Node-L2-Switch]]完成的架構相比,先來看看有那些地方不同:
照官方文件的說明,localnet是用來連接logical switch與實體網路。
Localnet ports represent the points of connectivity between logical switches and the physical network. They are implemented as OVS patch ports between the integration bridge and the separate Open vSwitch bridge that underlay physical ports attach to.
依照Day-04: 跨節點的logical switch 與 GEVEVE Overlay Network的介紹,overlay network上的二個namespace要通信,會經由eth1 用GENEVE傳送封裝後的封包。但是,如果今天namespace是在localnet switch上,會由br-int 和 br-eth2上的一對patch port,由br-int送到br-eth2後,由eth2送出去,完全不會經選GENEVE的封裝。有了基本的了解,來看一下要如何操作吧。
先建立namespace與logical switch,這一步相信大家都很熟了。
注意到這一次的範例,namespace的IP一定要用192.168.10.0/24 這個網段。主因是因為我們用Vagrnat和VirtualBox 建立VM時,讓eth2這張NIC是用192.168.10.0/24 這個網段;同時,VirtualBox會在你的電腦上建立一個新的NIC,也是在192.168.10.0/24這個網段。如此一來,我們的電腦和VirtualBox的這二個VM溝通。因為在今天的實驗,我們要讓二個namespace也用192.168.10.0/24這個網段和我們的VirtualBox VM 、我們的電腦互通,所以要用192.168.10.0/24 的IP。
sudo su
cd /opt/iTHome-2023/day-06
source helper.sh
# on controller
create-ns ns1 192.168.10.100 # MUST use 192.168.10.0/24
# on hypervisor
create-ns ns2 192.168.10.200 # MUST use 192.168.10.0/24
# only on controller
create-ovn-ls-and-lsp ls0
在logical switch上,建立一個type為localnet的port, localnet port有二個特別的設定:
add-localnet-port ls0 flat0 # add localnet port
add-localnet-port
實際的ovn-nbctl的指令:
localnet_port_name=$1-localnet
ovn-nbctl lsp-add $1 $localnet_port_name
ovn-nbctl lsp-set-addresses $localnet_port_name unknown
ovn-nbctl lsp-set-type $localnet_port_name localnet
ovn-nbctl lsp-set-options $localnet_port_name network_name=$2
OVN不會在各別的hypervisor上建立bridge,需要分別到每一個hypervisor上建立新的bridge. 並把實體介面加到bridge上。最後,還記得前一步在localnet port上設定的 network_name
嗎? 要把network_name
和要使用的bridge做mapping,這一步則是要透過ovs-vsctl在每個hypervisor上操作。
# on controller
assign-iface-to-ovn-lsp ls0 ns1
add-bridge-mapping eth2 flat0 # MUST use eth2, patch port will be created
# on hypervisor
assign-iface-to-ovn-lsp ls0 ns2
add-bridge-mapping eth2 flat0 # MUST use eth2, patch port will be created
add-bridge-mapping
function實際的ovn-nbctl的指令:
br_name=br-$1
ovs-vsctl add-br $br_name
ovs-vsctl add-port $br_name $1
ip link set $1 up
ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=$2:$br_name
一旦執行
add-bridge-mapping
後,在openvSwitch上的br-eth2 和 br-int會出現一對patch port。所以br-eth2 和 br-int上的patch 不用手動特別建立。透過這對patch port,讓原本只有和br-int連接的namespace,有了一個管道可以到br-eth2。也就能透過eth2實體介面與實體網路通訊。9e68e704-97cd-45c6-a4b2-69d77cba3522 Bridge br-eth2 Port br-eth2 Interface br-eth2 type: internal Port eth2 Interface eth2 Port patch-ls0-localnet-to-br-int Interface patch-ls0-localnet-to-br-int type: patch options: {peer=patch-br-int-to-ls0-localnet} Bridge br-int fail_mode: secure Port patch-br-int-to-ls0-localnet Interface patch-br-int-to-ls0-localnet type: patch options: {peer=patch-ls0-localnet-to-br-int} Port br-int Interface br-int type: internal Port ovn-f30077-0 Interface ovn-f30077-0 type: geneve options: {csum="true", key=flow, remote_ip="192.168.33.20"} Port veth-ns1-br Interface veth-ns1-br ovs_version: "2.13.8"
除了二個namespace可以互相通信之外,namespace也可以經由實體網路,和192.168.10.0/24上的其他設備溝通。
#在 hypervisor 上ping 另一個namespace
ip netns exec ns2 ping -c 1 192.168.10.100
PING 192.168.10.100 (192.168.10.100) 56(84) bytes of data.
64 bytes from 192.168.10.100: icmp_seq=1 ttl=64 time=1.45 ms
--- 192.168.10.100 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 1.448/1.448/1.448/0.000 ms
#在 hypervisor 上ping 其他設備
ip netns exec ns2 ping -c 1 192.168.10.1
PING 192.168.10.1 (192.168.10.1) 56(84) bytes of data.
64 bytes from 192.168.10.1: icmp_seq=1 ttl=64 time=0.243 ms
--- 192.168.10.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.243/0.243/0.243/0.000 ms
最後,我們來驗證一下,在使用Localnet port時,在同一個logical switch的namespace, 到底是透過實體網路 eth2, 還是透過 GENEVE 的eth1 通信呢? 在eth2 抓封包,可以看到二個namespace直接使用實體網路通信。當然,你也可以在eth1 抓GENEVE的封包來加以驗證,因為不會有任何的GENEVE封包,所以就不秀了唷,讓大家自己試試吧。
#contrlller
tcpdump -i eth2 icmp
05:49:39.212832 IP 192.168.10.200 > 192.168.10.100: ICMP echo request, id 11924, seq 1, length 64
05:49:39.213262 IP 192.168.10.100 > 192.168.10.200: ICMP echo reply, id 11924, seq 1, length 64
和前幾天相比,今天透過Localnet port,可以讓namespace直接使用到實體網路,而不在只是在overlay network裡通訊,這是不是很方便呢? 除了直接和實體網路通訊,localnet port的另一個更大的作用,就是讓在overlay network上的namespace可以連到Internet。就敬請期待明天的內容囉。