Open vSwitch学习记录

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/iroy33/article/details/102585420

顺利完成目标~~~开开心心地开始学Open vSwitch

概念

简而言之就是一个虚拟交换机。主要有如下两个作用:

  • 传递虚拟机啊VM之间的流量
  • 实现VM和外界网络的通信

在这里插入图片描述

  • Bridge: Bridge 代表一个以太网交换机(Switch),一个主机中可以创建一个或者多个 Bridge 设备。
  • Port: 端口与物理交换机的端口概念类似,每个 Port 都隶属于一个 Bridge。
  • Interface: 连接到 Port 的网络接口设备。在通常情况下,Port 和 Interface 是一对一的关系, 只有在配置 Port 为 bond 模式后,Port 和 Interface 是一对多的关系。
  • Controller: OpenFlow 控制器。OVS 可以同时接受一个或者多个 OpenFlow 控制器的管理。
  • datapath: 在 OVS 中,datapath 负责执行数据交换,也就是把从接收端口收到的数据包在流表中进行匹配,并执行匹配到的动作。
  • Flow table: 每个 datapath 都和一个“flow table”关联,当 datapath 接收到数据之后, OVS 会在 flow table 中查找可以匹配的 flow,执行对应的操作, 例如转发数据到另外的端口。支持 OpenFlow 协议的交换机应该包括一个或者多个流表,流表中的条目包含:数据包头的信息、匹配成功后要执行的指令和统计信息
  • Flow : 在 OpenFlow 的白皮书中,Flow 被定义为某个特定的网络流量。例如,一个 TCP 连接就是一个 Flow,或者从某个 IP 地址发出来的数据包,都可以被认为是一个 Flow。

架构

在这里插入图片描述

  1. ovs-vswitchd:OVS守护进程,OVS的核心部件,实现交换功能,和Linux内核兼容模块一起,实现基于流的交换(flow-based switching)。它和上层 controller 通信遵从 OPENFLOW 协议,它与 ovsdb-server 通信使用 OVSDB 协议,它和内核模块通过netlink通信,它支持多个独立的 datapath(网桥),它通过更改flow table 实现了绑定和VLAN等功能。

  2. ovsdb-server:轻量级的数据库服务,主要保存了整个OVS 的配置信息,包括接口啊,交换内容,VLAN啊等等。ovs-vswitchd 会根据数据库中的配置信息工作。它于 manager 和 ovs-vswitchd 交换信息使用了OVSDB(JSON-RPC)的方式。

  3. ovs-dpctl:一个工具,用来配置交换机内核模块,可以控制转发规则。

  4. ovs-vsctl:主要是获取或者更改ovs-vswitchd 的配置信息,此工具操作的时候会更新ovsdb-server 中的数据库。

  5. ovs-appctl:主要是向OVS 守护进程发送命令的,一般用不上。ovs-appctl ofproto/trace 可以用来生成测试用的模拟数据包,并一步步的展示 OVS 对数据包的流处理过程。

  6. ovsdbmonitor:GUI 工具来显示ovsdb-server 中数据信息。

  7. ovs-controller:一个简单的OpenFlow 控制器

  8. ovs-ofctl:用来控制OVS 作为OpenFlow 交换机工作时候的流表内容。

工作流程

在这里插入图片描述
VM实例 instance 产生一个数据包并发送至实例内的虚拟网络接口 VNIC,图中就是 instance 中的 eth0.

这个数据包会传送到物理机上的VNIC接口,如图就是vnet接口。

数据包从 vnet NIC 出来,到达桥(虚拟交换机) br100 上.

数据包经过交换机的处理,从物理节点上的物理接口发出,如图中物理机上的 eth0 .

数据包从 eth0 出去的时候,是按照物理节点上的路由以及默认网关操作的,这个时候该数据包其实已经不受你的控制了。

一般 L2 switch 连接 eth0 的这个口是一个 trunk 口, 因为虚拟机对应的 VNET 往往会设置 VLAN TAG, 可以通过对虚拟机对应的 vnet 打 VALN TAG 来控制虚拟机的网络广播域. 如果跑多个虚拟机的话, 多个虚拟机对应的 vnet 可以设置不同的 vlan tag, 那么这些虚拟机的数据包从 eth0(4)出去的时候, 会带上TAG标记. 这样也就必须是 trunk 口才行.

知识点补充

交换机端口

交换机端口分为四种:

  • Access类型的端口只能属于1个VLAN,一般用于连接计算机的端口;
  • Trunk类型的端口可以允许多个VLAN通过,可以接收和发送多个VLAN的报文,一般用于交换机之间连接的端
  • link还介绍了另外两种

在网络中,交换机和桥都是同一个概念,OVS实现了一个虚拟机的以太交换机,换句话说,OVS也就是实现了一个以太桥。那么,在OVS中,给一个交换机,或者说一个桥,用了一个专业的名词,叫做DataPath。网桥是以混杂模式工作的

在ovs中:
当我们创建了一个交换机(网桥)以后,此时网络功能不受影响,但是会产生一个虚拟网卡,名字就是网桥的名称(br-int),之所以会产生一个虚拟网卡,是为了实现接下来的网桥(交换机)功能。有了这个交换机以后,还需要为这个交换机增加端口(port),一个端口,就是一个物理网卡,当网卡加入到这个交换机之后,其工作方式就和普通交换机的一个端口的工作方式类似了。

给虚拟网卡br-int(交换机的管理接口)配置IP以后,就相当于给交换机的管理接口配置了IP,此时一个正常的虚拟交换机就搞定了。

Flow语法说明

当数据包进入 OVS 后,会将数据包和流表中的流表项进行匹配,如果发现了匹配的流表项,则执行该流表项中的指令集。相反,如果数据包在流表中没有发现任何匹配,OVS 会通过控制通道把数据包发到 OpenFlow 控制器中。
在这里插入图片描述
在 OVS 中,流表项作为 ovs-ofctl 的参数,采用如下的格式:字段=值。如果有多个字段,可以用逗号或者空格分开。
一些常用的字段列举如下

字段名称 说明
in_port=port 传递数据包的端口的OpenFlow端口编号
dl_vlan=vlan 数据包的 VLAN Tag 值,范围是 0-4095,0xffff 代表不包含 VLAN Tag 的数据包
dl_src=MAC dl_dst=MAC 匹配源或者目标的 MAC 地;01:00:00:00:00:00/01:00:00:00:00:00 代表广播地址;00:00:00:00:00:00/01:00:00:00:00:00 代表单播地址
dl_type=ethertype 匹配以太网协议类型,其中:dl_type=0x0800 代表 IPv4 协议;dl_type=0x086dd 代表 IPv6 协议;dl_type=0x0806 代表 ARP 协议
nw_src=ip[/netmask]
nw_dst=ip[/netmask] 当 dl_typ=0x0800 时,匹配源或者目标的 IPv4 地址,可以使 IP 地址或者域名
nw_proto=proto 和 dl_type 字段协同使用。;当 dl_type=0x0800 时,匹配 IP 协议编号;当 dl_type=0x086dd 代表 IPv6 协议编号
table=number 指定要使用的流表的编号,范围是 0-254。在不指定的情况下,默认值为 0。通过使用流表编号,可以创建或者修改多个 Table 中的 Flow
reg=value[/mask] 交换机中的寄存器的值。当一个数据包进入交换机时,所有的寄存器都被清零,用户可以通过 Action 的指令修改寄存器中的值

对于 add−flow,add−flows 和 mod−flows 这三个命令,还需要指定要执行的动作:actions=[target][,target…]

一个流规则中可能有多个动作,按照指定的先后顺序执行。
常见的操作有:

  • output:port: 输出数据包到指定的端口。port 是指端口的 OpenFlow 端口编号
  • mod_vlan_vid: 修改数据包中的 VLAN tag
  • strip_vlan: 移除数据包中的 VLAN tag
  • mod_dl_src/ mod_dl_dest: 修改源或者目标的 MAC 地址信息
  • mod_nw_src/mod_nw_dst: 修改源或者目标的 IPv4 地址信息
  • resubmit:port: 替换流表的 in_port 字段,并重新进行匹配
  • load:value−>dst[start…end]: 写数据到指定的字段

实践学习

安装完毕后,检查OVS运行情况
在这里插入图片描述
查看版本信息
在这里插入图片描述
查看支持的OpenFlow版本
在这里插入图片描述
创建一个新的OVS交换机

ovs-vsctl add-br ovs-switch 该交换机的名字叫做ovs-switch

创建端口

ovs-vsctl add-port ovs-switch p0 

Error :
在这里插入图片描述
尝试解决又遇到了
在这里插入图片描述
后来换了个教程emm

ovs-vsctl add-port ovs-switch p0 -- set Interface p0 ofport_request=100
port和Interface默认是一一对应的
指定了OpenFlow端口编号为100,不指定OVS会自动生成一个

在这里插入图片描述
不要慌,咱继续。设置网络接口设备类型为internal。该类型的网络接口,OVS会同时在Linux系统中创建一个可以用来收发数据的模拟网络设备。我们可以为整个网络设备配置IP地址,进行数据监听等等。
在这里插入图片描述
为了避免网络接口上的地址和本机已有网络地址冲突,我们可以创建一个虚拟网络空间 ns0,把 p0 接口移入网络空间 ns0,并配置 IP 地址为 192.168.1.101。之后在root下就不能直接对p0进行操作了

ip netns add ns0
$ ip link set p0 netns ns0
$ ip netns exec ns0 ip addr add 192.168.1.100/24 dev p0
$ ip netns exec ns0 ifconfig p0 promisc up
当端口被移入网络接口空间后,就要用ip netns exec ns_name 的方式执行可在命令行下执行的命令

查看交换机信息
在这里插入图片描述
使用ovs-ofctl创建并测试OpenFlow命令

  1. 查看Open vSwitch中的额端口信息。从输出结果中,可以获得交换机对应的 datapath ID (dpid),以及每个端口的 OpenFlow 端口编号,端口名称,当前状态等等
    在这里插入图片描述
    想获得网络接口的OpenFlow编号,可以在OVS的数据库中查询:
    在这里插入图片描述
    查看datapath信息
    在这里插入图片描述
  2. 屏蔽数据报
    屏蔽所有进入OVS的以太网广播数据报
ovs-ofctl add-flow ovs-switch "table=0, dl_src=01:00:00:00:00:00/01:00:00:00:00:00, actions=drop"

屏蔽 STP 协议的广播数据包

ovs-ofctl add-flow ovs-switch "table=0, dl_dst=01:80:c2:00:00:00/ff:ff:ff:ff:ff:f0, actions=drop"

  1. 修改数据包
    添加新的 OpenFlow 条目,修改从端口 p0 收到的数据包的源地址为 9.181.137.1
    ovs-ofctl add-flow ovs-switch "priority=1 idle_timeout=0,\ in_port=100,actions=mod_nw_src:9.181.137.1,normal"没有看明白为什么有的地方是带引号有的地方不带引号在这里插入图片描述
    从端口 p0(192.168.1.100)发送测试数据到端口 p1(192.168.1.101)
ip netns exec ns0 ping 192.168.1.101

在接收端口 p1 监控数据,发现接收到的数据包的来源已经被修改为 9.181.137.1

ip netns exec ns1 tcpdump -i p1 icmp

从这里可以看到 OpenFlow的规则是无视netns的

	配置错误?
	参考了[link](https://serverfault.com/questions/646605/hosts-cannot-ping-in-two-name-spaces-using-open-vswitch/646631#646631)这个回答,难道是因为type不是veth的原因?
	![在这里插入图片描述](https://img-blog.csdnimg.cn/20191016171706581.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2lyb3kzMw==,size_16,color_FFFFFF,t_70)为什么ping失败:ovs-ofctl Example Usage中搭建的网络没有controller,因此交换机不知道该做什么,需要我们手动添加流
# ovs-ofctl add-flow ovs-switch in_port=100,actions=output:101
 # ovs-ofctl add-flow ovs-switch in_port=101,actions=output:100

这个时候看流表,它就不是空的了,但是这显然没有达到想要的目的
在这里插入图片描述
IP地址没有改变?难道是因为空间不一样?

这个是流表内容,感到困惑
在这里插入图片描述

10/17 继续学习
ip netns exec ns0 之后就是命令行内容可以执行~
换了环境后就成功了,不知道是openflow版本问题还是ovs版本问题
在接收端口 p1 监控数据,发现接收到的数据包的来源已经被修改为 9.181.137.1

  1. 重定向数据包
    添加新的 OpenFlow 条目,重定向所有的 ICMP 数据包到端口 p2
    **哪里体现是ICMP包了orz???
ip netns exec ns3 tcpdump -i p2 icmp

在这里插入图片描述

  1. 修改数据报的VLAN tag
    除了使用“ping”、“tcpdump”和“iperf” 等 Linux 命令以外,我们也可以使用 OVS 提供的 ovs-appctl ofproto/trace 工具来测试 OVS 对数据包的转发状况。ovs-appctl ofproto/trace 可以用来生成测试用的模拟数据包,并一步步的展示 OVS 对数据包的流处理过程。
    修改端口 p1 的 VLAN tag 为 101,使端口 p1 成为一个隶属于 VLAN 101 的端口
ovs-vsctl set Port p1 tag=101

现在由于端口 p0 和 p1 属于不同的 VLAN,它们之间无法进行数据交换。我们使用 ovs-appctl ofproto/trace 生成一个从端口 p0 发送到端口 p1 的数据包,这个数据包不包含任何 VLAN tag,并观察 OVS 的处理过程在这里插入图片描述
第一行:“Flow”描述了输入的流的信息。未指定的字段被OVS设置为空值0x0000
第二行:“Rule”描述匹配成功的流表项
第三行:“OpenFlow actions”描述了实际执行的操作
最后一行:“Final flow”是整个处理过程的总结,“Datapath actions:10,7”代表数据包被发送到datapath的10和7号端口
在这里插入图片描述
可以看到,10是ovs switch,7是p2。没有涉及到我们的目标p0和p1
不明白那个MAC地址对是怎么出来的

dl_vlan=0xffff 不包含VLAN tag的数据包
再次尝试从端口 p0 发送一个不包含任何 VLAN tag 的数据包,发现数据包进入端口 p0 之后, 会被加上 VLAN tag101, 同时转发到端口 p1 上
在这里插入图片描述
看最后一行Datapath,先加标签101,发给ovs-switch,然后弹出标签,发给port1,最后达到port2。到达port2是因为所有的ICMP包被重定向给p2了吗,感觉不太对
在这里插入图片描述
反过来从端口 p1 发送数据包,由于 p1 现在是带有 VLAN tag 101 的 Access 类型的端口,所以数据包进入端口 p1 之后,会被 OVS 添加 VLAN tag 101 并发送到端口 p0,看最后一行Datapath
6. 其他OpenFlow常用的操作

  • 查看交换机中所有的table
    ovs-ofctl dump-tables ovs-switch
  • 查看交换机中的所有流表项
    ovs−ofctl dump−flows ovs-switch在这里插入图片描述
  • 删除编号为 100 的端口上的所有流表项
    ovs-ofctl del-flows ovs-switch “in_port=100”
  • 查看交换机上的端口信息
    ovs-ofctl show ovs-switch
    在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/iroy33/article/details/102585420