GNS3是一个专业的网络模拟器,可以用它来模拟交换机、路由器、防火墙等网络设备。它的功能非常强大,基于它能搭建一个近似于 “真实”的模拟环境。
Wireshark是一个跨平台的网络数据包分析工具,和tcpdump比较它提供了一个友好的GUI界面。GNS3中已经对它进行了集成(安装GNS3的时候自动安装),可以通过GNS3界面直接对网络拓扑中的某条链路抓包分析。
1.1 GNS3架构
GNS3由三部分组成,我们平时使用的是GNS3-GUI,这是一个用Python编写的GUI界面,通过这个界面我们定义网络拓扑、各种要模拟的网络元素(网元)。
GNS3中模拟网元分为两类,一类是IOU(IOS on Unix)组成的传统网元;一类是通过虚拟机+镜像创建的“虚拟机网元”。前者主要用来模拟Cisco的二层、三层交换机;后者主要用来模拟一些基于x86的网元,比如Citrix NetScaler、F5 BIG-IP、甚至Cisco的NX-OSv 9000,我们要模拟的OVS也属于这类。
1.2 GNS3安装
GNS3支持Windows、Linux、Mac三个平台,它们的使用和操作界面大同小异。安装的时候我们需要下载两个东西,一个是GNS3 VM;一个是GNS3 GUI。前者是一个GNS3封装的Linux虚拟机,IOU就运行在这台虚拟机里面。GNS3-GUI是一个交互界面,我们通过它完成拓扑规划。
大家可以通过官方网站可以下载到和自己操作系统相关的镜像,下载的时候会可能会需要GNS3的一个账号(可以免费注册)。GNS3的安装过程非常简单,不再赘述。GNS3 VM下载成功后是一个zip文件,解压后能得到一个ova文件,把它导入到虚拟机里面。
1.3 GNS3配置
首次启动GNS3会弹出一个向导,引导我们设置,直接关闭这个对话框。选择“Edit”->“Preferences”打开“Preferences”对话框。
配置GNS3 VM
确保勾选上“Enable the GNS3 VM”,这个选项是GNS3 VM的大小、容量的配置。GNS3 VM里面运行的有一个gns-server进程,当我们模拟IOU网元的实际上就是跑在这台虚拟机上,所以如果你要运行大量的IOU网元建议把它的配置调整高一点。
配置VPCS
Simple Virtual PC Simulator(VPCS)是一个GNS3自带的模拟网元,它会模拟一个简单的PC端——只提供一些简单的网络命令。运行的时候它是一个标准的操作系统进程(其实你可以在GNS3的安装目录中找到vpcs的二进制文件),在模拟的时候GNS3会让我们勾选VPCS进程要运行在哪里
它同时支持运行在本地和GNS3 VM上。我一般习惯把什么东西都丢到GNS3 VM上。为了避免每拖放一个VPCS后GNS3都每次来烦你,我们可以设置一个VPCS的模板,在模板中选择VPCS运行在GNS3 VM中。
1.4 配置IOU
Dynamips是一种老式的Cisco设备模拟方法,已经没人用了,我们不再介绍。本书用IOU的方式模拟传统网络设备。
Cisco提供的IOU镜像都是标准的Linux二进制文件,可以在Linux中直接执行。这些镜像Cisco并不是免费、公开提供的,必须有Cisco的一些账号才可以在Cisco官方网站上下载,当然你也可以借助搜索引擎来下载到这些镜像。
镜像通常都是以.bin结尾的,如果你用file命令查看,发现它们是可以被直接执行的。通过GNS3的向导我们可以把这些镜像上传到GNS3 VM中,这样我们就可以模拟创建出传统二层、三层的设备。这种模拟方法是Mininet所不具备的。本书中有三个镜像,分别是二层交换机标准版、企业版;三层路由器标准版、企业版。
1.5 配置VMWare VM
通过VMWare Workstation可以创建一个Ubuntu 17的Linux操作系统,我们可以把它理解为“模板”(可以创建更多的虚拟机来加入到GNS3模拟的网络中,比如笔者使用TinyLinuxCore模拟Linux终端;创建Windows7来模拟Windows终端)。
在GNS3的这个界面我们配置Ubuntu17这个虚拟机为模板(截图中命名为ovs-linux),当我们拖放一台“OVS-Linux”的时候实际上就是复制了一个虚拟机。
建议勾选“Use as a linked base VM”选项,否则GNS3会直接使用这台虚拟机而不是创建一台新的虚拟机。这样我们模拟多个OVS的时候会比较麻烦(需要手工创建多个虚拟机)。
前面步骤创建的虚拟机只有一块NAT网卡,我们把这个当做“管理”网络。作为一台“虚拟机交换机”OVS一般会配置多块网卡,这里我们配置5块网卡。点击“Edit”,勾选上Allow GNS3 to override non custom VMWare adapter,允许我们添加网元的时候指定网卡数量。
默认情况下GNS3会帮我们创建vmnet2-vmnet8,6个“仅主机”类型的网络。我们必须通过“Advanced local setting”针对上面是10块网卡增加一些网络。
点击Configure按钮GNS3就会调用VMWare的接口自动去创建出vmnet2-vmnet13的网络(我的vmnet8留作它用,所以GNS3忽略了这个网络)。点击Reset按钮会把GNS3创建的网络全部删掉。
我们还可以通过菜单中的VMnet Manager完成上述配置,过程相似不再赘述。
2.1 搭建拓扑
通过前面的配置我们已经搭建了一个“仿真的”OVS模拟环境,下面我们通过一个例子来“享受”一下我们的劳动成功。
GNS3的界面有两个核心部分组成,左边的是工具栏。我们配置的IOU、X86网元都在这里。中间的空白是主操作区域,在这个区域画出我们的拓扑,操作网元。
创建一个helloworld项目。
拖放一个OVS、两个VPCS到主操作区
GNS3中把网元连接起来都是通过“Add a link”按钮完成的,它在工具栏最下面。点击它之后再去点击网元就可以把它们连接起来。
我们的实验是要把PC1连接到ovs的1号口;PC2连接到ovs的2号口。完成后的拓扑如下
我们也可通过界面右上角的“Topology Summary”查看拓扑
右击每个网元,选择Start。也可以Ctrl+A全选->右击->Start,这样就启动了所有的网元。
右击菜单中的“Console”对于X86网元是没有用的,所以我们必须通过SSH连接到刚刚创建的OVS中。
2.2 验证调试
回到VMWare Workstation我们会发现多了一个叫ovs-linux-1的虚拟机,我们可以直接通过控制台登录到虚拟机里面,通过ifconfig命令,查看IP地址,第一块网卡作为我们的管理网络。为了便于操作,我直接通过这个SSH访问这个IP地址。
通过ip link命令可以看到我们添加的10块网卡,它们都处于down的状态。
我们把1、2(对应的是ens38、ens39)设置为up状态;然后创建一个ovs网桥,把这两块网卡加入到网桥中。
现在为PC1和PC2配置上IP地址,它们不是x86网元,右击选择Console可以直接打开Console。
虽然我们什么也没有做但是PC1和PC2互相访问了。这是由于OVS为每个网桥都配置了一条默认的流表。
为了验证数据包确实从PC1发到了PC2,我们在ovs-linux-1和PC2之间的链路抓包。
我们可以看到在这个链路上是有PC1、PC2之间的ICMP数据包产生的。
我们把默认流表删掉删掉,然后再试一下能否访问
PC1和PC2不可以互相访问
我们抓取PC1到ovs-linux-1之间的链路数据可以判断出是由于两条PC1、PC2之间不能相互通信,Wireshark显示它们之间ARP解析失败。
3.1 OVN简介
Open vSwitch(OVS)是一款开源的“虚拟交换机”,控制协议方面它不但支持OpenFlow的所有特性而且扩展了部分OpenFlow的功能;Overlay协议方面它支持GRE, VXLAN, STT, Geneve四种主流Overlay数据包。OVS已经是数据平面的事实标准了,很多白盒交换机都兼容它提供的接口;还有一些x86架构的交换机则直接是基于OVS和DPDK的。所以无论“上层”的ODL、ONOS、Neutron如何的翻天覆地的“闹腾”而OVS还是岿然不动(最后流表的执行者还是OVS)。
但是长期一来OVS都缺乏一个统一的网络模型(Neutron虽然花费巨大力气实现一个网络模型但是仅仅适用于OpenStack而无法用于容器更加无法单独使用),于是在2015年OVS社区宣布了一个子项目——Open Virtual Network(OVN)。它旨在为OVS提供一个控制平面,通过一个统一的网络模型为容器、虚拟机提供相同的网络服务。
虽然很多人不愿意承认但是事实上它瞄准的对象是三个——ODL、ONOS、Neutron。我们可以看一下OpenStack中networking-ovn子项目,它是基于OVN实现的“Neutron”旨在替换Neutron的L2、L3功能。对比传统的Neutron的L2、L3的实现代码它的代码量非常少。这就是OVN的优点,对比ODL、ONOS、Neutron提供的大而全、复杂庞大、紧耦合的控制器,OVN提供的是一个轻量级控制器,这个轻量级不但体现在OVN本身的代码少(只有几个C语言文件,而且代码很少),模型简单(虽然简单但是很丰富,更懂得利用OVS本身的特性)而且它的流表设计(Pipeline)也容易理解。
OVN的功能
L2功能,叫Logical switches(逻辑交换机)
L3功能,叫Logical Router(逻辑路由器)
ACL,就像我们物理交换机可以配置ACL,OVN可以针对逻辑交换机添加ACL
NAT,SNAT、DNAT都支持
Load Balancer,支持面向内部的负载均衡和提供外部访问的负载均衡
OVN的架构
这幅架构图描绘了OVN的整体架构和进程分布,为了讨论方便我们把OVN中承担“管理”任务的节点成为ovn-central;把承担实际数据转发的节点成为ovn-host(可以类比成controller node、compute node)。
OVN引入了两个全新的OVSDB,一个叫Northbound DB(北向数据库,NB),一个叫Southbound DB(南向数据库,SB);两个库都可以导出远程接口,允许用户通过OVSDB协议对数据库进行操作(不必担心OVSDB只是叫DB而已,其实它更像etcd、zookeeper这种中间件)。
NB存放的是我们定义的逻辑交换机、逻辑路由器之类的数据,我们可以通过ovn提供的命令行(ovn-nbctl)完成添加、删除、修改、查询等操作;当然可以写代码通过OVSDB协议完成类似动作。OVN的NB是面向“上层应用”的或者叫“云管平台(Cloud Management System,CMS)”所以叫“北向接口”。
SB进程比较特殊它同时接受两边的“写入”,首先是运行在ovn-host上的ovn-controller启动之后会去主动连接到ovn-central节点上的SB进程,把自己的IP地址(Chassis),本机的OVS状态(Datapath_Binding)写入到SB数据库中(所以叫南向接口)。ovn-controller还“监听”(etcd、zookeeper类似的功能)SB数据库中流表的变化(Flow)去更新本地的OVS数据库,这叫“流表下发”。
SB中的流表是由运行在ovn-central节点上的ovn-northd进程修改的,ovn-northd会“监听”NB的改变,把逻辑交换机、路由器的定义转换成流表(Flow)写入到SB数据库。
整个架构非常简单,OVN仅仅提供了一组网络模型(逻辑交换机、逻辑路由器等),提供了一个OVSDB数据库用来存放这些模型同时把数据库的访问权限开放给最终用户,让最终用户通过OVSDB协议来直接“写入”这些模型(北向)。通过一个叫ovn-northd的进程把网络模型转换成流表,放入另一个数据库让ovn-host自己来“取”流表(南向),以此完成流表下发。
3.2 拓扑规划
一般OVS试验环境建议创建N台虚拟机或者使用mininet作为试验环境,这种试验环境有三方面的缺陷1. 不具备“真实性”过于简单 2. 不便于借助Wireshark等分析工具来分析网络原理 3. 没有办法融入到真实环境,比如如何和传统L2、L3设备互联。
所以笔者这里推荐一种新的实验方式——借助GNS3完成实验。
GNS3提供OVS在2.6以上版本才会提供OVN支持(2.5的版本不太靠谱,跟现在的命令无法兼容),大家可以去官方网站上下载OVS自己来编译(目前版本是2.7)。当然如果你像我一样懒得话可以直接用编译好的,Centos没有提供OVS源,大家可以通过ovirt的yum源安装2.7版本。我个人的选择的版本是Ubuntu17(Ubuntu16带的是OVS2.5),它内置了OVS2.6版本的源,直接apt-get install就可以完成安装了。
通过GNS3创建一个拓扑
端口连接方式和服务器列表
服务器 | 业务IP|角色
ovn-node1 | 10.10.10.11 | central
ovn-node2 | 10.10.10.12 | host
ovn-node3 | 10.10.10.13 | host
截图中是ovn-node1的IP地址配置,注意我使用第二块网卡作为OVN互联网的网络(也是通过SW1互联的网卡),第一块网卡是NAT配置,由VMWare DHCP分配的,此处作为单纯的管理IP(用于SSH登录)。
3.3 安装配置
在ovn-node1上作为“管理节点”(架构图中叫 ovn-central,Ubuntu中软件包也叫 ovn-central)
安装成功后可以看到ovn相关进程,
在ovn-central启动了ovn-northd守护进程,两个OVSDB进程(分别是SB和NB)。
验证SB(6642)、NB(6641)的远程端口已经打开,
在ovn-node1、ovn-node2上安装ovn-host
安装成功后可以看到ovn相关进程
启动了ovn-controller进程和openvswtich进程
通过下面的命令把ovn-host节点连接到ovn-central(overlay封装协议为vxlan)
Java
1 |
`sudo ovs-vsctl set Open_vSwitch . external_ids:ovn-remote="tcp:10.10.10.11:6642" external_ids:ovn-encap-ip="10.10.10.12" external_ids:ovn-encap-type=vxlan` |
在ovn-node1上执行验证ovn-node2添加成功(chassis)
3.4 学会排错
由于环境不一样所以实验的过程中肯定会碰到各种问题,我们又不太可能枚举出所有的常见问题挨个说明。最有效的方式是“授人以渔”,所以后续的文章中我会尽量把如果排错写错来。今天我们先学习阅读OVN产生的日志。
ovn-central上的/var/log/openvswitch/以下几个文件:
ovn-northd.log ,ovn-northd进程产生的日志,类似下面的输出
可以看到ovn-northd进程通过unix domain socket(Linux下一种IPC通讯方式)连接上了SB、NB数据库进程。
ovsdb-server.log ,本机OVS数据库进程日志。一般我们不会让ovn-central加入到网络转发中所以这个进程以及日志都用不到。
ovsdb-server-nb.log,NB数据库日志
ovsdb-server-sb.log ,SB数据库日志
ovs-vswitchd.log,本机OVS进程,一般我们不会让ovn-central加入到网络转发中所以这个进程以及日志都用不到。
ovn-host上的/var/log/openvswitch/以下几个文件:
ovn-controller.log ,ovn-controller产生的日志,输入如下
以红线为分割,上面汇报了ovn-controller连接了两个OVSDB数据——通过unix domain socket连接到本地OVS数据库;通过TCP连接到远程OVS数据库。下面汇报了ovn-controller发现的本地网桥(Datapath)。
ovsdb-server.log ,本机OVS数据库进程日志
ovs-vswitchd.log,本机OVS进程日志
ovn-host承担数据转发功能,所以本机OVS需要参与转发的,日志是很有价值的
重点分析一下, ovs-vswitchd.log的内容。首先是汇报系统的硬件状态,通过unix domain socket连接到本地OVS数据库。**后面的“system@ovs-sytem”输出非常重要**,OVS有很多特性体现在允许使用一些OpenFlow没有定义的流表定义关键字(比如NAT,learn),这些特性中有一部分是需要系统支持的(内核模块)日志的输出说明了OVS相关特性是否工作正常。
本章我们学习了GNS3如何使用以及抓包,除此以外,对OVN主要有一个入门的了解,以及了解如何解决问题、技术架构,安装了一个OVN的实验环境,学会了分析OVN产生的日志。接下来的一章我们会开始OVN的正式学习——学习OVN网络模型中的第一部分“逻辑交换机”