zoukankan      html  css  js  c++  java
  • OVN实战---《A Primer on OVN》翻译

    overview

    在本文中,我们将在三个host之间创建一个简单的二层overlay network。首先,我们来简单看一下,整个系统是怎么工作的。OVN基于分布式的control plane,其中各个组件分布在network的各个节点中。在OVN中包含了如下两种角色:

    • OVN Central --- 现在该角色仅包含一个节点,该节点用于处理和cloud management platform等其他外部资源进行集成的API。并且在该节点中包含了OVN northbound database,用于存储追踪上层的逻辑结构,例如logical switches/port,以及OVN southbound database用于确定如何将ovn-northdb中的逻辑结构映射到物理世界中
    • OVN Host -- 该角色存在于所有节点中,其中包含了virtual networking end points,例如虚拟机。OVN Host中包含一个"chassis controller",它往上和ovn-soutdb连接,因为其中包含了权威的物理网络信息,向下作为一个openflow controller和ovs连接。

    The Lab

    OVN实验由三个连接到同一个子网(10.127.0.0/25)的ubuntu 17.04 server组成。每台主机以及它们的IP地址如下所示:

    • ubuntu1 10.127.0.2 --- 作为OVN Central
    • ubuntu2 10.127.0.3 --- 作为OVN Host
    • ubuntu3 10.127.0.4 --- 作为OVN Host

    为了实验的简单起见,我们将通过创建ovs internal interfaces,并且将它们加入一个network namespace来模拟虚拟机负载。namespace会保证我们的OVN overlay network和lab network完全隔离。

    Installing Open vSwitch

    和原文自行编译安装ovs不同的是,为了简单起见,我们使用了ubuntu 17.04,它的源里面已经包含了ovs 2.6.1,因此我们直接用apt-get安装即可,具体指令如下:

    sudo apt-get install openvswitch-common openvswitch-switch
    
    // OVN Central执行如下指令
    sudo apt-get install ovn-common ovn-central ovn-host
    
    // OVN Host执行如下指令
    sudo apt-get install ovn-common ovn-host
    

      

    Creating the Integration Bridge

    OVN会负责管理一个由ovs创建的bridge,所有希望加入OVN logical switch的设备都必须加入到该bridge中。尽管我们可以给该bridge取任意名字,但是一般我们都将它命名为"br-int"。首先我们要确认该bridge是否存在,如果有必要的话,对它进行创建。

    在ubuntu2/ubuntu3执行如下命令

    ovs-vsctl list-br
    

      

    如果没有在输出中看到"br-int",那么我们必须手动创建该bridge。记住,该integration bridge必须存在在所有包含虚拟机的节点中。

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

      

    其中的"fail-mode=secure"是一个安全特性,它用于配置bridge,让它默认丢弃所有的流量。这非常重要,因为我们不想要integration bridge的租户能相互沟通,如果我们的flow因为一些原因被删除了或者我们在OVN controller启动前就将租户插入到了bridge中。

    Connecting the Chassis Controllers to the Central Controller

    接下来我们要做的是将ubuntu2/ubuntu3中的chassis controllers和ubuntu1中的central controller连接起来。

    ubuntu2:

    ovs-vsctl set open . external-ids:ovn-remote=tcp:10.127.0.2:6642
    ovs-vsctl set open . external-ids:ovn-encap-type=geneve
    ovs-vsctl set open . external-ids:ovn-encap-ip=10.127.0.3
    

      

    ubuntu3:

    ovs-vsctl set open . external-ids:ovn-remote=tcp:10.127.0.2:6642
    ovs-vsctl set open . external-ids:ovn-encap-type=geneve
    ovs-vsctl set open . external-ids:ovn-encap-ip=10.127.0.4
    

      

    上述命令会触发每个节点上的OVN chassis controller和ubuntu1中的OVN Central host进行连接。并且我们指定了,我们的overlay network使用geneve协议来加密数据平面流量。

    我们可以使用netstat命令来确定连接是否完成。在ubuntu3的输出应当如下所示:

    root@ubuntu3:~# netstat -antp | grep 10.127.0.2
    tcp        0      0 10.127.0.4:39256        10.127.0.2:6642         ESTABLISHED 3072/ovn-controller
    

      

    Defining the Logical Network

    下图展示了lab中创建的各个OVN逻辑组件

    首先我们定义一个名为"ls1"的OVN logical switch以及和它相连的logical port。在ubuntu1执行如下命令:

    # create the logical switch
    ovn-nbctl ls-add ls1
    
    # create logical port
    ovn-nbctl lsp-add ls1 ls1-vm1
    ovn-nbctl lsp-set-addresses ls1-vm1 02:ac:10:ff:00:11
    ovn-nbctl lsp-set-port-security ls1-vm1 02:ac:10:ff:00:11
    
    # create logical port
    ovn-nbctl lsp-add ls1 ls1-vm2
    ovn-nbctl lsp-set-addresses ls1-vm2 02:ac:10:ff:00:22
    ovn-nbctl lsp-set-port-security ls1-vm2 02:ac:10:ff:00:22
    
    ovn-nbctl show
    

      

    在每一个命令集中我们都创建了一个命名唯一的logical port。通常这些logical port都会以UUID进行命名,从而确保唯一性,但是我们使用了对人类更加友好的命名方式。同时我们还定义了和每个logical port相关联的mac地址,而且我们还更近一步,利用port security对logical port进行了锁定(从而从该logical port只能使用我们提供的mac地址)。

    Addint "Fake" Virtual Machines

    接下来我们将创建用于连接到logical switch的"虚拟机"。如上文所述,我们将使用OVS internal ports和network namespace来模拟虚拟机,并且使用172.16.255.0/24来作为我们的logical switch的地址空间

    ubuntu2:

    ip netns add vm1
    ovs-vsctl add-port br-int vm1 -- set interface vm1 type=internal
    ip link set vm1 netns vm1
    ip netns exec vm1 ip link set vm1 address 02:ac:10:ff:00:11
    ip netns exec vm1 ip addr add 172.16.255.11/24 dev vm1
    ip netns exec vm1 ip link set vm1 up
    ovs-vsctl set Interface vm1 external_ids:iface-id=ls1-vm1
    
    ip netns exec vm1 ip addr show
    

      

    ubuntu3:

    ip netns add vm2
    ovs-vsctl add-port br-int vm2 -- set interface vm2 type=internal
    ip link set vm2 netns vm2
    ip netns exec vm2 ip link set vm2 address 02:ac:10:ff:00:22
    ip netns exec vm2 ip addr add 172.16.255.22/24 dev vm2
    ip netns exec vm2 ip link set vm2 up
    ovs-vsctl set Interface vm2 external_ids:iface-id=ls1-vm2
    
    ip netns exec vm2 ip addr show
    

      

    如果你对namespace或者ovs不熟悉,那么上述命令可能显得有点让人疑惑。简单地说,我们创建了一个network namespace作为我们的fake VM,创建了一个internal OVS port,并将该port加入到namespace中,通过netns exec命令对其进行配置,包括IP,mac地址等,最后创建一个OVS interface,其中external_id设置为我们在OVN中定义的logical port的ID。这最后一步触发了OVS通知OVN,一个新的logical port已将上线了。OVN在接到通知后,会将指令传输给对应的节点的logical chassis controller,同时chassis controller会将network flows压入OVS。

    需要注意的是,在这里我显式设置了这些interface的mac地址来和我们在OVN logical switch中的配置相匹配。这非常重要,因为如果mac地址不匹配的话,logical network将不能工作。事实上,我故意把工作流搞反了一点。其实你并不会去改变虚拟机的mac地址,而是将一个已经存在的,已知的mac存入OVN/OVS。而我这样做的目的是为了让mac/IP更加容易演示。

    Verifying and Testing Connectivity

    在ubuntu1中我们可以通过ovn-sbctl来确定logical network configuration。输出如下所示:

    root@ubuntu1:~# ovn-sbctl show
    Chassis "239f2c28-90ff-468f-a701-655585c630bf"
            hostname: "ubuntu3"
            Encap geneve
                    ip: "10.127.0.4"
                    options: {csum="true"}
            Port_Binding "ls1-vm2"
    Chassis "517d558e-158a-4cb2-8870-283e9d39685e"
            hostname: "ubuntu2"
            Encap geneve
                    ip: "10.127.0.3"
                    options: {csum="true"}
            Port_Binding "ls1-vm1"
    

      

    注意每个OVN Host相关联的port bindings。为了测试连接,我们在vm1这个namespace中启动一个ping命令。输出结果如下所示:

    root@ubuntu2:~# ip netns exec vm1 ping 172.16.255.22
    PING 172.16.255.22 (172.16.255.22) 56(84) bytes of data.
    64 bytes from 172.16.255.22: icmp_seq=1 ttl=64 time=1.60 ms
    64 bytes from 172.16.255.22: icmp_seq=2 ttl=64 time=0.638 ms
    64 bytes from 172.16.255.22: icmp_seq=3 ttl=64 time=0.344 ms
    

      

    Adding a 3rd "VM" and Migrating It

    接着我们加入第三个"虚拟机",并且模拟虚拟机在各个节点的迁移。首先,通过ovn-nbclt在ubuntu1中定义logical port

    ovn-nbctl lsp-add ls1 ls1-vm3
    ovn-nbctl lsp-set-addresses ls1-vm3 02:ac:10:ff:00:33
    ovn-nbctl lsp-set-port-security ls1-vm3 02:ac:10:ff:00:33
    
    ovn-nbctl show
    

      

    接着,在ubuntu2上为该虚拟机创建interface

    ip netns add vm3
    ovs-vsctl add-port br-int vm3 -- set interface vm3 type=internal
    ip link set vm3 netns vm3
    ip netns exec vm3 ip link set vm3 address 02:ac:10:ff:00:33
    ip netns exec vm3 ip addr add 172.16.255.33/24 dev vm3
    ip netns exec vm3 ip link set vm3 up
    ovs-vsctl set Interface vm3 external_ids:iface-id=ls1-vm3
    
    ip netns exec vm3 ip addr show
    

      

    测试vm3的连通性

    root@ubuntu2:~# ip netns exec vm3 ping 172.16.255.22
    PING 172.16.255.22 (172.16.255.22) 56(84) bytes of data.
    64 bytes from 172.16.255.22: icmp_seq=1 ttl=64 time=2.04 ms
    64 bytes from 172.16.255.22: icmp_seq=2 ttl=64 time=0.337 ms
    64 bytes from 172.16.255.22: icmp_seq=3 ttl=64 time=0.536 ms
    

      

    注意OVN southbound DB中的配置。我们可以看到ubuntu2由两个已经注册的port bindings

    root@ubuntu1:~# ovn-sbctl show
    Chassis "239f2c28-90ff-468f-a701-655585c630bf"
            hostname: "ubuntu3"
            Encap geneve
                    ip: "10.127.0.4"
                    options: {csum="true"}
            Port_Binding "ls1-vm2"
    Chassis "517d558e-158a-4cb2-8870-283e9d39685e"
            hostname: "ubuntu2"
            Encap geneve
                    ip: "10.127.0.3"
                    options: {csum="true"}
            Port_Binding "ls1-vm3"
            Port_Binding "ls1-vm1"
    

      

    为了模拟vm3的迁移,我们先在ubuntu2中删除"vm3"这个namespace,并且将它的port从br-int上移除,最后在ubuntu3上重新进行创建。

    ubuntu2:

    ip netns del vm3
    ovs-vsctl --if-exists --with-iface del-port br-int vm3
    ovs-vsctl list-ports br-int
    

      

    ubuntu3:

    ip netns add vm3
    ovs-vsctl add-port br-int vm3 -- set interface vm3 type=internal
    ip link set vm3 netns vm3
    ip netns exec vm3 ip link set vm3 address 02:ac:10:ff:00:33
    ip netns exec vm3 ip addr add 172.16.255.33/24 dev vm3
    ip netns exec vm3 ip link set vm3 up
    ovs-vsctl set Interface vm3 external_ids:iface-id=ls1-vm3
    

      

    测试连接:

    root@ubuntu3:~# ip netns exec vm3 ping 172.16.255.11
    PING 172.16.255.11 (172.16.255.11) 56(84) bytes of data.
    64 bytes from 172.16.255.11: icmp_seq=1 ttl=64 time=1.44 ms
    64 bytes from 172.16.255.11: icmp_seq=2 ttl=64 time=0.407 ms
    64 bytes from 172.16.255.11: icmp_seq=3 ttl=64 time=0.395 ms
    

      

    再一次,我们在ubuntu1中观察OVN southbound DB configuration。我们可以看到port binding已经发生了改变。

    root@ubuntu1:~# ovn-sbctl show
    Chassis "239f2c28-90ff-468f-a701-655585c630bf"
            hostname: "ubuntu3"
            Encap geneve
                    ip: "10.127.0.4"
                    options: {csum="true"}
            Port_Binding "ls1-vm2"
            Port_Binding "ls1-vm3"
    Chassis "517d558e-158a-4cb2-8870-283e9d39685e"
            hostname: "ubuntu2"
            Encap geneve
                    ip: "10.127.0.3"
                    options: {csum="true"}
            Port_Binding "ls1-vm1"
    

      

    Cleaning Up

    在退出前,我们先对环境进行清理

    ubuntu1:

    # delete the logical switch and its ports
    ovn-nbctl ls-del ls1
    

      

    ubuntu2:

    # delete vm1
    ip netns del vm1
    ovs-vsctl --if-exists --with-iface del-port br-int vm1
    

      

    ubuntu3:

    # delete vm2 and vm3
    ip netns del vm2
    ovs-vsctl --if-exists --with-iface del-port br-int vm2
    
    ip netns del vm3
    ovs-vsctl --if-exists --with-iface del-port br-int vm3
    

      

    Final Words

    我们可以看到,使用OVN创建一个二层的overlay network是相对比较直接的。在下一篇文章中,我将通过介绍OVN logical router来讨论OVN 三层网络

  • 相关阅读:
    assert用法,原理,改编(C++)
    使用临界段实现优化的进程间同步对象原理和实现 (转)
    去除表达式里面多余的()
    为什么C++编译器不能支持对模板的分离式编译
    python试题[转]
    从CSDN的趣味题学Python
    即时战略游戏中如何协调对象移动
    贪心算法精讲
    游戏引擎大全
    I/O 完成端口( Windows核心编程 )
  • 原文地址:https://www.cnblogs.com/YaoDD/p/7474536.html
Copyright © 2011-2022 走看看