SDN第三章实验
实验一:Open vSwitch的安装和配置
由于安装mininet时就已经安装好Open vSwitch了,所以这里略过。
# 查看ovs版本
ovs-vsctl --version
实验二:Open vSwitch的网桥管理
1、实验环境检查
执行sudo ovs-vsctl show
命令查看网桥。如果有网桥,则将网桥删除。
# 查看网桥
sudo ovs-vsctl show
# 删除网桥br0
sudo ovs-vsctl del-br br0
2、添加网桥和端口
# 添加名称为br0的网桥
sudo ovs-vsctl add-br br0
# 列出所有网桥
sudo ovs-vsctl list-br
# 将物理网卡eth0挂接到网桥br0上
sudo ovs-vsctl add-port br0 eth0
# 列出挂接到网桥br0上的所有网卡
sudo ovs-vsctl list-ports br0
# 列出挂接到eth0上的所有网桥
sudo ovs-vsctl port-to-br eth0
# 查看Open vSwitch的网络状态
sudo ovs-vsctl show
3、删除网桥和端口
# 删除挂接到网桥br0上的网卡eth0
sudo ovs-vsctl del-port br0 eth0
# 查看网络状态
sudo ovs-vsctl show
# 删除网桥br0
sudo ovs-vsctl del-br br0
# 再次查看网络状态
sudo ovs-vsctl show
如果不删除eth0而直接删除br0,则br0及挂接到br0上的端口也会被一并删除。
实验三:Open vSwitch的流表管理
1、实验环境检查
# 查看网桥
sudo ovs-vsctl show
# 删除网桥br0
sudo ovs-vsctl del-br br0
没有网桥则不需要删除。
2、流表管理
(1)添加网桥并查看虚拟交换机的基本信息。
sudo ovs-vsctl add-br br0
sudo ovs-ofctl show br0
- 数据路径标识符 (dpid): 0000ea5a25ce3741。这是桥接器的唯一标识符。
- 表数量 (n_tables): 254。表示该桥接器支持的最大流表数量为254个。
- 缓冲区数量 (n_buffers): 256。这表明桥接器可以同时处理的最大数据包缓存数量是256个。
- 功能 (capabilities): 包括流统计信息、表统计信息、端口统计信息和队列统计信息。这些功能允许收集关于网络流量的详细统计数据。
- 支持的动作 (actions): 列出了桥接器能够执行的一系列操作,例如设置VLAN标签、修改数据包头部字段等。
- LOCAL(br0): 表示这是一个本地接口,其MAC地址为 ea:5a:25:ce:37:41。
config
和state
字段都为0,意味着此接口没有特定的配置或状态标志被设置。 - 速度: 当前和最大速度均为0 Mbps,这可能是因为这个接口是一个虚拟接口,并不直接对应于物理网卡的速度。
- 配置 (OFPT_GET_CONFIG_REPLY): 这部分信息显示了交换机的配置,如数据包碎片处理方式(
frags=normal
)和当流表未命中时发送给控制器的数据包长度(miss_send_len=0
)。
(2)查看交换机的初始流表信息。
sudo ovs-ofctl dump-flows br0
(3)添加一条流表项。
设置流表生命周期为1000s,优先级为17,入端口为3,动作是output:2。
sudo ovs-ofctl add-flow br0 idle_timeout=1000,priority=17,in_port=3,actions=output:2
(4)查看交换机的所有流表信息。
sudo ovs-ofctl dump-flows br0
(5)删除端口为3的流表项,再次查看流表信息。
sudo ovs-ofctl del-flows br0 in_port=3
sudo ovs-ofctl dump-flows br0
实验四:Open vSwitch的QoS设置及端口映射
场景一 QoS设置
(1)实验环境检查
本实验需要使用到netperf软件包,实验过程中,虚拟机会出现无法访问外网的情况,请先安装好该软件包。
sudo apt install netperf
查看并删除交换机S1中的网桥。
ovs-vsctl show
ovs-vsctl del-br br0
# 注:如果是普通用户,需要加上sudo,之后的命令也是一样。
分别在交换机S1和主机1中使用ifconfig
命令查看IP地址信息。
在我的环境中,主机1与S1的IP分别为192.168.66.51和192.168.66.52。(请保证主机1与S1在同一网段,否则后续实验将无法进行)。
后续涉及到IP地址的命令需要根据自己的情况来调整。
测试主机与交换机的连通性
# 用主机1去ping交换机S1
ping your_S1_IP
# 我的环境下:
ping 192.168.66.52
(2)测试主机间的吞吐量
在交换机S1上查看OVS进程。
ps -ef | grep ovs
创建网桥br0,并将eth0网卡挂接到br0。
ovs-vsctl add-br br0
ovs-vsctl add-port br0 eth0
注:将eth0挂接到br0上后,虚拟机的网络将变得不可用(不可访问外网、物理机、哪怕是同一网段的虚拟机也无法访问。
如果是使用远程方式登录的虚拟机,接下来的命令请转到虚拟机内部执行。
将eth0的IP地址赋给br0。
# 将 eth0 的 IP 地址设置为 0.0.0.0,实际上就是移除了它的 IP 圴址,并保持接口处于活动状态。
ifconfig eth0 0 up
# 为 br0 配置 IP 地址并激活(执行完下面这条命令后,就可以继续使用远程连接登录了)
ifconfig br0 192.168.66.52/24 up
# 查看网卡信息
ifconfig
下面这部分内容与本实验无关。
注意:此时的网络连接并没有完全恢复正常,虚拟机依然无法访问外网。外部(物理机,以及其他虚拟机)可以访问该虚拟机,但是改虚拟机无法主动访问外部网络。
原因可能是因为我们移除了eth的地址,并将eth原先的地址赋给了br0,希望通过br0来通信。但是,查看路由表发现,默认网关仍然是指向eth0的,所以造成了虚拟机无法访问外部网络。
解决方法是,删除接口为eth0的默认网关,并添加新的接口为br0的默认网关:
# 删除旧的默认网关 sudo route del default gw 192.168.66.254 eth0 # 添加新的默认网关,接口为br0 sudo route add default gw 192.168.66.254 br0
将Open vSwitch主机作为Netperf的服务器:
netserver -p 9991
服务启动后,默认程序在后台运行,可以使用
ps -ef | grep netserver
命令查看进程
将主机1作为Netperf的客户端,测量主机1与服务器之间的吞吐量。
# 在主机1上执行该命令
netperf -t UDP_STREAM -H [交换机S1的IP] -p 9991
# 例如:
netperf -t UDP_STREAM -H 192.168.66.52 -p 9991
可以看到,上面的测试中发送了两组测试数据,吞吐量都是900*10**6bps,即900Mbps左右(1bps就是1bit/s)。
(3)设置QoS参数
现在,回到交换机S1上,将eth0的吞吐量设置为(100±50)Mbit/s。
# 设置入方向流量速率限制(设置限制最大速率)
ovs-vsctl set interface eth0 ingress_policing_rate=100000
# 设置入方向流量突发限制(设置最大浮动速率)
ovs-vsctl set interface eth0 ingress_policing_burst=50000
# ingress_policing_rate 的默认单位都是Kbps, ingress_policing_burst 的默认单位是Kb。
ingress_policing_rate:应允许此 VM 发送的最大速率(以 Kbps 为单位)
ingress_policing_burst:管制算法的参数,用于指示最大数据量 (以 Kb) 为单位),此接口可以发送的超出管制速率。
设置好后,回到主机1,再次测试吞吐量:
# 在主机1上执行该命令
netperf -t UDP_STREAM -H [交换机S1的IP] -p 9991
# 例如:
netperf -t UDP_STREAM -H 192.168.66.52 -p 9991
由运行结果可知,吞吐量确实被限制了。
场景二 端口映射
(1)实验环境准备
由于当前环境中没有虚拟交换机,所以就新建一个。
# 创建网桥br-sw
root@UbuntuDesktop:~# ovs-vsctl add-br br-sw
# 添加端口
root@UbuntuDesktop:~# ovs-vsctl add-port br-sw eth1
root@UbuntuDesktop:~# ovs-vsctl add-port br-sw eth2
root@UbuntuDesktop:~# ovs-vsctl add-port br-sw eth3
# 查看网桥信息
root@UbuntuDesktop:~# ovs-vsctl show
(2)设置端口映射
查看端口序号uuid。
ovs-vsctl list port | more
eth1的uuid是d7a1718e-f2b2-4010-a854-17ec3cbf09b9
eth2的uuid是13efc493-6153-4dd1-a11f-445595ec353a
eth3的uuid是389d148a-5117-4d67-8402-ecc9e53a4937
进行端口映射,将发往eth1端口和从eth2端口发出的数据包全部定向到eth3。
ovs-vsctl \
-- set bridge br-sw mirrors=@m \
-- --id=@m create mirror name=mymirror \
select-dst-port=eth1的uuid \
select-src-port=eth2的uuid \
output-port=eth3的uuid
# 验证配置是否成功
ovs-vsctl list mirror
对上述端口映射的命令的解释:
-- set bridge br-sw mirrors=@m
:--
:分隔符,表示这是一个新的子命令。set
: 设置指定对象的属性。bridge br-sw
: 指定要操作的桥接器(br-sw
)。mirrors=@m
: 将桥接器的mirrors
属性设置为一个名为@m
的镜像对象。这里的@m
是一个临时引用,用于在后续命令中引用这个镜像对象。
-- --id=@m create mirror name=mymirror
:--
:分隔符,表示这是一个新的子命令。--id=@m
: 创建一个新的镜像对象,并将其 ID 设置为@m
。这个@m
与前面的mirrors=@m
中的@m
是同一个引用。create mirror
: 创建一个镜像对象。name=mymirror
: 为镜像对象指定一个名称(mymirror
)。
select-dst-port=<eth1的UUID>
:select-dst-port
: 指定目标端口(即流量的目的端口)。这意味着只有那些目的端口为eth1
的流量会被镜像。<eth1的UUID>
:eth1
端口的唯一标识符(UUID),可以通过ovs-vsctl list-ports <bridge>
命令获取。
select-src-port=<eth2的UUID>
:select-src-port
: 指定源端口(即流量的源端口)。这意味着只有那些源端口为eth2
的流量会被镜像。<eth2的UUID>
:eth2
端口的唯一标识符(UUID),可以通过ovs-vsctl list-ports <bridge>
命令获取。
output-port=<eth3的UUID>
:output-port
: 指定输出端口,即将镜像的流量发送到的端口。<eth3的UUID>
:eth3
端口的唯一标识符(UUID),可以通过ovs-vsctl list-ports <bridge>
命令获取。
练习
第8题
假设某网吧使用 OVS 进行总机数据交换,该 OVS现有网桥及端口信息如图 3-56 所示,假设端口 eth1 和eth4 的速率需求为 1000 kbit/s。现要求用 eth8 对上述两个端口进行监控,同时为3个端口提供 QoS 保障。试根据实验所学内容,写出 OVS 的关键配置步骤。
(1)实验环境准备
根据题目要求创建网桥及对应端口。
root@UbuntuDesktop:~# ovs-vsctl add-br br-sw
root@UbuntuDesktop:~# ovs-vsctl add-port br-sw eth1
root@UbuntuDesktop:~# ovs-vsctl add-port br-sw eth4
root@UbuntuDesktop:~# ovs-vsctl add-port br-sw eth8
root@UbuntuDesktop:~# ovs-vsctl show
(2)设置QoS参数
#将eth1的端口速率和突发流量都设置为1000kbit/s
root@UbuntuDesktop:~# ovs-vsctl set interface eth1 ingress_policing_rate=1000
root@UbuntuDesktop:~# ovs-vsctl set interface eth1 ingress_policing_burst=1000
#将eth4的端口速率和突发流量都设置为1000kbit/s
root@UbuntuDesktop:~# ovs-vsctl set interface eth4 ingress_policing_burst=1000
root@UbuntuDesktop:~# ovs-vsctl set interface eth4 ingress_policing_rate=1000
(3)设置端口映射
查看端口uudi:
ovs-vsctl list port | more
eth1的uuid为5869b36e-8dbc-4627-b8d9-e3814055255f
,eth4的uuid为4f84c676-33f6-4782-8f7b-a6bbe4a33202
,eth8的uuid为1b16f9b5-9064-49da-a893-116be3567a2d
。
配置镜像,使 eth8
能够监控 eth1
和 eth4
的流量。
# 将从eth1或eth4发出或接收的数据包全部重定向到eth8
ovs-vsctl \
-- set bridge br-sw mirrors=@m \
-- --id=@m create mirror name=mymirror \
select-dst-port=eth1的uuid,eth4的uuid \
select-src-port=eth1的uuid,eth4的uuid \
output-port=eth8的uuid
# 上述命令也可以写为
ovs-vsctl -- set bridge br-sw mirrors=@m \
-- --id=@eth1 get port eth1 \
-- --id=@eth4 get port eth4 \
-- --id=@eth8 get port eth8 \
-- --id=@m create mirror name=mymirror \
select-dst-port=@eth1,@eth4 select-src-port=@eth1,@eth4 output-port=@eth8
解释:
--id=@eth1 get port eth1
@eth1相当于一个变量,
get port eth1用于获取eth1端口的属性,
这条子命令的作用就是获取eth1端口的详细信息,并赋值给@eth1
# 这样,在后面的select-dst-port=@eth1,@eth4命令中,就不需要手动输入对应接口的uuid了。
设置完端口映射后,就实现了题目要求。
课堂练习1
要求:创建下图中的topo,将eth1和eth2的端口映射到eht3上,实现在eth3上对eth1和eth2的流量监控。
(1)创建topo
打开一个终端(终端1),在终端1中执行下面的命令,创建topo。
mn --topo single,2
再新建一个终端(终端2),执行如下命令,给交换机S1添加端口s1-eth3
。
# 在终端2中执行
ovs-vsctl add-port s1 s1-eth3
更改端口s1-eth3
的类型为internal(内部类型):
# 在终端2中执行
ovs-vsctl set interface s1-eth3 type=internal
查看是否更改成功
# 在终端2中执行
ifconfig
# 执行命令后,可以看到名为s1-eth3的网卡
(2)监控s1-eth3的流量
在终端2中执行下面的命令,监控s1-eth3的流量。
# 终端2中执行
tcpdump -i s1-eth3
回到终端1中,执行下面的命令,让h1 ping h2,产生流量。
h1 ping h2
再切换到终端2中,可以看到,在s1-eth3端口中只捕获到了一条数据。
由下图中可以看到,这条数据是一个ARP数据包,Request who-has 10.0.0.2 tell 10.0.0.1
表示主机h1在通过ARP报文解析主机h2的MAC地址。之所以能收到这条数据包,是因为arp使用的是广播。
为了使s1-eth3能够对eth1和eth2的流量进行监控,我们需要给eth1和eth2创建映射,将流量重定向到s1-eth3中。
(3)创建端口映射
由于终端1和终端2都正在被使用,所以我们需要再新建一个终端3。
创建映射,将eth1和eth2的流量映射到eht3。
# 终端3中执行
ovs-vsctl -- set bridge s1 mirrors=@m \
-- --id=@eth1 get port s1-eth1 \
-- --id=@eth2 get port s1-eth2 \
-- --id=@eth3 get port s1-eth3 \
-- --id=@m create mirror name=mymirror \
select-dst-port=@eth1,@eth2 select-src-port=@eth1,@eth2 output-port=@eth3
此时,回到终端2中,即可看到,在s1-eth3上捕获到了端口s1-eth1和s1-eth2的流量。
课堂练习2
(1)安装JDK
参考:Linux之Ubuntu18.04安装Java JDK8的三种方式_ubuntu jave8 镜像站-CSDN博客
华为镜像站下载jdk:Index of java-local/jdk/8u151-b12
下载好后,将文件复制到虚拟机中。这里是放在了Downloads目录。
进入到JDK压缩包所在的目录,进行解压。
# 创建文件夹
sudo mkdir /usr/lib/jvm
# 将JDK解压到上面创建的文件夹
tar -zxvf jdk-8u151-linux-x64.tar.gz -C /usr/lib/jvm
查看JDK的安装目录,这里是jdk1.8.0_151,下面修改环境变量时的目录要与这里的目录名一样。
ls /usr/lib/jvm/
修改环境变量
# 打开文件
sudo vi ~/.bashrc
在文件末尾添加下面的内容
#set oracle jdk environment
export JAVA_HOME=/usr/lib/jvm/jdk1.8.0_151 ## 这里要注意目录要换成自己解压的jdk 目录
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
export PATH=${JAVA_HOME}/bin:$PATH
使环境变量立即生效
source ~/.bashrc
系统注册此JDK
sudo update-alternatives --install /usr/bin/java java /usr/lib/jvm/jdk1.8.0_151/bin/java 300
# 注意:/usr/lib/jvm/jdk1.8.0_151/bin/java这里也要改为自己的JDK目录
查看当前JDK版本。
java -version
如果执行上面的命令后,输出的版本与下载的JDK版本不一致,可能是安装了多个Java版本,通过下面的命令可以切换系统中的多个Java版本。
sudo update-alternatives --config java
(2)安装sFlow-RT
可参考官方文档:sFlow-RT 下载
# 下载sFlow-RT软件包
wget https://inmon.com/products/sFlow-RT/sflow-rt_3.0-1707.deb
# 使用功能dpkg包管理工具安装sFlow-RT
sudo dpkg -i sflow-rt_3.0-1707.deb
执行下面的命令,启动sflow-rt
sudo systemctl enable sflow-rt
sudo systemctl start sflow-rt
我这里执行上面的命令无法运行。只能手动运行。
# 进入到sflow-rt安装目录
cd /usr/local/sflow-rt/bin/
# 手动运行run-rt
./run-rt
运行后,在虚拟机的浏览器中访问网址http://127.0.0.1:8008
,如下图。
这个终端(终端0)不要关闭,请重新创建一个终端继续接下来的实验。
(3)创建topo
注意,接下来的命令请再虚拟机中运行。
新建一个终端(终端1),执行下面的命令,创建topo。
# 创建topo
sudo mn
再用h1 ping h2
重新打开一个终端(终端2),将eth0的IP复制给s1。
sudo ovs-vsctl add-port s1 eth0
sudo ovs-vsctl set Interface eth0 type=internal
sudo ifconfig s1 192.168.66.52 netmask 255.255.255.0
使用ifconfig
查看s1的端口状态
现在回到Mininet的终端,终端1。用h1 ping h2。
h1 ping h2
(4)部署sFlow Agent
再切换到终端2,执行下面的命令,开启 OvS 的 sFlow 功能。
sudo ovs-vsctl -- \
--id=@s create sFlow agent=s1 target=\"127.0.0.1:6343\" \
-- set bridge s1 sflow=@s
解释:
- agent:虚拟机对应的某个监控流量的网卡,本实验用s1网卡产生和监控流量;
- target:sFlow Collector 的 IP,默认端口6343;
- bridge:需要开启 sflow 的网桥;
打开虚拟机中的浏览器,在地址栏输入127.0.0.1:8008
,查看监控结果。
其他
关于ingress_policing_rate 和 ingress_policing_burst 的默认单位的问题。
书上说两者都是kbit/s。但我在一片博客中看到"ingress_policing_burst:策略算法的一个参数,用于指示接口可发送的超过配置的策略速率的最大数据量(以KB为单位)。",问AI,AI的回答是bit/s。
于是我查阅了ovs官方文档,看到下面这样一段。但这也只能证明rate的默认单位是kbit/s。
后来继续找,终于让我找到了,书上说的是对的。
官方文档QoS配置链接:服务质量 (QoS) 速率限制 — Open vSwitch 3.4.90 文档
虽然我的Open vSwitch版本是2.0.2但是,根据实验结果分析,默认单位确实是kbit/s。