SDN第三章实验

实验一:Open vSwitch的安装和配置

由于安装mininet时就已经安装好Open vSwitch了,所以这里略过。

# 查看ovs版本
ovs-vsctl --version

image-20241015212707142

实验二:Open vSwitch的网桥管理

1、实验环境检查

执行sudo ovs-vsctl show命令查看网桥。如果有网桥,则将网桥删除。

# 查看网桥
sudo ovs-vsctl show
# 删除网桥br0
sudo ovs-vsctl del-br br0

image-20241015215303605

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

image-20241015215802953

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

image-20241015220709053

如果不删除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

image-20241015221926370

  • 数据路径标识符 (dpid): 0000ea5a25ce3741。这是桥接器的唯一标识符。
  • 表数量 (n_tables): 254。表示该桥接器支持的最大流表数量为254个。
  • 缓冲区数量 (n_buffers): 256。这表明桥接器可以同时处理的最大数据包缓存数量是256个。
  • 功能 (capabilities): 包括流统计信息、表统计信息、端口统计信息和队列统计信息。这些功能允许收集关于网络流量的详细统计数据。
  • 支持的动作 (actions): 列出了桥接器能够执行的一系列操作,例如设置VLAN标签、修改数据包头部字段等。
  • LOCAL(br0): 表示这是一个本地接口,其MAC地址为 ea:5a:25:ce:37:41。configstate 字段都为0,意味着此接口没有特定的配置或状态标志被设置。
  • 速度: 当前和最大速度均为0 Mbps,这可能是因为这个接口是一个虚拟接口,并不直接对应于物理网卡的速度。
  • 配置 (OFPT_GET_CONFIG_REPLY): 这部分信息显示了交换机的配置,如数据包碎片处理方式(frags=normal)和当流表未命中时发送给控制器的数据包长度(miss_send_len=0)。

(2)查看交换机的初始流表信息。

sudo ovs-ofctl dump-flows br0

image-20241015222206772

(3)添加一条流表项。

设置流表生命周期为1000s,优先级为17,入端口为3,动作是output:2。

sudo ovs-ofctl add-flow br0 idle_timeout=1000,priority=17,in_port=3,actions=output:2

image-20241015222531482

(4)查看交换机的所有流表信息。

sudo ovs-ofctl dump-flows br0

image-20241015222656855

(5)删除端口为3的流表项,再次查看流表信息。

sudo ovs-ofctl del-flows br0 in_port=3
sudo ovs-ofctl dump-flows br0

image-20241015222923698

实验四:Open vSwitch的QoS设置及端口映射

场景一 QoS设置

(1)实验环境检查

本实验需要使用到netperf软件包,实验过程中,虚拟机会出现无法访问外网的情况,请先安装好该软件包。

sudo apt install netperf

查看并删除交换机S1中的网桥。

ovs-vsctl show
ovs-vsctl del-br br0
# 注:如果是普通用户,需要加上sudo,之后的命令也是一样。

image-20241015224204572

分别在交换机S1和主机1中使用ifconfig命令查看IP地址信息。

image-20241015224702707

在我的环境中,主机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

image-20241015224902855

(2)测试主机间的吞吐量

在交换机S1上查看OVS进程。

ps -ef | grep ovs

image-20241015225315268

创建网桥br0,并将eth0网卡挂接到br0。

ovs-vsctl add-br br0
ovs-vsctl add-port br0 eth0

image-20241015225528172

注:将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

image-20241015232356578

下面这部分内容与本实验无关。

注意:此时的网络连接并没有完全恢复正常,虚拟机依然无法访问外网。外部(物理机,以及其他虚拟机)可以访问该虚拟机,但是改虚拟机无法主动访问外部网络。

原因可能是因为我们移除了eth的地址,并将eth原先的地址赋给了br0,希望通过br0来通信。但是,查看路由表发现,默认网关仍然是指向eth0的,所以造成了虚拟机无法访问外部网络。

image-20241015234054734

解决方法是,删除接口为eth0的默认网关,并添加新的接口为br0的默认网关:

# 删除旧的默认网关
sudo route del default gw 192.168.66.254 eth0
# 添加新的默认网关,接口为br0
sudo route add default gw 192.168.66.254 br0

image-20241015234403078

将Open vSwitch主机作为Netperf的服务器:

netserver -p 9991

image-20241018110002841

服务启动后,默认程序在后台运行,可以使用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

image-20241018110919726

可以看到,上面的测试中发送了两组测试数据,吞吐量都是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) 为单位),此接口可以发送的超出管制速率。

image-20241018112228697

设置好后,回到主机1,再次测试吞吐量:

# 在主机1上执行该命令
netperf -t UDP_STREAM -H [交换机S1的IP] -p 9991
# 例如:
netperf -t UDP_STREAM -H 192.168.66.52 -p 9991

image-20241018112435761

由运行结果可知,吞吐量确实被限制了。

场景二 端口映射

(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

image-20241018125614189

(2)设置端口映射

查看端口序号uuid。

ovs-vsctl list port | more

eth1的uuid是d7a1718e-f2b2-4010-a854-17ec3cbf09b9

image-20241018130006596

eth2的uuid是13efc493-6153-4dd1-a11f-445595ec353a

image-20241018130100267

eth3的uuid是389d148a-5117-4d67-8402-ecc9e53a4937

image-20241018130132144

进行端口映射,将发往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

image-20241018131158446

对上述端口映射的命令的解释:

  1. -- set bridge br-sw mirrors=@m:
    • --:分隔符,表示这是一个新的子命令。
    • set: 设置指定对象的属性。
    • bridge br-sw: 指定要操作的桥接器(br-sw)。
    • mirrors=@m: 将桥接器的 mirrors 属性设置为一个名为 @m 的镜像对象。这里的 @m 是一个临时引用,用于在后续命令中引用这个镜像对象。
  2. -- --id=@m create mirror name=mymirror:
    • --:分隔符,表示这是一个新的子命令。
    • --id=@m: 创建一个新的镜像对象,并将其 ID 设置为 @m。这个 @m 与前面的 mirrors=@m 中的 @m 是同一个引用。
    • create mirror: 创建一个镜像对象。
    • name=mymirror: 为镜像对象指定一个名称(mymirror)。
  3. select-dst-port=<eth1的UUID>:
    • select-dst-port: 指定目标端口(即流量的目的端口)。这意味着只有那些目的端口为 eth1 的流量会被镜像。
    • <eth1的UUID>: eth1 端口的唯一标识符(UUID),可以通过 ovs-vsctl list-ports <bridge> 命令获取。
  4. select-src-port=<eth2的UUID>:
    • select-src-port: 指定源端口(即流量的源端口)。这意味着只有那些源端口为 eth2 的流量会被镜像。
    • <eth2的UUID>: eth2 端口的唯一标识符(UUID),可以通过 ovs-vsctl list-ports <bridge> 命令获取。
  5. 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

image-20241018224336905

(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 能够监控 eth1eth4 的流量。

# 将从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了。

image-20241021152444331

设置完端口映射后,就实现了题目要求。

课堂练习1

要求:创建下图中的topo,将eth1和eth2的端口映射到eht3上,实现在eth3上对eth1和eth2的流量监控。

image-20241021185238164

(1)创建topo

打开一个终端(终端1),在终端1中执行下面的命令,创建topo。

mn --topo single,2

image-20241021185030088

再新建一个终端(终端2),执行如下命令,给交换机S1添加端口s1-eth3

# 在终端2中执行
ovs-vsctl add-port s1 s1-eth3

更改端口s1-eth3的类型为internal(内部类型):

# 在终端2中执行
ovs-vsctl set interface s1-eth3 type=internal

image-20241021185640841

查看是否更改成功

# 在终端2中执行
ifconfig
# 执行命令后,可以看到名为s1-eth3的网卡

image-20241021161947119

(2)监控s1-eth3的流量

在终端2中执行下面的命令,监控s1-eth3的流量。

# 终端2中执行
tcpdump -i s1-eth3

image-20241021185733887

回到终端1中,执行下面的命令,让h1 ping h2,产生流量。

h1 ping h2

image-20241021185840497

再切换到终端2中,可以看到,在s1-eth3端口中只捕获到了一条数据。

由下图中可以看到,这条数据是一个ARP数据包,Request who-has 10.0.0.2 tell 10.0.0.1表示主机h1在通过ARP报文解析主机h2的MAC地址。之所以能收到这条数据包,是因为arp使用的是广播。

image-20241021185916206

为了使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

image-20241021190751941

此时,回到终端2中,即可看到,在s1-eth3上捕获到了端口s1-eth1和s1-eth2的流量。

image-20241021190818882

课堂练习2

(1)安装JDK

参考:Linux之Ubuntu18.04安装Java JDK8的三种方式_ubuntu jave8 镜像站-CSDN博客

华为镜像站下载jdk:Index of java-local/jdk/8u151-b12

image-20241028153537432

下载好后,将文件复制到虚拟机中。这里是放在了Downloads目录。

image-20241028153637555

进入到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/

image-20241028154320370

修改环境变量

# 打开文件
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  

image-20241028154530249

使环境变量立即生效

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

image-20241028154856369

(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

image-20241028145757287

执行下面的命令,启动sflow-rt

sudo systemctl enable sflow-rt
sudo systemctl start sflow-rt

我这里执行上面的命令无法运行。只能手动运行。

# 进入到sflow-rt安装目录
cd /usr/local/sflow-rt/bin/
# 手动运行run-rt
./run-rt

image-20241028155446960

运行后,在虚拟机的浏览器中访问网址http://127.0.0.1:8008,如下图。

image-20241028155802037

这个终端(终端0)不要关闭,请重新创建一个终端继续接下来的实验。

(3)创建topo

注意,接下来的命令请再虚拟机中运行。

新建一个终端(终端1),执行下面的命令,创建topo。

# 创建topo
sudo mn

image-20241028160215153

再用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的端口状态

image-20241028200356432

现在回到Mininet的终端,终端1。用h1 ping h2。

h1 ping h2

image-20241028200718031

(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

image-20241028201102245

解释:

  • agent:虚拟机对应的某个监控流量的网卡,本实验用s1网卡产生和监控流量;
  • target:sFlow Collector 的 IP,默认端口6343;
  • bridge:需要开启 sflow 的网桥;

打开虚拟机中的浏览器,在地址栏输入127.0.0.1:8008,查看监控结果。

image-20241028201803081

参考文章:基于Mininet,搭建简单的sFlow测试环境 - cyquen - 博客园

其他

关于ingress_policing_rate 和 ingress_policing_burst 的默认单位的问题。

书上说两者都是kbit/s。但我在一片博客中看到"ingress_policing_burst:策略算法的一个参数,用于指示接口可发送的超过配置的策略速率的最大数据量(以KB为单位)。",问AI,AI的回答是bit/s。

于是我查阅了ovs官方文档,看到下面这样一段。但这也只能证明rate的默认单位是kbit/s。

image-20241018120450597

后来继续找,终于让我找到了,书上说的是对的。

官方文档QoS配置链接:服务质量 (QoS) 速率限制 — Open vSwitch 3.4.90 文档

虽然我的Open vSwitch版本是2.0.2但是,根据实验结果分析,默认单位确实是kbit/s。

image-20241018121409470

posted @ 2024-10-18 23:00  最爱喝开水  阅读(129)  评论(0编辑  收藏  举报