LOADING

Follow me

OVN介绍及安装流程【zoues.com】
五月 3, 2017|ITPaaSSDN

OVN介绍及安装流程【zoues.com】

OVN介绍及安装流程【zoues.com】

译者简介:郑敏先,就职于诺云系统(上海)有限公司。工作地点为南京的诺云研发中心。担任解决方案工程师。 本人博客为:http://blog.csdn.net/zhengmx100

本文作者:Dustin Spinhirne ,在网络行业有超过十五年的工作经验。在Rackspace做了8年的网络架构师,后又在Nicira做了2年解决方案架构师。又随着Nicira被VMware收购而进入VMware担任解决方案架构师至今。

OVS是Nicira发布的开源虚拟交换机。OVS从发布到现在一直是业界最流行的虚拟交换机。2012年VMware以12.6亿美元收购Nicira 。VMware在OVS上继续投入更多的资源,是目前OVS/OVN社区的最大贡献者。Dustin Spinhirne在Nicira和VMware担任解决方案架构师,对OVS/OVS的应用场景有着更深的理解。因此选择其博客文章进行翻译,将其引入国内供解决方案架构师,解决方案工程师,学生等人员参考。

原文链接:http://blog.spinhirne.com/2016/09/a-primer-on-ovn.html

OVN概览

OVN是由开发出OVS的那群出色的程序员们的另一个优秀的作品。这个网络虚拟化项目从2015初宣告启动, 到不久前才发布第一个正式版本OVN 2.6 。在这篇文章中,我会配置一个简单示例:在三个主机之间配置一个layer-2 overlay 网络。
首先讲一下OVN工作机制中的2种角色:

  • OVN Central ——目前只能有一台主机承担这个角色。该主机将成为和外部资源(比如云管理平台)集成的API中心节点。中心节点运行着OVN 北向数据库和OVN南向数据库。OVN北向数据库,用于描述上层的逻辑网络组件,比如逻辑交换机/逻辑端口。南向数据库,其将北向数据库的逻辑网络数据格式转换为物理网络数据格式并进行存储。
  • OVN Host ——所有提供虚拟机或虚拟网络的节点。OVN Host 运行着 “chassis controller” ,它上连OVN南向数据库并作为其记录的物理网络信息授权来源,下接OVS 并成为其openflow 控制器。

实验环境

本次实验中使用了3 台Ubuntu 16.04主机
OVN实验拓扑: 3 台Ubuntu 16.04主机都连接到同一个管理网络 10.127.0.0/25
主机的角色和IP地址分配如下:

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

物理网络拓扑图如下:
OVN介绍及安装流程
为了方便测试,将会创建OVS内部接口并在网络命名空间(namespace)中使用沙盒技术来模拟虚拟机。命名空间能保证我们的OVN overlay网络与实验室物理网络完全隔离。

编译Open vSwitch 2.6

2016年9月28日社区发布了 Open vSwitch 2.6版本,可以从 这里下载。 下载包中的Ubuntu 的指导手册INSTALL.Debian.md非常不错。下面是按照这个指导手册进行实验后的总结:

首先为三台主机编译出相应的版本的OVS (注意ubuntu内核版本)
更新和安装依赖包:

Java

1
2
aptget update
aptget y install buildessential fakeroot

安装编译工具包:

Java

1
2
aptget y install graphviz autoconf automake bzip2 debhelper dhautoreconf libssldev libtool openssl
aptget y install procps pythonall pythontwistedconch pythonzopeinterface pythonsix

进行编译:

Java

1
2
3
cd openvswitch2.6.0
dpkgcheckbuilddeps
`DEB_BUILD_OPTIONS=‘parallel=8 nocheck’ fakeroot debian/rules binary`

生成的OVS的.deb文件路径为当前路径的上一层目录。

下面会编译openvswitch-datapath内核模块
安装datapath源:

Java

1
2
3
cd ..
aptget y install moduleassistant
dpkg i openvswitchdatapathsource_2.6.01_all.deb

使用 module-assistant编译内核模块

Java

1
2
ma prepare
ma build openvswitchdatapath

复制生成的deb包。你们重复这个实验时注意,版本号跟这里的输出的可能存在不同。

Java

1
cp /usr/src/openvswitchdatapathmodule*.deb ./

把下面的这些包传到 三台Ubuntu 主机上:

  • openvswitch-datapath-module-*.deb
  • openvswitch-common_2.6.0-1_amd64.deb
  • openvswitch-switch_2.6.0-1_amd64.deb
  • ovn-common_2.6.0-1_amd64.deb
  • ovn-central_2.6.0-1_amd64.deb
  • ovn-host_2.6.0-1_amd64.deb

安装 Open vSwitch

在ubuntu1上安装 OVS/OVN 和依赖包:

Java

1
2
3
4
5
aptget update
aptget y install pythonsix python2.7
dpkg i openvswitchdatapathmodule*.deb
dpkg i openvswitchcommon_2.6.01_amd64.deb openvswitchswitch_2.6.01_amd64.deb
dpkg i ovncommon_2.6.01_amd64.deb ovncentral_2.6.01_amd64.deb ovnhost_2.6.01_amd64.deb

在ubuntu2、ubuntu3上安装 OVS/OVN 和依赖包:

Java

1
2
3
4
5
aptget update
aptget y install pythonsix python2.7
dpkg i openvswitchdatapathmodule*.deb
dpkg i openvswitchcommon_2.6.01_amd64.deb openvswitchswitch_2.6.01_amd64.deb
dpkg i ovncommon_2.6.01_amd64.deb ovnhost_2.6.01_amd64.deb

这些包安装完成后,去ubuntu1上检查下ovsdb-server进程是否监听TCP 6641,6642端口。6641端口用于监听OVN北向数据库,6642端口用于监听OVN南向数据库。下面是我执行netstat的输出结果:

Java

1
2
3
4
5
root@ubuntu1:~# netstat lntp
Active Internet connections (only servers)
Proto RecvQ SendQ Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:6641            0.0.0.0:*               LISTEN      1798/ovsdbserver
tcp        0      0 0.0.0.0:6642            0.0.0.0:*               LISTEN      1806/ovsdbserver

如果 ovsdb-server没有使用 6641/6642 那么需要通过运行启动脚本来启动这些进程。启动脚本路径为/etc/init.d/openvswitch-switch 和 /etc/init.d/ovn-central 。

创建集成化网桥

OVS的网桥要连接到一个集成化网桥后才能够被OVN管理。通常我们给这个集成化网桥命名为“br-int”(其实可以任意命名)。首先检查环境中是否存在这个网桥,不存在的话就进行创建。

在ubuntu2、ubuntu3上:

Java

1
ovsvsctl listbr

如果看不到“br-int” 网桥,那么需要手工创建。注意:所有运行虚拟机的节点都要存在“br-int” 网桥。

Java

1
2
ovsvsctl addbr brint set Bridge brint failmode=secure
ovsvsctl listbr

“fail-mode=secure” 是一个安全特性,其让网桥丢掉所有流量。 这里用这个参数是因为我们不想在OVN控制器启用前使用网络。

将Chassis 控制器连接到中央控制器

接下来将ubuntu2/ubuntu3 上的chassis 控制器连接到ubuntu 1上的中央控制器
ubuntu2:

Java

1
2
3
ovsvsctl set open . externalids:ovnremote=tcp:10.127.0.2:6642
ovsvsctl set open . externalids:ovnencaptype=geneve
ovsvsctl set open . externalids:ovnencapip=10.127.0.3

ubuntu3:

Java

1
2
3
ovsvsctl set open . externalids:ovnremote=tcp:10.127.0.2:6642
ovsvsctl set open . externalids:ovnencaptype=geneve
ovsvsctl set open . externalids:ovnencapip=10.127.0.4

这些命令将触发ubuntu2/ubuntu3上的OVN chassis控制器发起一个到ubuntu 1上的中央控制器的连接。我们同时指定了overlay网络封装数据平面流量的协议为 geneve 协议。
在ubuntu2/ubuntu3使用netstat校验连接是否建立:

Java

1
2
root@ubuntu3:~# netstat antp | grep 10.127.0.2
tcp        0      0 10.127.0.4:39256        10.127.0.2:6642         ESTABLISHED 3072/ovncontroller

创建逻辑网络

下图是本次实验的OVN逻辑网络拓扑图。
OVN介绍及安装流程
在ubuntu1 定义一台逻辑交换机和相关的逻辑端口:

Java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 创建logical switch
ovnnbctl lsadd ls1
 
# 创建 logical port
ovnnbctl lspadd ls1 ls1vm1
ovnnbctl lspsetaddresses ls1vm1 02:ac:10:ff:00:11
ovnnbctl lspsetportsecurity ls1vm1 02:ac:10:ff:00:11
 
# 创建 logical port
ovnnbctl lspadd ls1 ls1vm2
ovnnbctl lspsetaddresses ls1vm2 02:ac:10:ff:00:22
ovnnbctl lspsetportsecurity ls1vm2 02:ac:10:ff:00:22
 
ovnnbctl show

注意,虚拟端口的名称是唯一的,不能重复。虚拟端口同时也会生成一个很长的UUID。本文使用更加人性化的端口名称来代表这些端口。我们同时定义了这些虚拟端口的mac地址。在端口安全实验(逻辑端口只允许特定的源mac地址数据包通过)将用到这些mac地址。

添加“伪虚拟机”

接下来创建连接到逻辑交换机的“伪虚拟机”。上文已经提到,我们会使用OVS内部端口和网络命名空间来模拟虚拟机。我们会给这台逻辑交换机分配172.16.255.0/24网络。
在ubuntu2上:

Java

1
2
3
4
5
6
7
8
9
ip netns add vm1
ovsvsctl addport brint 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
ovsvsctl set Interface vm1 external_ids:ifaceid=ls1vm1
 
ip netns exec vm1 ip addr show

在ubuntu3上:

Java

1
2
3
4
5
6
7
8
9
ip netns add vm2
ovsvsctl addport brint 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
ovsvsctl set Interface vm2 external_ids:ifaceid=ls1vm2
 
ip netns exec vm2 ip addr show

如果你从没接触过命名空间或者OVS,也许会对这些命令很困惑。
其实我们进行了如下几步操作:

  • 给“伪虚拟机”创建了网络命名空间,
  • 再给它添加一个OVS内部端口,
  • 再把端口添加到命名空间,
  • 在命名空间内部使用netns exec命令配置 IP地址
  • 最后创建一个OVS接口,并给这个接口指定一个external_id 。(这个ID是之前创建的逻辑接口的名称或UUID)

最后一步执行完成后,OVS就会通知OVN有逻辑端口上线了。然后,OVN向下游主机的本地chassis 控制器发送指令,同时 OVN也会将网络流量传递给上游的OVS。
注意,我已明确地给这些接口设置了与OVN逻辑交换机中相同的mac地址。这非常重要。如果mac地址没有映射正确,逻辑网络就不会正常工作。请记住,我在这里没有使用常规流程。正常情况下,你不会更改虚拟机的MAC地址,而是将现有的/已知的mac地址传递入OVN / OVS。 我为了演示方便才手动设置IP/mac地址。

测试网络连通性

在 ubuntu1 上,我们使用ovn-sbctl验证逻辑网络配置 :

Java

1
2
3
4
5
6
7
8
9
10
11
12
13
root@ubuntu1:~# ovnsbctl 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主机的端口绑定是否正常。
为了测试网络连通性,我们只需从vm1的命名空间发起ping:

Java

1
2
3
4
5
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

添加和迁移一个第三方 “虚拟机”

让我们添加一个第三方“虚拟机”,然后在主机之间迁移它。 首先,在ubuntu1上使用ovn-nbctl定义其逻辑端口:

Java

1
2
3
4
5
ovnnbctl lspadd ls1 ls1vm3
ovnnbctl lspsetaddresses ls1vm3 02:ac:10:ff:00:33
ovnnbctl lspsetportsecurity ls1vm3 02:ac:10:ff:00:33
 
ovnnbctl show

然后在ubuntu2上给这台虚拟机创建接口:

Java

1
2
3
4
5
6
7
8
9
ip netns add vm3
ovsvsctl addport brint 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
ovsvsctl set Interface vm3 external_ids:ifaceid=ls1vm3
 
ip netns exec vm3 ip addr show

从vm3测试网络:

Java

1
2
3
4
5
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

注意ubuntu1上的OVN南向数据库配置。 我们看到ubuntu2有2个注册的端口绑定。

Java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
root@ubuntu1:~# ovnsbctl 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”命名空间,删除其在br-int上的端口,然后在ubuntu3上重新进行配置。
在ubuntu2上:

Java

1
2
3
ip netns del vm3
ovsvsctl ifexists withiface delport brint vm3
ovsvsctl listports brint

在ubuntu3上:

Java

1
2
3
4
5
6
7
ip netns add vm3
ovsvsctl addport brint 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
ovsvsctl set Interface vm3 external_ids:ifaceid=ls1vm3

测试网络连通性:

Java

1
2
3
4
5
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南向数据库配置。 我们看到端口绑定已经改变。

Java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
root@ubuntu1:~# ovnsbctl 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”

清理环境

为了让环境用于后面的其他实验,我们在退出前需要清理环境。
ubuntu1:

Java

1
2
#删除逻辑交换机及其端口
ovnnbctl lsdel ls1

ubuntu2:

Java

1
2
3
# 删除 vm1
ip netns del vm1
ovsvsctl ifexists withiface delport brint vm1

ubuntu3:

Java

1
2
3
4
5
6
# delete vm2 vm3
ip netns del vm2
ovsvsctl ifexists withiface delport brint vm2
 
ip netns del vm3
ovsvsctl ifexists withiface delport brint vm3

结语

如您所见,使用OVN创建二层overlay网络相对简单。 在下一篇文章中,我们将通过引入OVN逻辑路由器来构建一个OVN基本的三层网络。

no comments
Share

发表评论